diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 24176c27d3..d459989cd8 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -40,13 +40,13 @@ # Protobuf for node -/proto/node/ @evan-gray @bruce-riley +/proto/node/ @evan-gray @bruce-riley @panoel # Guardiand node ## Fallback -/node/ @bruce-riley @evan-gray @SEJeff +/node/ @bruce-riley @evan-gray @panoel @SEJeff ## Entrypoint / RPC @@ -54,7 +54,7 @@ ## DB -/node/pkg/db/ @bruce-riley @panoel +/node/pkg/db/ @bruce-riley @evan-gray @panoel ## Accountant @@ -78,11 +78,11 @@ ## Public RPC -/node/pkg/publicrpc/ @bruce-riley @panoel +/node/pkg/publicrpc/ @bruce-riley @evan-gray @panoel ## Supervisor Framework -/node/pkg/supervisor/ @bruce-riley @evan-gray +/node/pkg/supervisor/ @bruce-riley @evan-gray @panoel ## Watchers @@ -91,6 +91,7 @@ ## Hacks / Tools /node/hack/ @bruce-riley @panoel @evan-gray +/node/hack/governor @claudijd @SEJeff @djb15 @johnsaigle ## Documentation diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index a414bf0cd5..40d5624dab 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -332,7 +332,7 @@ jobs: go-version: "1.23.3" # The go-ethereum and celo-blockchain packages both implement secp256k1 using the exact same header, but that causes duplicate symbols. - name: Run golang tests - run: cd node && go test -v -timeout 5m -race -ldflags '-extldflags "-Wl,--allow-multiple-definition" ' ./... + run: cd node && go test -v -timeout 5m -race ./... # Run Rust lints and tests rust-lint-and-tests: diff --git a/.github/workflows/wormchain-icts.yml b/.github/workflows/wormchain-icts.yml index 805a568727..867c729875 100644 --- a/.github/workflows/wormchain-icts.yml +++ b/.github/workflows/wormchain-icts.yml @@ -63,6 +63,7 @@ jobs: - "ictest-wormchain" - "ictest-ibc-receiver" - "ictest-validator-hotswap" + - "ictest-cw-wormhole" fail-fast: false steps: diff --git a/.golangci.yml b/.golangci.yml index 6a320b8180..5d72dbc262 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -28,3 +28,7 @@ issues: text: "^func.*supervisor.*(waitSettle|waitSettleError).*$" linters: - unused + # This file contains hard-coded Sui core contract addresses that are marked as hardcoded credentials. + - path: pkg/txverifier/sui_test.go + + text: "G101: Potential hardcoded credentials" diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 74a8d32f8c..a50517629d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -23,9 +23,7 @@ and code reviews are our most important tools to accomplish that. Small commits, meaningful commit messages and useful comments make it easier to review code and improve the quality of code review as well as review turnaround times. It's much easier to spot mistakes in small, well-defined changes. -- We welcome typo and grammar fixes to *public facing* documents. This includes - things like the whitepapers, but excludes inline code comments. PRs that touch - only the latter will be rejected. Fixing typos in comments alongside other non-trivial engineering work is welcome. +- PRs that only correct typos or make minor wording adjustments will be rejected. Fixing typos alongside other non-trivial engineering work is welcome. - Pull requests that modify dependencies must be well-documented so that the benefits of updating can be weighed against security and compatibility concerns. Low-effort PRs that update dependencies without any documentation will be rejected. diff --git a/Makefile b/Makefile index a9b8a53b60..5472293fef 100755 --- a/Makefile +++ b/Makefile @@ -38,7 +38,6 @@ node: $(BIN)/guardiand .PHONY: $(BIN)/guardiand $(BIN)/guardiand: CGO_ENABLED=1 $(BIN)/guardiand: dirs generate - @# The go-ethereum and celo-blockchain packages both implement secp256k1 using the exact same header, but that causes duplicate symbols. - cd node && go build -ldflags "-X github.com/certusone/wormhole/node/pkg/version.version=${VERSION} -extldflags -Wl,--allow-multiple-definition" \ + cd node && go build -ldflags "-X github.com/certusone/wormhole/node/pkg/version.version=${VERSION}" \ -mod=readonly -o ../$(BIN)/guardiand \ github.com/certusone/wormhole/node diff --git a/Tiltfile b/Tiltfile index 71872d3029..600c548118 100644 --- a/Tiltfile +++ b/Tiltfile @@ -604,6 +604,11 @@ if evm2: ) +# Note that ci_tests requires other resources in order to build properly: +# - eth-devnet -- required by: accountant_tests, ntt_accountant_tests, tx-verifier +# - eth-devnet2 -- required by: accountant_tests, ntt_accountant_tests +# - wormchain -- required by: accountant_tests, ntt_accountant_tests +# - solana -- required by: spydk-ci-tests if ci_tests: docker_build( ref = "sdk-test-image", @@ -635,6 +640,16 @@ if ci_tests: sync("./testing", "/app/testing"), ], ) + docker_build( + ref = "tx-verifier-monitor", + context = "./devnet/tx-verifier-monitor/", + dockerfile = "./devnet/tx-verifier-monitor/Dockerfile" + ) + docker_build( + ref = "tx-verifier-test", + context = "./devnet/tx-verifier-monitor/", + dockerfile = "./devnet/tx-verifier-monitor/Dockerfile.cast" + ) k8s_yaml_with_ns( encode_yaml_stream( @@ -644,6 +659,11 @@ if ci_tests: "BOOTSTRAP_PEERS", str(ccqBootstrapPeers)), "MAX_WORKERS", max_workers)) ) + + # transfer-verifier -- daemon and log monitoring + k8s_yaml_with_ns("devnet/tx-verifier.yaml") + + k8s_yaml_with_ns("devnet/tx-verifier-test.yaml") # separate resources to parallelize docker builds k8s_resource( @@ -676,6 +696,20 @@ if ci_tests: trigger_mode = trigger_mode, resource_deps = [], # testing/querysdk.sh handles waiting for query-server, not having deps gets the build earlier ) + # launches tx-verifier binary and sets up monitoring script + k8s_resource( + "tx-verifier-with-monitor", + resource_deps = ["eth-devnet"], + labels = ["tx-verifier"], + trigger_mode = trigger_mode, + ) + # triggers the integration tests that will be detected by the monitor + k8s_resource( + "tx-verifier-test", + resource_deps = ["eth-devnet", "tx-verifier-with-monitor"], + labels = ["tx-verifier"], + trigger_mode = trigger_mode, + ) if terra_classic: docker_build( diff --git a/clients/js/src/chains/sui/utils.ts b/clients/js/src/chains/sui/utils.ts index 79f533873d..7944d9270f 100644 --- a/clients/js/src/chains/sui/utils.ts +++ b/clients/js/src/chains/sui/utils.ts @@ -416,7 +416,7 @@ export const setMaxGasBudgetDevnet = ( network: Network, tx: TransactionBlock ) => { - if (network === "Devnet") { + if (network === "Devnet" || network === "Testnet") { // Avoid Error checking transaction input objects: GasBudgetTooHigh { gas_budget: 50000000000, max_budget: 10000000000 } tx.setGasBudget(10000000000); } diff --git a/clients/js/src/cmds/aptos.ts b/clients/js/src/cmds/aptos.ts index b1d326ff5a..41838a7f6e 100644 --- a/clients/js/src/cmds/aptos.ts +++ b/clients/js/src/cmds/aptos.ts @@ -57,12 +57,19 @@ export const builder = (y: typeof yargs) => "init-token-bridge", "Init token bridge contract", (yargs) => - yargs.option("network", NETWORK_OPTIONS).option("rpc", RPC_OPTIONS), + yargs + .option("network", NETWORK_OPTIONS) + .option("rpc", RPC_OPTIONS) + .option("contract-address", { + describe: "Core contract address", + type: "string", + demandOption: false, + }), async (argv) => { const network = getNetwork(argv.network); - const contract_address = evm_address( - contracts.tokenBridge(network, "Aptos") - ); + const contract_address = + argv["contract-address"] || + evm_address(contracts.tokenBridge(network, "Aptos")); const rpc = argv.rpc ?? NETWORKS[network].Aptos.rpc; await callEntryFunc( network, @@ -104,13 +111,18 @@ export const builder = (y: typeof yargs) => demandOption: true, describe: "Initial guardian's addresses (CSV)", type: "string", + }) + .option("contract-address", { + describe: "Core contract address", + type: "string", + demandOption: false, }), async (argv) => { const network = getNetwork(argv.network); - const contract_address = evm_address( - contracts.coreBridge(network, "Aptos") - ); + const contract_address = + argv["contract-address"] || + evm_address(contracts.coreBridge(network, "Aptos")); const guardian_addresses = argv["guardian-address"] .split(",") .map((address) => evm_address(address).substring(24)); @@ -196,11 +208,15 @@ export const builder = (y: typeof yargs) => const b = serializePackage(p); const seed = Buffer.from(argv["seed"], "ascii"); - let module_name = APTOS_DEPLOYER_ADDRESS_DEVNET + "::deployer"; - if (network == "Testnet" || network == "Mainnet") { - module_name = - "0x0108bc32f7de18a5f6e1e7d6ee7aff9f5fc858d0d87ac0da94dd8d2a5d267d6b::deployer"; + let deployer = APTOS_DEPLOYER_ADDRESS_DEVNET; + const addresses = argv["named-addresses"]?.split(",") || []; + for (const addressPair of addresses) { + const [name, address] = addressPair.split("="); + if (name === "deployer") { + deployer = address; + } } + const module_name = deployer + "::deployer"; const rpc = argv.rpc ?? NETWORKS[network].Aptos.rpc; await callEntryFunc( network, @@ -223,12 +239,19 @@ export const builder = (y: typeof yargs) => describe: "Message to send", demandOption: true, }) - .option("network", NETWORK_OPTIONS), + .option("network", NETWORK_OPTIONS) + .option("rpc", RPC_OPTIONS) + .option("sender", { + describe: "Sender address", + type: "string", + demandOption: false, + }), async (argv) => { const network = getNetwork(argv.network); - const rpc = NETWORKS[network].Aptos.rpc; - let module_name = APTOS_DEPLOYER_ADDRESS_DEVNET + "::sender"; - if (network == "Testnet" || network == "Mainnet") { + const rpc = argv.rpc ?? NETWORKS[network].Aptos.rpc; + let module_name = + (argv.sender || APTOS_DEPLOYER_ADDRESS_DEVNET) + "::sender"; + if (!argv.sender && (network == "Testnet" || network == "Mainnet")) { module_name = "0x0108bc32f7de18a5f6e1e7d6ee7aff9f5fc858d0d87ac0da94dd8d2a5d267d6b::sender"; } diff --git a/clients/js/src/cmds/verifyVaa.ts b/clients/js/src/cmds/verifyVaa.ts index 21265c6be6..fce28cf4d9 100644 --- a/clients/js/src/cmds/verifyVaa.ts +++ b/clients/js/src/cmds/verifyVaa.ts @@ -24,13 +24,18 @@ export const handler = async ( const network = getNetwork(argv.network); const buf = Buffer.from(String(argv.vaa), "hex"); - const contract_address = contracts.coreBridge(network, "Ethereum"); + const contract_address = + network === "Testnet" + ? contracts.coreBridge(network, "Sepolia") + : contracts.coreBridge(network, "Ethereum"); if (!contract_address) { throw Error(`Unknown core contract on ${network} for ethereum`); } const provider = new ethers.providers.JsonRpcProvider( - NETWORKS[network].Ethereum.rpc + network === "Testnet" + ? NETWORKS[network].Sepolia.rpc + : NETWORKS[network].Ethereum.rpc ); const contract = Implementation__factory.connect(contract_address, provider); const result = await contract.parseAndVerifyVM(buf); diff --git a/deployments/testnet/tokenBridgeVAAs.csv b/deployments/testnet/tokenBridgeVAAs.csv index f3c77f523c..84b9431c72 100644 --- a/deployments/testnet/tokenBridgeVAAs.csv +++ b/deployments/testnet/tokenBridgeVAAs.csv @@ -30,10 +30,13 @@ Blast (36) Testnet Token Bridge,0100000000010052b4615add1ca354feb81a7f90b70a0d78 XLayer (37) Testnet Token Bridge,01000000000100c983babda02e84e346e49f823aa201d65c82e19c51cdfb555cc9aa2fa6809f4500f6344d86722b1a8023906d185c96bc9b4e332402ae2e05ec69d0d95c39ea81000000000100000001000100000000000000000000000000000000000000000000000000000000000000040000000005b1293100000000000000000000000000000000000000000000546f6b656e4272696467650100000025000000000000000000000000da91a06299bbf302091b053c6b9ef86eff0f930d Linea (38) Testnet Token Bridge,01000000000100411f65a20405ad0d85d6718a91bc16cf645a7eb7dbd29d4b2d0b9cc2d872dc01112cf96dc40c07ddf648325a5dcdba42c70612179126178e7fb9e9bcfef1cb4a01000000010000000100010000000000000000000000000000000000000000000000000000000000000004000000000183785600000000000000000000000000000000000000000000546f6b656e4272696467650100000026000000000000000000000000c7a204bdbfe983fcd8d8e61d02b475d4073ff97e Berachain (39) Testnet Token Bridge,01000000000100c19d35faa10139fef5b3244f120efb67ad22d2d9ece7d777bcb6e957506ba9f15e2e6fd91a18dcdd6bf434d96d624fd725f957437f2e86dfdcbb6d0e97f3eeb100000000010000000100010000000000000000000000000000000000000000000000000000000000000004000000000404250300000000000000000000000000000000000000000000546f6b656e4272696467650100000027000000000000000000000000a10f2ef61de1f19f586ab8b6f2eba89bace63f7a +SeiEVM (40) Testnet Token Bridge,0100000000010095c3bd258103e0ba1b26f63753ffd5468c3c7434ecc731e2f3e3cd84ce8e76087d7307c261470b83b4b756bed6ebd88ff5d4c9fa85d1fc9463c6802eba5e2e230000000001000000010001000000000000000000000000000000000000000000000000000000000000000400000000041ba71f00000000000000000000000000000000000000000000546f6b656e427269646765010000002800000000000000000000000023908a62110e21c04f3a4e011d24f901f911744a Snaxchain (43) Testnet Token Bridge,010000000001008ed60dec76f13f6da695fc5f134c8cf3527f264712e7bb98d2e54a5f457759e0491e3f1cb42eed9b84edc60a96836df98a3752c8a4e10977801e6c35a39f211b000000000100000001000100000000000000000000000000000000000000000000000000000000000000040000000005ba971e00000000000000000000000000000000000000000000546f6b656e427269646765010000002b000000000000000000000000a10f2ef61de1f19f586ab8b6f2eba89bace63f7a Unichain (44) Testnet Token Bridge,010000000001004f9c7be0694bcabbf1fec2300004b9d82f6a122c459fababcfdc897e894769290c9a9655015909b5c17667d63f8edcec9ad9ee2d05e7cdb24a7a64136a4312c70100000001000000010001000000000000000000000000000000000000000000000000000000000000000400000000008006e100000000000000000000000000000000000000000000546f6b656e427269646765010000002c000000000000000000000000a10f2ef61de1f19f586ab8b6f2eba89bace63f7a Worldchain (45) Testnet Token Bridge,01000000000100f1ae141e77e67110aecade87c6a5f9b34545638aba1a3a7dbf6a311fe58c99fd351650c8593a8161a03cc7f94b76cdc0a5978fa3e0ffbfb3738085a070172cc5010000000100000001000100000000000000000000000000000000000000000000000000000000000000040000000004f3500a00000000000000000000000000000000000000000000546f6b656e427269646765010000002d000000000000000000000000430855b4d43b8aeb9d2b9869b74d58dda79c0db2 HyperEVM (47) Testnet Token Bridge,010000000001003f9a225a8b004c871374f69c29e8a3335614270886719a9ce30b1e5afb1df04d144208fb42b74fbfb140977a13e4fb4fa6107e625745ede6d6ddca0e4eafcb3c01000000010000000100010000000000000000000000000000000000000000000000000000000000000004000000000456642800000000000000000000000000000000000000000000546f6b656e427269646765010000002f0000000000000000000000004a8bc80ed5a4067f1ccf107057b8270e0cc11a78 +Monad (48) Testnet Token Bridge,01000000000100f55193326b0cf4dc1fe356b47a9842ff751c033e0b002b1d572ccbf8b1cb45b6770d4ce7f415fb29b4d87f75fec9e5dd15df56fc20ba401a4f07e5956394225501000000010000000100010000000000000000000000000000000000000000000000000000000000000004000000000521e4d200000000000000000000000000000000000000000000546f6b656e4272696467650100000030000000000000000000000000f323dcde4d33efe83cf455f78f9f6cc656e6b659 +Movement (49) Testnet Token Bridge,010000000001006e366ef014166b9618721b6e7c37d6a0dab510a6526061c219f88d46f39ada887a870c4aeff812795a4a78d0334567af817c54c1bfe197f0b92c357f4e49a311000000000100000001000100000000000000000000000000000000000000000000000000000000000000040000000003d9804a00000000000000000000000000000000000000000000546f6b656e42726964676501000000310000000000000000000000000000000000000000000000000000000000000002 Gateway (3104) Testnet Token Bridge,01000000000100117d1c7a124a9e2e29d82b3803b825be7c8a1dc7f19013669f7d11d42d448aa72339fe3657e4bd156c5c28dd10e78aab3e06e9e76c4bbd38c81e057533d577c40000000000d09296c5000100000000000000000000000000000000000000000000000000000000000000049ea4b9942b23298c20000000000000000000000000000000000000000000546f6b656e4272696467650100000c20ef5251ea1e99ae48732800ccc7b83b57881232a73eb796b63b1d86ed2ea44e27 Sepolia (10002) (Ethereum) Testnet Token Bridge,01000000000100a03841125d40e9df3cd80d027bc660191755587980e49f6a46e9baa1b5c3f6b46e51256c225bd242139ae11d3c84439acdc204a5f39a2e1acb750ae98bb759f1000000000100000001000100000000000000000000000000000000000000000000000000000000000000040000000005491ea100000000000000000000000000000000000000000000546f6b656e4272696467650100002712000000000000000000000000db5492265f6038831e89f495670ff909ade94bd9 Arbitrum Sepolia (10003) Testnet Token Bridge,010000000001001b0fbbcc7a3e8c491dc25f0a611075513032fe444d8e6585153e6ae2cf8c7514152b050e95a3e0af11e5b2705b2efb717bec3cfaa3b1617ff623c14e61a69224000000000100000001000100000000000000000000000000000000000000000000000000000000000000040000000001b8de3c00000000000000000000000000000000000000000000546f6b656e4272696467650100002713000000000000000000000000c7a204bdbfe983fcd8d8e61d02b475d4073ff97e diff --git a/devnet/eth-devnet.yaml b/devnet/eth-devnet.yaml index d4b1c10ef0..697ca1ae9f 100644 --- a/devnet/eth-devnet.yaml +++ b/devnet/eth-devnet.yaml @@ -33,13 +33,16 @@ spec: containers: - name: anvil image: eth-node + # This command generates additional accounts compared to the default of 10. The purpose is to use dedicated + # accounts for different aspects of the test suite. When adding new integration tests, consider increasing + # the number of accounts below and using a fresh key for the new tests. command: - anvil - --silent - --mnemonic=myth like bonus scare over problem client lizard pioneer submit female collect - --block-time=1 - --host=0.0.0.0 - - --accounts=13 + - --accounts=14 - --chain-id=1337 ports: - containerPort: 8545 diff --git a/devnet/eth-devnet2.yaml b/devnet/eth-devnet2.yaml index 22ca588d54..3dd507a813 100644 --- a/devnet/eth-devnet2.yaml +++ b/devnet/eth-devnet2.yaml @@ -34,13 +34,16 @@ spec: containers: - name: anvil image: eth-node + # This command generates additional accounts compared to the default of 10. The purpose is to use dedicated + # accounts for different aspects of the test suite. When adding new integration tests, consider increasing + # the number of accounts below and using a fresh key for the new tests. command: - anvil - --silent - --mnemonic=myth like bonus scare over problem client lizard pioneer submit female collect - --block-time=1 - --host=0.0.0.0 - - --accounts=13 + - --accounts=14 - --chain-id=1397 ports: - containerPort: 8545 diff --git a/devnet/tx-verifier-monitor/Dockerfile b/devnet/tx-verifier-monitor/Dockerfile new file mode 100644 index 0000000000..0e9be40bd3 --- /dev/null +++ b/devnet/tx-verifier-monitor/Dockerfile @@ -0,0 +1,10 @@ +# There's nothing special about this version, it is simply the `latest` as of +# the creation date of this file. +FROM alpine:3.20.3@sha256:1e42bbe2508154c9126d48c2b8a75420c3544343bf86fd041fb7527e017a4b4a + +RUN apk add --no-cache inotify-tools + +COPY monitor.sh /monitor.sh +RUN chmod +x /monitor.sh + +CMD ["/monitor.sh"] diff --git a/devnet/tx-verifier-monitor/Dockerfile.cast b/devnet/tx-verifier-monitor/Dockerfile.cast new file mode 100644 index 0000000000..0124bdf7a6 --- /dev/null +++ b/devnet/tx-verifier-monitor/Dockerfile.cast @@ -0,0 +1,13 @@ +# These versions are pinned to match the Dockerfile in the `ethereum/` +# directory. Otherwise, there is nothing special about them and they can be +# updated alongside the other Dockerfile. +FROM --platform=linux/amd64 ghcr.io/foundry-rs/foundry:nightly-55bf41564f605cae3ca4c95ac5d468b1f14447f9@sha256:8c15d322da81a6deaf827222e173f3f81c653136a3518d5eeb41250a0f2e17ea as foundry +# node is required to install Foundry +FROM node:19.6.1-slim@sha256:a1ba21bf0c92931d02a8416f0a54daad66cb36a85d2b73af9d73b044f5f57cfc + +COPY --from=foundry /usr/local/bin/cast /bin/cast + +COPY transfer-verifier-test.sh /transfer-verifier-test.sh +RUN chmod +x /transfer-verifier-test.sh + +CMD ["/transfer-verifier-test.sh"] diff --git a/devnet/tx-verifier-monitor/README.md b/devnet/tx-verifier-monitor/README.md new file mode 100644 index 0000000000..7102b16531 --- /dev/null +++ b/devnet/tx-verifier-monitor/README.md @@ -0,0 +1,64 @@ +# Transfer Verifier -- Integration Tests + +## EVM Integration Tests + +### Overview + +The Transfer Verifier tests involve interacting with the local ethereum devnet defined by the Tilt set-up in this repository. + +The basic idea is as follows: +* Interact with the local Ethereum testnet. This should already have important pieces such as the Token Bridge and Core Bridge deployed. +* Use `cast` from the foundry tool set to simulate malicious interactions with the Token Bridge. +* Transfer Verifier detects the malicious messages and emits errors about what went wrong. +* The error messages are logged to a file +* A "monitor" script is used to detect the expected error message, waiting until the file is written to +* If the monitor script sees the expected error message in the error log, it terminates + +## Components + +### Scripts + +#### transfer-verifier-test.sh + +Contains the `cast` commands that simulate malicious interactions with the Token Bridge and Core Bridge. It is able to broadcast +transactions to the `anvil` instance that powers the Ethereum testnet while being able to impersonate arbitrary senders. + +This lets us perform actions that otherwise should be impossible, like causing a Publish Message event to be emitted from the Core Bridge +without a corresponding deposit or transfer into the Token Bridge. + +#### monitor.sh + +A bash script that monitors the error log file for a specific error pattern. It runs in an infinite loop so it will +not exit until the error pattern is detected. + +The error pattern is defined in `wormhole/devnet/tx-verifier.yaml` and matches an error string in the Transfer Verifier package. + +Once the pattern is detected, a success message is logged to a status file. Currently this is unused but this set-up +could be modified to detect that this script has written the success message to figure out whether the whole test completed successfully. + +### Pods + +The files detailed below each have a primary role and are responsible for running one of the main pieces of the test functionality: + +* The Transfer Verifier binary which monitors the state of the local Ethereum network +* The integration test script that generates activity that the Transfer Verifier classifies as malicious +* The monitor script which ensures that the Transfer Verifier successfully +detected the error we expected, and signals to Tilt that the overall test has +succeeded + +#### devnet/tx-verifier.yaml + +Runs the Transfer Verifier binary and redirects its STDERR to the error log file. This allows the output of the binary +to be monitored by `monitor.sh`. + +#### devnet/tx-verifier-test.yaml + +Runs the `transfer-verifier-test.sh` script which simulates malicious Token Bridge activity. Defines the RPC URL used +by that bash script, which corresponds to the `anvil` instance created in the Ethereum devnet. + +#### devnet/tx-verifier-monitor.yaml + +Defines the expected error string that should be emitted by the Transfer Verifier code assuming that it successfully recognizes +the malicious Token Bridge activity simulated by the `cast` commands in `transfer-verifier-test.sh`. + +It also defines a path to the log file that contains this string. diff --git a/devnet/tx-verifier-monitor/monitor.sh b/devnet/tx-verifier-monitor/monitor.sh new file mode 100755 index 0000000000..9ccdc8efb1 --- /dev/null +++ b/devnet/tx-verifier-monitor/monitor.sh @@ -0,0 +1,25 @@ +#!/bin/sh + +log_file="${ERROR_LOG_PATH:-/logs/error.log}" +error_pattern="${ERROR_PATTERN:-ERROR}" +status_file="/logs/status" + +# Wait for log file to exist and be non-empty +while [ ! -s "${log_file}" ]; do + echo "Waiting for ${log_file} to be created and contain data..." + sleep 5 +done + +# Initialize status +echo "RUNNING" > "$status_file" +echo "Monitoring file '${log_file}' for error pattern: '${error_pattern}'" + +# Watch for changes in the log file. If we find the error pattern that means we have +# succeeded. (Transfer verifier should correctly detect errors. +inotifywait -m -e modify "${log_file}" | while read -r directory events filename; do + if grep -q "$error_pattern" "$log_file"; then + echo "SUCCESS" > "$status_file" + echo "Found error pattern. Exiting." + exit 0 + fi +done diff --git a/devnet/tx-verifier-monitor/transfer-verifier-test.sh b/devnet/tx-verifier-monitor/transfer-verifier-test.sh new file mode 100755 index 0000000000..18e98bef1e --- /dev/null +++ b/devnet/tx-verifier-monitor/transfer-verifier-test.sh @@ -0,0 +1,120 @@ +#!/usr/bin/env bash +set -euo pipefail + +RPC="${RPC_URL:-ws://eth-devnet:8545}" + +# mainnet values +# export CORE_CONTRACT="0x98f3c9e6E3fAce36bAAd05FE09d375Ef1464288B" +# export TOKEN_BRIDGE_CONTRACT="0x3ee18B2214AFF97000D974cf647E7C347E8fa585" + +# TODO these could be CLI params from the sh/devnet script +CORE_BRIDGE_CONTRACT=0xC89Ce4735882C9F0f0FE26686c53074E09B0D550 +TOKEN_BRIDGE_CONTRACT=0x0290FB167208Af455bB137780163b7B7a9a10C16 + +MNEMONIC=0x4f3edf983ac636a65a842ce7c78d9aa706d3b113bce9c46f30d7d21715b23b1d + +ERC20_ADDR="0x47bdB2D7d6528C760b6f228b3B8F9F650169a10f" # Test token A + +VALUE="1000" # Wei value sent as msg.value +TRANSFER_AMOUNT="10" + +# This account is generated by anvil and can be confirmed by running `anvil --accounts=13`. +# The accounts at other indices are used by other tests in the test suite, so +# account[13] is used here to help encapsulate the tests. +ANVIL_USER="0x64E078A8Aa15A41B85890265648e965De686bAE6" +ETH_WHALE="${ANVIL_USER}" +FROM="${ETH_WHALE}" +# Anvil user1 normalized to Wormhole size. (The value itself it unchecked but must have this format.) +RECIPIENT="0x00000000000000000000000064E078A8Aa15A41B85890265648e965De686bAE6" +NONCE="234" # arbitrary + +# Build the payload for token transfers. Declared on multiple lines to +# be more legible. Data pulled from an arbitrary LogMessagePublished event +# on etherscan. Metadata and fees commented out, leaving only the payload +PAYLOAD="0x" +declare -a SLOTS=( + # "0000000000000000000000000000000000000000000000000000000000055baf" + # "0000000000000000000000000000000000000000000000000000000000000000" + # "0000000000000000000000000000000000000000000000000000000000000080" + # "0000000000000000000000000000000000000000000000000000000000000001" + # "00000000000000000000000000000000000000000000000000000000000000ae" + "030000000000000000000000000000000000000000000000000000000005f5e1" + "000000000000000000000000002260fac5e5542a773aa44fbcfedf7c193bc2c5" + "9900020000000000000000000000000000000000000000000000000000000000" + "000816001000000000000000000000000044eca3f6295d6d559ca1d99a5ef5a8" + "f72b4160f10001010200c91f01004554480044eca3f6295d6d559ca1d99a5ef5" + "a8f72b4160f10000000000000000000000000000000000000000000000000000" +) +for i in "${SLOTS[@]}" +do + PAYLOAD="$PAYLOAD$i" +done + +echo "DEBUG:" +echo "- RPC=${RPC}" +echo "- CORE_BRIDGE_CONTRACT=${CORE_BRIDGE_CONTRACT}" +echo "- TOKEN_BRIDGE_CONTRACT=${TOKEN_BRIDGE_CONTRACT}" +echo "- MNEMONIC=${MNEMONIC}" +echo "- FROM=${FROM}" +echo "- VALUE=${VALUE}" +echo "- RECIPIENT=${RECIPIENT}" +echo + +# Fund the token bridge from the user +echo "Start impersonating Anvil key: ${ANVIL_USER}" +cast rpc \ + anvil_impersonateAccount "${ANVIL_USER}" \ + --rpc-url "${RPC}" +echo "Funding token bridge using the user's balance" +cast send --unlocked \ + --rpc-url "${RPC}" \ + --from $ANVIL_USER \ + --value 100000000000000 \ + ${TOKEN_BRIDGE_CONTRACT} +echo "" +echo "End impersonating User0" +cast rpc \ + anvil_stopImpersonatingAccount "${ANVIL_USER}" \ + --rpc-url "${RPC}" + +BALANCE_CORE=$(cast balance --rpc-url "${RPC}" $CORE_BRIDGE_CONTRACT) +BALANCE_TOKEN=$(cast balance --rpc-url "${RPC}" $TOKEN_BRIDGE_CONTRACT) +BALANCE_USER=$(cast balance --rpc-url "${RPC}" $ANVIL_USER) +echo "BALANCES:" +echo "- CORE_BRIDGE_CONTRACT=${BALANCE_CORE}" +echo "- TOKEN_BRIDGE_CONTRACT=${BALANCE_TOKEN}" +echo "- ANVIL_USER=${BALANCE_USER}" +echo + +# === Malicious call to transferTokensWithPayload() +# This is the exploit scenario: the token bridge has called publishMessage() without a ERC20 Transfer or Deposit +# being present in the same receipt. +# This is done by impersonating the token bridge contract and sending a message directly to the core bridge. +# Ensure that anvil is using `--auto-impersonate` or else that account impersonation is enabled in your local environment. +# --private-key "$MNEMONIC" \ +# --max-fee 500000 \ +echo "Start impersonate token bridge" +cast rpc \ + --rpc-url "${RPC}" \ + anvil_impersonateAccount "${TOKEN_BRIDGE_CONTRACT}" +echo "Calling publishMessage as ${TOKEN_BRIDGE_CONTRACT}" +cast send --unlocked \ + --rpc-url "${RPC}" \ + --json \ + --gas-limit 10000000 \ + --priority-gas-price 1 \ + --from "${TOKEN_BRIDGE_CONTRACT}" \ + --value "0" \ + "${CORE_BRIDGE_CONTRACT}" \ + "publishMessage(uint32,bytes,uint8)" \ + 0 "${PAYLOAD}" 1 +echo "" +cast rpc \ + --rpc-url "${RPC}" \ + anvil_stopImpersonatingAccount "${TOKEN_BRIDGE_CONTRACT}" +echo "End impersonate token bridge" + +# TODO add the 'multicall' scenario encoded in the forge script + +echo "Done Transfer Verifier integration test." +echo "Exiting." diff --git a/devnet/tx-verifier-test.yaml b/devnet/tx-verifier-test.yaml new file mode 100644 index 0000000000..17be61586f --- /dev/null +++ b/devnet/tx-verifier-test.yaml @@ -0,0 +1,32 @@ +apiVersion: batch/v1 +kind: Job +metadata: + name: tx-verifier-test +spec: + # Number of successful pod completions needed + completions: 1 + # Number of pods to run in parallel + parallelism: 1 + # Time limit after which the job is terminated (optional) + # activeDeadlineSeconds: 100 + # Number of retries before marking as failed + backoffLimit: 4 + template: + metadata: + labels: + app: tx-verifier-test + spec: + restartPolicy: Never + containers: + - name: tx-verifier-test + image: tx-verifier-test + command: + - /bin/bash + - -c + - "/transfer-verifier-test.sh" + env: + - name: RPC_URL + value: "ws://eth-devnet:8545" + volumes: + - name: log-volume + emptyDir: {} diff --git a/devnet/tx-verifier.yaml b/devnet/tx-verifier.yaml new file mode 100644 index 0000000000..1130f76035 --- /dev/null +++ b/devnet/tx-verifier.yaml @@ -0,0 +1,51 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: tx-verifier-with-monitor +spec: + selector: + matchLabels: + app: tx-verifier-with-monitor + template: + metadata: + labels: + app: tx-verifier-with-monitor + spec: + securityContext: + runAsUser: 1000 + runAsGroup: 1000 + fsGroup: 1000 + containers: + - name: tx-verifier + image: guardiand-image + volumeMounts: + - name: log-volume + mountPath: /logs + command: + ["/bin/sh", "-c"] + # See `ethereum/.env.test` and related shell scripts for how these values are configured in localnet testing. + args: + - | + exec /guardiand \ + transfer-verifier \ + evm \ + --rpcUrl ws://eth-devnet:8545 \ + --coreContract 0xC89Ce4735882C9F0f0FE26686c53074E09B0D550 \ + --tokenContract 0x0290FB167208Af455bB137780163b7B7a9a10C16 \ + --wrappedNativeContract 0xDDb64fE46a91D46ee29420539FC25FD07c5FEa3E \ + --logLevel=info \ + 2> /logs/error.log \ + - name: tx-verifier-monitor + image: tx-verifier-monitor + volumeMounts: + - name: log-volume + mountPath: /logs + env: + - name: ERROR_PATTERN + # This error string comes from the transfer-verifier binary in node/ + value: "invalid receipt: no deposits and no transfers" + - name: ERROR_LOG_PATH + value: "/logs/error.log" + volumes: + - name: log-volume + emptyDir: {} diff --git a/ethereum/env/.env.monad.testnet b/ethereum/env/.env.monad.testnet new file mode 100644 index 0000000000..98f85573c1 --- /dev/null +++ b/ethereum/env/.env.monad.testnet @@ -0,0 +1,19 @@ +# Monad testnet env +# Rename to .env + +# Common config for forge deployment +RPC_URL=public_url + +# Wormhole Core Migrations +INIT_SIGNERS=["0x13947Bd48b18E53fdAeEe77F3473391aC727C638"] +INIT_CHAIN_ID=48 +INIT_GOV_CHAIN_ID=0x1 +INIT_GOV_CONTRACT=0x0000000000000000000000000000000000000000000000000000000000000004 +INIT_EVM_CHAIN_ID=10143 + +# Bridge Migrations +BRIDGE_INIT_CHAIN_ID=48 +BRIDGE_INIT_GOV_CHAIN_ID=0x1 +BRIDGE_INIT_GOV_CONTRACT=0x0000000000000000000000000000000000000000000000000000000000000004 +BRIDGE_INIT_FINALITY=1 +BRIDGE_INIT_WETH=0x760AfE86e5de5fa0Ee542fc7B7B713e1c5425701 diff --git a/ethereum/env/.env.seievm.devnet b/ethereum/env/.env.seievm.devnet new file mode 100644 index 0000000000..83565e4dbf --- /dev/null +++ b/ethereum/env/.env.seievm.devnet @@ -0,0 +1,13 @@ +# Sei EVM testnet read only env. Use to deploy the core contract with forge. + +# ethereum$ ln -s env/.env.seievm.testnet .env + +RPC_URL="https://evm-rpc-arctic-1.sei-apis.com/" +FORGE_ARGS="--legacy --with-gas-price 3000000000" # 3 gwei + +# Wormhole Core +INIT_SIGNERS=["0x58CC3AE5C097b213cE3c81979e1B9f9570746AA5"] +INIT_CHAIN_ID=40 +INIT_GOV_CHAIN_ID=0x1 +INIT_GOV_CONTRACT=0x0000000000000000000000000000000000000000000000000000000000000004 +INIT_EVM_CHAIN_ID=713715 diff --git a/ethereum/env/.env.seievm.testnet b/ethereum/env/.env.seievm.testnet index 83565e4dbf..daae071fa7 100644 --- a/ethereum/env/.env.seievm.testnet +++ b/ethereum/env/.env.seievm.testnet @@ -1,13 +1,19 @@ -# Sei EVM testnet read only env. Use to deploy the core contract with forge. +# SeiEVM testnet (atlantic-2) env +# Rename to .env -# ethereum$ ln -s env/.env.seievm.testnet .env +# Common config for forge deployment +RPC_URL="https://evm-rpc-testnet.sei-apis.com/" -RPC_URL="https://evm-rpc-arctic-1.sei-apis.com/" -FORGE_ARGS="--legacy --with-gas-price 3000000000" # 3 gwei - -# Wormhole Core -INIT_SIGNERS=["0x58CC3AE5C097b213cE3c81979e1B9f9570746AA5"] +# Wormhole Core Migrations +INIT_SIGNERS=["0x13947Bd48b18E53fdAeEe77F3473391aC727C638"] INIT_CHAIN_ID=40 INIT_GOV_CHAIN_ID=0x1 INIT_GOV_CONTRACT=0x0000000000000000000000000000000000000000000000000000000000000004 -INIT_EVM_CHAIN_ID=713715 +INIT_EVM_CHAIN_ID=1328 + +# Bridge Migrations +BRIDGE_INIT_CHAIN_ID=40 +BRIDGE_INIT_GOV_CHAIN_ID=0x1 +BRIDGE_INIT_GOV_CONTRACT=0x0000000000000000000000000000000000000000000000000000000000000004 +BRIDGE_INIT_WETH=0x3921eA6Cf927BE80211Bb57f19830700285b0AdA +BRIDGE_INIT_FINALITY=1 diff --git a/ethereum/forge-scripts/DeployTestToken.s.sol b/ethereum/forge-scripts/DeployTestToken.s.sol index 399a21ccdf..9ee1d0f6b9 100644 --- a/ethereum/forge-scripts/DeployTestToken.s.sol +++ b/ethereum/forge-scripts/DeployTestToken.s.sol @@ -17,7 +17,8 @@ contract DeployTestToken is Script { address deployedTokenAddress, address deployedNFTaddress, address deployedWETHaddress, - address deployedAccountantTokenAddress + address deployedAccountantTokenAddress, + address transferVerificationTokenA ) { vm.startBroadcast(); @@ -25,7 +26,8 @@ contract DeployTestToken is Script { deployedTokenAddress, deployedNFTaddress, deployedWETHaddress, - deployedAccountantTokenAddress + deployedAccountantTokenAddress, + transferVerificationTokenA ) = _deploy(); vm.stopBroadcast(); } @@ -36,10 +38,11 @@ contract DeployTestToken is Script { address deployedTokenAddress, address deployedNFTaddress, address deployedWETHaddress, - address deployedAccountantTokenAddress + address deployedAccountantTokenAddress, + address transferVerificationTokenA ) { - address[] memory accounts = new address[](13); + address[] memory accounts = new address[](14); accounts[0] = 0x90F8bf6A479f320ead074411a4B0e7944Ea8c9C1; accounts[1] = 0xFFcf8FDEE72ac11b5c542428B35EEF5769C409f0; accounts[2] = 0x22d491Bde2303f2f43325b2108D26f1eAbA1e32b; @@ -53,6 +56,8 @@ contract DeployTestToken is Script { accounts[10] = 0x610Bb1573d1046FCb8A70Bbbd395754cD57C2b60; accounts[11] = 0x855FA758c77D68a04990E992aA4dcdeF899F654A; accounts[12] = 0xfA2435Eacf10Ca62ae6787ba2fB044f8733Ee843; + accounts[13] = 0x64E078A8Aa15A41B85890265648e965De686bAE6; + ERC20PresetMinterPauser token = new ERC20PresetMinterPauser( "Ethereum Test Token", @@ -95,11 +100,33 @@ contract DeployTestToken is Script { // mint 1000 units accountantToken.mint(accounts[9], 1_000_000_000_000_000_000_000); + for(uint16 i=0; i<11; i++) { + // Give the accounts enough eth to send transactions + vm.deal(accounts[i], 1e18); + } + + // Deploy a test token for Transfer Verification + ERC20PresetMinterPauser deployedA = new ERC20PresetMinterPauser( + "TransferVerifier Test Token A", + "TVA" + ); + console.log("Test token A deployed at: ", address(deployedA)); + + // Mint Eth and test tokens to Anvil's default account at index 13. + // This will be used for Transfer Verification integration tests. + // The other accounts created by Anvil are used for other tests in the devnet, so + // using account 14 to send transfers will hopefully cause things to be + // better encapsulated. + deployedA.mint(accounts[13], 1_000_000_000_000_000_000_000); + token.mint(accounts[13], 1_000_000_000_000_000_000_000); + vm.deal(accounts[13], 1e18); + return ( address(token), address(nft), address(mockWeth), - address(accountantToken) + address(accountantToken), + address(deployedA) ); } } diff --git a/node/Dockerfile b/node/Dockerfile index c84b4772e5..646a931bda 100644 --- a/node/Dockerfile +++ b/node/Dockerfile @@ -19,7 +19,7 @@ ARG GO_BUILD_ARGS=-race RUN --mount=type=cache,target=/root/.cache --mount=type=cache,target=/go \ export CGO_ENABLED=1 && \ cd node && \ - go build ${GO_BUILD_ARGS} -gcflags="all=-N -l" --ldflags '-extldflags "-Wl,--allow-multiple-definition" -X "github.com/certusone/wormhole/node/cmd/guardiand.Build=dev"' -mod=readonly -o /guardiand github.com/certusone/wormhole/node && \ + go build ${GO_BUILD_ARGS} -gcflags="all=-N -l" --ldflags '-X "github.com/certusone/wormhole/node/cmd/guardiand.Build=dev"' -mod=readonly -o /guardiand github.com/certusone/wormhole/node && \ go get github.com/CosmWasm/wasmvm@v1.1.1 && \ cp /go/pkg/mod/github.com/!cosm!wasm/wasmvm@v1.1.1/internal/api/libwasmvm.*.so /usr/lib/ diff --git a/node/Makefile b/node/Makefile index 5fc2c94974..fca11d951d 100644 --- a/node/Makefile +++ b/node/Makefile @@ -1,13 +1,3 @@ -.PHONY test +.PHONY: test test: -# Use this command on amd64 systems - go test -v -ldflags '-extldflags "-Wl,--allow-multiple-definition" ' ./... - -.PHONY test-arm64 -test-arm64: -# Use this command on arm64, otherwise you will encounter linker errors. -# It's not perfect: it will fail due to 'undefined symbols' errors -# for packges using cgo. Still, it will get you farther than running -# the default command. -# To test a single package, use these -ldflags with e.g. ./pkg/governor - go test -ldflags '-extldflags "-Wl,-ld_classic " ' ./... + go test -v ./... diff --git a/node/cmd/guardiand/adminnodes.go b/node/cmd/guardiand/adminnodes.go index cb2e5a06e6..08b0ab21c9 100644 --- a/node/cmd/guardiand/adminnodes.go +++ b/node/cmd/guardiand/adminnodes.go @@ -85,6 +85,7 @@ func runListNodes(cmd *cobra.Command, args []string) { vaa.ChainID } + // NOTE: Please keep these in numerical order by chain ID. networks := []network{ {"Solana", vaa.ChainIDSolana}, {"Ethereum", vaa.ChainIDEthereum}, @@ -92,10 +93,8 @@ func runListNodes(cmd *cobra.Command, args []string) { {"BSC", vaa.ChainIDBSC}, {"Polygon", vaa.ChainIDPolygon}, {"Avalanche", vaa.ChainIDAvalanche}, - {"Algorand", vaa.ChainIDAlgorand}, - {"Aptos", vaa.ChainIDAptos}, - {"Sui", vaa.ChainIDSui}, {"Oasis", vaa.ChainIDOasis}, + {"Algorand", vaa.ChainIDAlgorand}, {"Aurora", vaa.ChainIDAurora}, {"Fantom", vaa.ChainIDFantom}, {"Karura", vaa.ChainIDKarura}, @@ -103,32 +102,43 @@ func runListNodes(cmd *cobra.Command, args []string) { {"Klaytn", vaa.ChainIDKlaytn}, {"Celo", vaa.ChainIDCelo}, {"Near", vaa.ChainIDNear}, - {"Terra2", vaa.ChainIDTerra2}, - {"Pythnet", vaa.ChainIDPythNet}, {"Moonbeam", vaa.ChainIDMoonbeam}, + {"Terra2", vaa.ChainIDTerra2}, + {"Injective", vaa.ChainIDInjective}, + // Osmosis is not supported in the guardian. + {"Sui", vaa.ChainIDSui}, + {"Aptos", vaa.ChainIDAptos}, {"Arbitrum", vaa.ChainIDArbitrum}, {"Optimism", vaa.ChainIDOptimism}, + // Gnosis is not supported in the guardian. + {"Pythnet", vaa.ChainIDPythNet}, {"Xpla", vaa.ChainIDXpla}, {"Btc", vaa.ChainIDBtc}, - {"Injective", vaa.ChainIDInjective}, - {"Ink", vaa.ChainIDInk}, {"Base", vaa.ChainIDBase}, + // Filecoin is not supported in the guardian. {"Sei", vaa.ChainIDSei}, + // Rootstock is not supported in the guardian. {"Scroll", vaa.ChainIDScroll}, {"Mantle", vaa.ChainIDMantle}, {"Blast", vaa.ChainIDBlast}, {"XLayer", vaa.ChainIDXLayer}, {"Linea", vaa.ChainIDLinea}, {"Berachain", vaa.ChainIDBerachain}, + {"SeiEVM", vaa.ChainIDSeiEVM}, {"Snaxchain", vaa.ChainIDSnaxchain}, {"Unichain", vaa.ChainIDUnichain}, {"Worldchain", vaa.ChainIDWorldchain}, + {"Ink", vaa.ChainIDInk}, + {"HyperEVM", vaa.ChainIDHyperEVM}, + {"Monad", vaa.ChainIDMonad}, + {"Movement", vaa.ChainIDMovement}, {"Wormchain", vaa.ChainIDWormchain}, + // The IBC chains (4000 range) are not included here. {"Sepolia", vaa.ChainIDSepolia}, - {"Holesky", vaa.ChainIDHolesky}, {"ArbitrumSepolia", vaa.ChainIDArbitrumSepolia}, {"BaseSepolia", vaa.ChainIDBaseSepolia}, {"OptimismSepolia", vaa.ChainIDOptimismSepolia}, + {"Holesky", vaa.ChainIDHolesky}, {"PolygonSepolia", vaa.ChainIDPolygonSepolia}, {"MonadDevnet", vaa.ChainIDMonadDevnet}, } diff --git a/node/cmd/guardiand/node.go b/node/cmd/guardiand/node.go index 0bc96197fc..fe569050ee 100644 --- a/node/cmd/guardiand/node.go +++ b/node/cmd/guardiand/node.go @@ -65,7 +65,6 @@ var ( guardianKeyPath *string guardianSignerUri *string - solanaContract *string ethRPC *string ethContract *string @@ -150,10 +149,16 @@ var ( aptosAccount *string aptosHandle *string + movementRPC *string + movementAccount *string + movementHandle *string + suiRPC *string suiMoveEventType *string - solanaRPC *string + solanaRPC *string + solanaContract *string + solanaShimContract *string pythnetContract *string pythnetRPC *string @@ -195,6 +200,9 @@ var ( worldchainRPC *string worldchainContract *string + monadRPC *string + monadContract *string + monadDevnetRPC *string monadDevnetContract *string @@ -204,6 +212,9 @@ var ( hyperEvmRPC *string hyperEvmContract *string + seiEvmRPC *string + seiEvmContract *string + sepoliaRPC *string sepoliaContract *string @@ -286,7 +297,8 @@ func init() { guardianKeyPath = NodeCmd.Flags().String("guardianKey", "", "Path to guardian key") guardianSignerUri = NodeCmd.Flags().String("guardianSignerUri", "", "Guardian signer URI") - solanaContract = NodeCmd.Flags().String("solanaContract", "", "Address of the Solana program (required)") + solanaContract = NodeCmd.Flags().String("solanaContract", "", "Address of the Solana program (required if solanaRpc is specified)") + solanaShimContract = NodeCmd.Flags().String("solanaShimContract", "", "Address of the Solana shim program") ethRPC = node.RegisterFlagWithValidationOrFail(NodeCmd, "ethRPC", "Ethereum RPC URL", "ws://eth-devnet:8545", []string{"ws", "wss"}) ethContract = NodeCmd.Flags().String("ethContract", "", "Ethereum contract address") @@ -371,6 +383,10 @@ func init() { aptosAccount = NodeCmd.Flags().String("aptosAccount", "", "aptos account") aptosHandle = NodeCmd.Flags().String("aptosHandle", "", "aptos handle") + movementRPC = node.RegisterFlagWithValidationOrFail(NodeCmd, "movementRPC", "Movement RPC URL", "", []string{"http", "https"}) + movementAccount = NodeCmd.Flags().String("movementAccount", "", "movement account") + movementHandle = NodeCmd.Flags().String("movementHandle", "", "movement handle") + suiRPC = node.RegisterFlagWithValidationOrFail(NodeCmd, "suiRPC", "Sui RPC URL", "http://sui:9000", []string{"http", "https"}) suiMoveEventType = NodeCmd.Flags().String("suiMoveEventType", "", "Sui move event type for publish_message") @@ -428,6 +444,12 @@ func init() { hyperEvmRPC = node.RegisterFlagWithValidationOrFail(NodeCmd, "hyperEvmRPC", "HyperEVM RPC URL", "ws://eth-devnet:8545", []string{"ws", "wss"}) hyperEvmContract = NodeCmd.Flags().String("hyperEvmContract", "", "HyperEVM contract address") + monadRPC = node.RegisterFlagWithValidationOrFail(NodeCmd, "monadRPC", "Monad RPC URL", "ws://eth-devnet:8545", []string{"ws", "wss"}) + monadContract = NodeCmd.Flags().String("monadContract", "", "Monad contract address") + + seiEvmRPC = node.RegisterFlagWithValidationOrFail(NodeCmd, "seiEvmRPC", "SeiEVM RPC URL", "ws://eth-devnet:8545", []string{"ws", "wss"}) + seiEvmContract = NodeCmd.Flags().String("seiEvmContract", "", "SeiEVM contract address") + arbitrumSepoliaRPC = node.RegisterFlagWithValidationOrFail(NodeCmd, "arbitrumSepoliaRPC", "Arbitrum on Sepolia RPC URL", "ws://eth-devnet:8545", []string{"ws", "wss"}) arbitrumSepoliaContract = NodeCmd.Flags().String("arbitrumSepoliaContract", "", "Arbitrum on Sepolia contract address") @@ -650,7 +672,7 @@ func runNode(cmd *cobra.Command, args []string) { // Verify flags - if *nodeName == "" { + if *nodeName == "" && env == common.MainNet { logger.Fatal("Please specify --nodeName") } if *nodeKeyPath == "" && env != common.UnsafeDevNet { // In devnet mode, keys are deterministically generated. @@ -760,6 +782,10 @@ func runNode(cmd *cobra.Command, args []string) { logger.Fatal("Please specify --telemetryLokiURL or set --disableTelemetry=false") } + if *nodeName == "" { + logger.Fatal("If telemetry is enabled, --nodeName must be set") + } + // Get libp2p peer ID from private key pk := p2pKey.GetPublic() peerID, err := peer.IDFromPublicKey(pk) @@ -819,6 +845,8 @@ func runNode(cmd *cobra.Command, args []string) { *worldchainContract = checkEvmArgs(logger, *worldchainRPC, *worldchainContract, "worldchain", true) *inkContract = checkEvmArgs(logger, *inkRPC, *inkContract, "ink", false) *hyperEvmContract = checkEvmArgs(logger, *hyperEvmRPC, *hyperEvmContract, "hyperEvm", false) + *monadContract = checkEvmArgs(logger, *monadRPC, *monadContract, "monad", false) + *seiEvmContract = checkEvmArgs(logger, *seiEvmRPC, *seiEvmContract, "seiEvm", false) // These chains will only ever be testnet / devnet. *sepoliaContract = checkEvmArgs(logger, *sepoliaRPC, *sepoliaContract, "sepolia", false) @@ -833,6 +861,14 @@ func runNode(cmd *cobra.Command, args []string) { logger.Fatal("Both --solanaContract and --solanaRPC must be set or both unset") } + if *solanaShimContract != "" && *solanaContract == "" { + logger.Fatal("--solanaShimContract may only be specified if --solanaContract is specified") + } + + if *solanaShimContract != "" && env == common.MainNet { + logger.Fatal("--solanaShimContract is not currently supported in mainnet") + } + if !argsConsistent([]string{*pythnetContract, *pythnetRPC, *pythnetWS}) { logger.Fatal("Either --pythnetContract, --pythnetRPC and --pythnetWS must all be set or all unset") } @@ -873,6 +909,10 @@ func runNode(cmd *cobra.Command, args []string) { logger.Fatal("Either --aptosAccount, --aptosRPC and --aptosHandle must all be set or all unset") } + if !argsConsistent([]string{*movementAccount, *movementRPC, *movementHandle}) { + logger.Fatal("Either --movementAccount, --movementRPC and --movementHandle must all be set or all unset") + } + if !argsConsistent([]string{*suiRPC, *suiMoveEventType}) { logger.Fatal("Either --suiRPC and --suiMoveEventType must all be set or all unset") } @@ -920,68 +960,85 @@ func runNode(cmd *cobra.Command, args []string) { logger.Fatal("Infura is known to send incorrect blocks - please use your own nodes") } + // NOTE: Please keep these in numerical order by chain ID. rpcMap := make(map[string]string) - rpcMap["acalaRPC"] = *acalaRPC - rpcMap["accountantWS"] = *accountantWS + rpcMap["solanaRPC"] = *solanaRPC + rpcMap["ethRPC"] = *ethRPC + rpcMap["terraWS"] = *terraWS + rpcMap["terraLCD"] = *terraLCD + rpcMap["bscRPC"] = *bscRPC + rpcMap["polygonRPC"] = *polygonRPC + rpcMap["avalancheRPC"] = *avalancheRPC + rpcMap["oasisRPC"] = *oasisRPC rpcMap["algorandIndexerRPC"] = *algorandIndexerRPC rpcMap["algorandAlgodRPC"] = *algorandAlgodRPC - rpcMap["aptosRPC"] = *aptosRPC - rpcMap["arbitrumRPC"] = *arbitrumRPC - rpcMap["avalancheRPC"] = *avalancheRPC - rpcMap["baseRPC"] = *baseRPC - rpcMap["berachainRPC"] = *berachainRPC - rpcMap["blastRPC"] = *blastRPC - rpcMap["bscRPC"] = *bscRPC - rpcMap["celoRPC"] = *celoRPC - rpcMap["ethRPC"] = *ethRPC + // ChainIDAurora is not supported in the guardian. rpcMap["fantomRPC"] = *fantomRPC - rpcMap["hyperEvmRPC"] = *hyperEvmRPC - rpcMap["ibcBlockHeightURL"] = *ibcBlockHeightURL - rpcMap["ibcLCD"] = *ibcLCD - rpcMap["ibcWS"] = *ibcWS - rpcMap["injectiveLCD"] = *injectiveLCD - rpcMap["injectiveWS"] = *injectiveWS - rpcMap["inkRPC"] = *inkRPC rpcMap["karuraRPC"] = *karuraRPC + rpcMap["acalaRPC"] = *acalaRPC rpcMap["klaytnRPC"] = *klaytnRPC - rpcMap["lineaRPC"] = *lineaRPC - rpcMap["mantleRPC"] = *mantleRPC - rpcMap["moonbeamRPC"] = *moonbeamRPC + rpcMap["celoRPC"] = *celoRPC rpcMap["nearRPC"] = *nearRPC - rpcMap["oasisRPC"] = *oasisRPC + rpcMap["moonbeamRPC"] = *moonbeamRPC + rpcMap["terra2WS"] = *terra2WS + rpcMap["terra2LCD"] = *terra2LCD + rpcMap["injectiveLCD"] = *injectiveLCD + rpcMap["injectiveWS"] = *injectiveWS + // ChainIDOsmosis is not supported in the guardian. + rpcMap["suiRPC"] = *suiRPC + rpcMap["aptosRPC"] = *aptosRPC + rpcMap["arbitrumRPC"] = *arbitrumRPC rpcMap["optimismRPC"] = *optimismRPC - rpcMap["polygonRPC"] = *polygonRPC + // ChainIDGnosis is not supported in the guardian. rpcMap["pythnetRPC"] = *pythnetRPC rpcMap["pythnetWS"] = *pythnetWS + rpcMap["xplaWS"] = *xplaWS + rpcMap["xplaLCD"] = *xplaLCD + // ChainIDBtc is not supported in the guardian. + rpcMap["baseRPC"] = *baseRPC + // ChainIDSei is supported over IBC, so it's not listed here. + // ChainIDRootstock is not supported in the guardian. + rpcMap["scrollRPC"] = *scrollRPC + rpcMap["mantleRPC"] = *mantleRPC + rpcMap["blastRPC"] = *blastRPC + rpcMap["xlayerRPC"] = *xlayerRPC + rpcMap["lineaRPC"] = *lineaRPC + rpcMap["berachainRPC"] = *berachainRPC + rpcMap["seiEvmRPC"] = *seiEvmRPC + rpcMap["snaxchainRPC"] = *snaxchainRPC + rpcMap["unichainRPC"] = *unichainRPC + rpcMap["worldchainRPC"] = *worldchainRPC + rpcMap["inkRPC"] = *inkRPC + rpcMap["hyperEvmRPC"] = *hyperEvmRPC + rpcMap["monadRPC"] = *monadRPC + rpcMap["movementRPC"] = *movementRPC + + // Wormchain is in the 3000 range. + rpcMap["wormchainURL"] = *wormchainURL + + // Generate the IBC chains (3000 range). + for _, ibcChain := range ibc.Chains { + rpcMap[ibcChain.String()] = "IBC" + } + + // The testnet only chains (10000 range) go here. if env == common.TestNet { rpcMap["sepoliaRPC"] = *sepoliaRPC - rpcMap["holeskyRPC"] = *holeskyRPC rpcMap["arbitrumSepoliaRPC"] = *arbitrumSepoliaRPC rpcMap["baseSepoliaRPC"] = *baseSepoliaRPC rpcMap["optimismSepoliaRPC"] = *optimismSepoliaRPC + rpcMap["holeskyRPC"] = *holeskyRPC rpcMap["polygonSepoliaRPC"] = *polygonSepoliaRPC rpcMap["monadDevnetRPC"] = *monadDevnetRPC } - rpcMap["scrollRPC"] = *scrollRPC - rpcMap["solanaRPC"] = *solanaRPC - rpcMap["snaxchainRPC"] = *snaxchainRPC - rpcMap["suiRPC"] = *suiRPC - rpcMap["terraWS"] = *terraWS - rpcMap["terraLCD"] = *terraLCD - rpcMap["terra2WS"] = *terra2WS - rpcMap["terra2LCD"] = *terra2LCD - rpcMap["unichainRPC"] = *unichainRPC - rpcMap["worldchainRPC"] = *worldchainRPC + + // Other, non-chain specific parameters go here. + rpcMap["accountantWS"] = *accountantWS rpcMap["gatewayWS"] = *gatewayWS rpcMap["gatewayLCD"] = *gatewayLCD - rpcMap["wormchainURL"] = *wormchainURL - rpcMap["xlayerRPC"] = *xlayerRPC - rpcMap["xplaWS"] = *xplaWS - rpcMap["xplaLCD"] = *xplaLCD - - for _, ibcChain := range ibc.Chains { - rpcMap[ibcChain.String()] = "IBC" - } + rpcMap["ibcBlockHeightURL"] = *ibcBlockHeightURL + rpcMap["ibcLCD"] = *ibcLCD + rpcMap["ibcWS"] = *ibcWS // Handle SIGTERM sigterm := make(chan os.Signal, 1) @@ -1449,6 +1506,30 @@ func runNode(cmd *cobra.Command, args []string) { watcherConfigs = append(watcherConfigs, wc) } + if shouldStart(monadRPC) { + wc := &evm.WatcherConfig{ + NetworkID: "monad", + ChainID: vaa.ChainIDMonad, + Rpc: *monadRPC, + Contract: *monadContract, + CcqBackfillCache: *ccqBackfillCache, + } + + watcherConfigs = append(watcherConfigs, wc) + } + + if shouldStart(seiEvmRPC) { + wc := &evm.WatcherConfig{ + NetworkID: "seievm", + ChainID: vaa.ChainIDSeiEVM, + Rpc: *seiEvmRPC, + Contract: *seiEvmContract, + CcqBackfillCache: *ccqBackfillCache, + } + + watcherConfigs = append(watcherConfigs, wc) + } + if shouldStart(terraWS) { wc := &cosmwasm.WatcherConfig{ NetworkID: "terra", @@ -1531,6 +1612,17 @@ func runNode(cmd *cobra.Command, args []string) { watcherConfigs = append(watcherConfigs, wc) } + if shouldStart(movementRPC) { + wc := &aptos.WatcherConfig{ + NetworkID: "movement", + ChainID: vaa.ChainIDMovement, + Rpc: *movementRPC, + Account: *movementAccount, + Handle: *movementHandle, + } + watcherConfigs = append(watcherConfigs, wc) + } + if shouldStart(suiRPC) { wc := &sui.WatcherConfig{ NetworkID: "sui", @@ -1549,6 +1641,7 @@ func runNode(cmd *cobra.Command, args []string) { Rpc: *solanaRPC, Websocket: "", Contract: *solanaContract, + ShimContract: *solanaShimContract, ReceiveObsReq: false, Commitment: rpc.CommitmentConfirmed, } @@ -1562,6 +1655,7 @@ func runNode(cmd *cobra.Command, args []string) { Rpc: *solanaRPC, Websocket: "", Contract: *solanaContract, + ShimContract: *solanaShimContract, ReceiveObsReq: true, Commitment: rpc.CommitmentFinalized, } diff --git a/node/cmd/root.go b/node/cmd/root.go index f221b47969..996e146fd9 100644 --- a/node/cmd/root.go +++ b/node/cmd/root.go @@ -7,6 +7,7 @@ import ( "github.com/certusone/wormhole/node/cmd/ccq" "github.com/certusone/wormhole/node/cmd/debug" "github.com/certusone/wormhole/node/cmd/spy" + txverifier "github.com/certusone/wormhole/node/cmd/txverifier" "github.com/certusone/wormhole/node/pkg/version" "github.com/spf13/cobra" @@ -49,6 +50,7 @@ func init() { rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.guardiand.yaml)") rootCmd.AddCommand(guardiand.NodeCmd) rootCmd.AddCommand(spy.SpyCmd) + rootCmd.AddCommand(txverifier.TransferVerifierCmd) rootCmd.AddCommand(ccq.QueryServerCmd) rootCmd.AddCommand(guardiand.KeygenCmd) rootCmd.AddCommand(guardiand.AdminCmd) diff --git a/node/cmd/txverifier/evm.go b/node/cmd/txverifier/evm.go new file mode 100644 index 0000000000..478faaa83d --- /dev/null +++ b/node/cmd/txverifier/evm.go @@ -0,0 +1,157 @@ +package txverifier + +import ( + "context" + "fmt" + "os" + + "github.com/certusone/wormhole/node/pkg/telemetry" + txverifier "github.com/certusone/wormhole/node/pkg/txverifier" + "github.com/certusone/wormhole/node/pkg/version" + "github.com/certusone/wormhole/node/pkg/watchers/evm/connectors" + "github.com/ethereum/go-ethereum/common" + ipfslog "github.com/ipfs/go-log/v2" + "github.com/spf13/cobra" + "go.uber.org/zap" +) + +var TransferVerifierCmdEvm = &cobra.Command{ + Use: "evm", + Short: "Transfer Verifier for EVM-based chains", + Run: runTransferVerifierEvm, +} + +// Configuration variables for EVM interactions. +var ( + // RPC endpoint URL for interacting with an EVM node. + evmRpc *string + // Contract address of the core bridge. + evmCoreContract *string + // Contract address of the token bridge. + evmTokenBridgeContract *string + // Contract address of the wrapped native asset, e.g. WETH for Ethereum + wrappedNativeContract *string + // Height difference between pruning windows (in blocks). + pruneHeightDelta *uint64 +) + +// Function to initialize the configuration for the TransferVerifierCmdEvm flags. +// The MarkFlagRequired calls will cause the script to fail on their own. No need to handle the errors manually. +// +//nolint:errcheck +func init() { + evmRpc = TransferVerifierCmdEvm.Flags().String("rpcUrl", "ws://localhost:8546", "RPC url") + evmCoreContract = TransferVerifierCmdEvm.Flags().String("coreContract", "", "core bridge address") + evmTokenBridgeContract = TransferVerifierCmdEvm.Flags().String("tokenContract", "", "token bridge") + wrappedNativeContract = TransferVerifierCmdEvm.Flags().String("wrappedNativeContract", "", "wrapped native address (e.g. WETH on Ethereum)") + pruneHeightDelta = TransferVerifierCmdEvm.Flags().Uint64("pruneHeightDelta", 10, "The number of blocks for which to retain transaction receipts. Defaults to 10 blocks.") + + TransferVerifierCmd.MarkFlagRequired("rpcUrl") + TransferVerifierCmd.MarkFlagRequired("coreContract") + TransferVerifierCmd.MarkFlagRequired("tokenContract") + TransferVerifierCmd.MarkFlagRequired("wrappedNativeContract") +} + +// Note: logger.Error should be reserved only for conditions that break the +// invariants of the Token Bridge +func runTransferVerifierEvm(cmd *cobra.Command, args []string) { + + // Setup logging + lvl, logErr := ipfslog.LevelFromString(*logLevel) + if logErr != nil { + fmt.Println("Invalid log level") + os.Exit(1) + } + + logger := ipfslog.Logger("wormhole-transfer-verifier").Desugar() + ipfslog.SetAllLoggers(lvl) + + // Setup logging to Loki if configured + if *telemetryLokiUrl != "" && *telemetryNodeName != "" { + labels := map[string]string{ + // Is this required? + // "network": *p2pNetworkID, + "node_name": *telemetryNodeName, + "version": version.Version(), + } + + tm, err := telemetry.NewLokiCloudLogger( + context.Background(), + logger, + *telemetryLokiUrl, + // Note: the product name parameter here is representing a per-chain configuration, so 'eth' is used + // rather than 'evm'. This allows us to distinguish this instance from other EVM chains that may be added in + // the future. + "transfer-verifier-eth", + // Private logs are not used in this code + false, + labels, + ) + if err != nil { + logger.Fatal("Failed to initialize telemetry", zap.Error(err)) + } + + defer tm.Close() + logger = tm.WrapLogger(logger) // Wrap logger with telemetry logger + } + + logger.Info("Starting EVM transfer verifier") + + logger.Debug("EVM rpc connection", zap.String("url", *evmRpc)) + logger.Debug("EVM core contract", zap.String("address", *evmCoreContract)) + logger.Debug("EVM token bridge contract", zap.String("address", *evmTokenBridgeContract)) + logger.Debug("EVM wrapped native asset contract", zap.String("address", *wrappedNativeContract)) + logger.Debug("EVM prune config", + zap.Uint64("height delta", *pruneHeightDelta)) + + // Create the RPC connection, context, and channels + ctx, ctxCancel := context.WithCancel(context.Background()) + defer ctxCancel() + + var evmConnector connectors.Connector + evmConnector, connectErr := connectors.NewEthereumBaseConnector(ctx, "eth", *evmRpc, common.HexToAddress(*evmCoreContract), logger) + if connectErr != nil { + logger.Fatal("could not create new evm base connector", + zap.Error(connectErr)) + } + + // Create main configuration for Transfer Verification + transferVerifier, err := txverifier.NewTransferVerifier( + evmConnector, + &txverifier.TVAddresses{ + CoreBridgeAddr: common.HexToAddress(*evmCoreContract), + TokenBridgeAddr: common.HexToAddress(*evmTokenBridgeContract), + WrappedNativeAddr: common.HexToAddress(*wrappedNativeContract), + }, + *pruneHeightDelta, + logger, + ) + + if err != nil { + logger.Fatal("could not create new transfer verifier", zap.Error(err)) + } + + // Set-up for main processing loop + + // Subscription for LogMessagePublished events + sub := txverifier.NewSubscription(evmConnector.Client(), evmConnector) + sub.Subscribe(ctx) + defer sub.Close() + + // MAIN LOOP: + // - watch for LogMessagePublished events coming from the connector attached to the core bridge. + // - process the events through the transfer verifier. + for { + select { + case <-ctx.Done(): + logger.Info("context cancelled, exiting") + return + case subErr := <-sub.Errors(): + logger.Warn("error on subscription", zap.Error(subErr)) + + // Process observed LogMessagePublished events + case vLog := <-sub.Events(): + transferVerifier.ProcessEvent(ctx, vLog, nil) + } + } +} diff --git a/node/cmd/txverifier/sui.go b/node/cmd/txverifier/sui.go new file mode 100644 index 0000000000..f41e0dc36a --- /dev/null +++ b/node/cmd/txverifier/sui.go @@ -0,0 +1,209 @@ +package txverifier + +import ( + "context" + "fmt" + "os" + "strconv" + "time" + + "github.com/certusone/wormhole/node/pkg/telemetry" + txverifier "github.com/certusone/wormhole/node/pkg/txverifier" + "github.com/certusone/wormhole/node/pkg/version" + + ipfslog "github.com/ipfs/go-log/v2" + "github.com/spf13/cobra" + "go.uber.org/zap" +) + +const ( + INITIAL_EVENT_FETCH_LIMIT = 25 +) + +// CLI args +var ( + suiRPC *string + suiCoreContract *string + suiTokenBridgeEmitter *string + suiTokenBridgeContract *string + suiProcessInitialEvents *bool +) + +var TransferVerifierCmdSui = &cobra.Command{ + Use: "sui", + Short: "Transfer Verifier for Sui", + Run: runTransferVerifierSui, +} + +// CLI parameters +// The MarkFlagRequired calls will cause the script to fail on their own. No need to handle the errors manually. +// +//nolint:errcheck +func init() { + suiRPC = TransferVerifierCmdSui.Flags().String("suiRPC", "", "Sui RPC url") + suiCoreContract = TransferVerifierCmdSui.Flags().String("suiCoreContract", "", "Sui core contract address") + suiTokenBridgeEmitter = TransferVerifierCmdSui.Flags().String("suiTokenBridgeEmitter", "", "Token bridge emitter on Sui") + suiTokenBridgeContract = TransferVerifierCmdSui.Flags().String("suiTokenBridgeContract", "", "Token bridge contract on Sui") + suiProcessInitialEvents = TransferVerifierCmdSui.Flags().Bool("suiProcessInitialEvents", false, "Indicate whether the Sui transfer verifier should process the initial events it fetches") + + TransferVerifierCmd.MarkFlagRequired("suiRPC") + TransferVerifierCmd.MarkFlagRequired("suiCoreContract") + TransferVerifierCmd.MarkFlagRequired("suiTokenBridgeEmitter") + TransferVerifierCmd.MarkFlagRequired("suiTokenBridgeContract") +} + +func runTransferVerifierSui(cmd *cobra.Command, args []string) { + ctx := context.Background() + + // Setup logging + // lvl, err := ipfslog.LevelFromString(*logLevel) + lvl, err := ipfslog.LevelFromString("info") + if err != nil { + fmt.Println("Invalid log level") + os.Exit(1) + } + + logger := ipfslog.Logger("wormhole-transfer-verifier-sui").Desugar() + + ipfslog.SetAllLoggers(lvl) + + // Setup logging to Loki if configured + if *telemetryLokiUrl != "" && *telemetryNodeName != "" { + labels := map[string]string{ + // Is this required? + // "network": *p2pNetworkID, + "node_name": *telemetryNodeName, + "version": version.Version(), + } + + tm, err := telemetry.NewLokiCloudLogger( + context.Background(), + logger, + *telemetryLokiUrl, + "transfer-verifier-sui", + // Private logs are not used in this code + false, + labels, + ) + if err != nil { + logger.Fatal("Failed to initialize telemetry", zap.Error(err)) + } + + defer tm.Close() + logger = tm.WrapLogger(logger) // Wrap logger with telemetry logger + } + + logger.Info("Starting Sui transfer verifier") + logger.Debug("Sui rpc connection", zap.String("url", *suiRPC)) + logger.Debug("Sui core contract", zap.String("address", *suiCoreContract)) + logger.Debug("Sui token bridge contract", zap.String("address", *suiTokenBridgeContract)) + logger.Debug("token bridge event emitter", zap.String("object id", *suiTokenBridgeEmitter)) + logger.Debug("process initial events", zap.Bool("processInitialEvents", *suiProcessInitialEvents)) + + // Verify CLI parameters + if *suiRPC == "" || *suiCoreContract == "" || *suiTokenBridgeEmitter == "" || *suiTokenBridgeContract == "" { + logger.Fatal("One or more CLI parameters are empty", + zap.String("suiRPC", *suiRPC), + zap.String("suiCoreContract", *suiCoreContract), + zap.String("suiTokenBridgeEmitter", *suiTokenBridgeEmitter), + zap.String("suiTokenBridgeContract", *suiTokenBridgeContract)) + } + + // Create a new SuiTransferVerifier + suiTransferVerifier := txverifier.NewSuiTransferVerifier(*suiCoreContract, *suiTokenBridgeEmitter, *suiTokenBridgeContract) + + // Get the event filter + eventFilter := suiTransferVerifier.GetEventFilter() + + suiApiConnection := txverifier.NewSuiApiConnection(*suiRPC) + + // Initial event fetching + resp, err := suiApiConnection.QueryEvents(eventFilter, "null", INITIAL_EVENT_FETCH_LIMIT, true) + if err != nil { + logger.Fatal("Error in querying initial events", zap.Error(err)) + } + + initialEvents := resp.Result.Data + + // Use the latest timestamp to determine the starting point for live processing + var latestTimestamp int + for _, event := range initialEvents { + if event.Timestamp != nil { + timestampInt, err := strconv.Atoi(*event.Timestamp) + if err != nil { + logger.Error("Error converting timestamp to int", zap.Error(err)) + continue + } + if timestampInt > latestTimestamp { + latestTimestamp = timestampInt + } + } + } + logger.Info("Initial events fetched", zap.Int("number of initial events", len(initialEvents)), zap.Int("latestTimestamp", latestTimestamp)) + + // If specified, process the initial events. This is useful for running a number of digests + // through the verifier before starting live processing. + if *suiProcessInitialEvents { + logger.Info("Processing initial events") + for _, event := range initialEvents { + if event.ID.TxDigest != nil { + _, err = suiTransferVerifier.ProcessDigest(*event.ID.TxDigest, suiApiConnection, logger) + if err != nil { + logger.Error(err.Error()) + } + } + } + } + + // Ticker for live processing + ticker := time.NewTicker(5 * time.Second) + defer ticker.Stop() + + for { + select { + case <-ctx.Done(): + logger.Info("Context cancelled") + case <-ticker.C: + // Fetch new events + resp, err := suiApiConnection.QueryEvents(eventFilter, "null", 25, true) + if err != nil { + logger.Error("Error in querying new events", zap.Error(err)) + continue + } + + newEvents := resp.Result.Data + + // List of transaction digests for transactions in which the WormholeMessage + // event was emitted. + var txDigests []string + + // Iterate over all events and get the transaction digests for events younger + // than latestTimestamp. Also update latestTimestamp. + for _, event := range newEvents { + if event.Timestamp != nil { + timestampInt, err := strconv.Atoi(*event.Timestamp) + if err != nil { + logger.Error("Error converting timestamp to int", zap.Error(err)) + continue + } + if timestampInt > latestTimestamp { + latestTimestamp = timestampInt + if event.ID.TxDigest != nil { + txDigests = append(txDigests, *event.ID.TxDigest) + } + } + } + } + + for _, txDigest := range txDigests { + _, err := suiTransferVerifier.ProcessDigest(txDigest, suiApiConnection, logger) + if err != nil { + logger.Error(err.Error()) + } + } + + logger.Info("New events processed", zap.Int("latestTimestamp", latestTimestamp), zap.Int("txDigestCount", len(txDigests))) + + } + } +} diff --git a/node/cmd/txverifier/txverifier.go b/node/cmd/txverifier/txverifier.go new file mode 100644 index 0000000000..946abe2b88 --- /dev/null +++ b/node/cmd/txverifier/txverifier.go @@ -0,0 +1,36 @@ +package txverifier + +import ( + "github.com/spf13/cobra" +) + +var TransferVerifierCmd = &cobra.Command{ + Use: "transfer-verifier", + Short: "Transfer Verifier", +} + +var ( + // logLevel is a global flag that is used to set the logging level for the TransferVerifierCmd + logLevel *string + // telemetryLokiUrl is a global flag that is used to set the Loki cloud logging URL for the TransferVerifierCmd. + telemetryLokiUrl *string + // telemetryNodeName is a global flag that is used to set the node name used in telemetry for the TransferVerifierCmd. + telemetryNodeName *string +) + +// init initializes the global flags and subcommands for the TransferVerifierCmd. +// It sets up a persistent flag for logging level with a default value of "info" +// and adds subcommands for EVM and Sui transfer verification. +func init() { + // Global flags + logLevel = TransferVerifierCmd.PersistentFlags().String("logLevel", "info", "Logging level (debug, info, warn, error, dpanic, panic, fatal)") + telemetryLokiUrl = TransferVerifierCmd.PersistentFlags().String("telemetryLokiUrl", "", "Loki cloud logging URL") + telemetryNodeName = TransferVerifierCmd.PersistentFlags().String("telemetryNodeName", "", "Node name used in telemetry") + + // Either both loki flags should be present or neither of them. + TransferVerifierCmd.MarkFlagsRequiredTogether("telemetryLokiUrl", "telemetryNodeName") + + // Subcommands corresponding to chains supported by the Transfer Verifier. + TransferVerifierCmd.AddCommand(TransferVerifierCmdEvm) + TransferVerifierCmd.AddCommand(TransferVerifierCmdSui) +} diff --git a/node/hack/accountant/send_obs.go b/node/hack/accountant/send_obs.go index f64bdbf843..24b77d5de2 100644 --- a/node/hack/accountant/send_obs.go +++ b/node/hack/accountant/send_obs.go @@ -58,6 +58,7 @@ func main() { return } + // Don't increment the sequence number here. if !testSubmit(ctx, logger, guardianSigner, wormchainConn, contract, "0000000000000000000000000290fb167208af455bb137780163b7b7a9a10c16", timestamp, sequence, true, "Already commited should succeed") { return } @@ -82,6 +83,11 @@ func main() { return } + sequence += 10 + if !testBigBatch(ctx, logger, guardianSigner, wormchainConn, contract, "0000000000000000000000000290fb167208af455bb137780163b7b7a9a10c16", timestamp, sequence, true, "Submit of big batch should succeed") { + return + } + logger.Info("Success! All tests passed!") } @@ -102,7 +108,7 @@ func testSubmit( Payload, _ := hex.DecodeString("010000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000002d8be6bf0baa74e0a907016679cae9190e80dd0a0002000000000000000000000000c10820983f33456ce7beb3a046f5a83fa34f027d0c200000000000000000000000000000000000000000000000000000000000000000") msg := common.MessagePublication{ - TxHash: TxHash, + TxID: TxHash.Bytes(), Timestamp: timestamp, Nonce: uint32(0), Sequence: sequence, @@ -167,7 +173,7 @@ func testBatch( msgs := []*common.MessagePublication{} msg1 := common.MessagePublication{ - TxHash: TxHash, + TxID: TxHash.Bytes(), Timestamp: timestamp, Nonce: nonce, Sequence: sequence, @@ -181,7 +187,7 @@ func testBatch( nonce = nonce + 1 sequence = sequence + 1 msg2 := common.MessagePublication{ - TxHash: TxHash, + TxID: TxHash.Bytes(), Timestamp: time.Now(), Nonce: nonce, Sequence: sequence, @@ -246,7 +252,7 @@ func testBatchWithcommitted( logger.Info("submitting a single transfer that should work") msg1 := common.MessagePublication{ - TxHash: TxHash, + TxID: TxHash.Bytes(), Timestamp: timestamp, Nonce: nonce, Sequence: sequence, @@ -269,7 +275,7 @@ func testBatchWithcommitted( nonce = nonce + 1 sequence = sequence + 1 msg2 := common.MessagePublication{ - TxHash: TxHash, + TxID: TxHash.Bytes(), Timestamp: time.Now(), Nonce: nonce, Sequence: sequence, @@ -338,7 +344,7 @@ func testBatchWithDigestError( logger.Info("submitting a single transfer that should work") msg1 := common.MessagePublication{ - TxHash: TxHash, + TxID: TxHash.Bytes(), Timestamp: timestamp, Nonce: nonce, Sequence: sequence, @@ -361,7 +367,7 @@ func testBatchWithDigestError( nonce = nonce + 1 sequence = sequence + 1 msg2 := common.MessagePublication{ - TxHash: TxHash, + TxID: TxHash.Bytes(), Timestamp: time.Now(), Nonce: nonce, Sequence: sequence, @@ -440,3 +446,72 @@ func submit( return accountant.SubmitObservationsToContract(ctx, logger, guardianSigner, gsIndex, guardianIndex, wormchainConn, contract, accountant.SubmitObservationPrefix, msgs) } + +func testBigBatch( + ctx context.Context, + logger *zap.Logger, + guardianSigner guardiansigner.GuardianSigner, + wormchainConn *wormconn.ClientConn, + contract string, + emitterAddressStr string, + timestamp time.Time, + sequence uint64, + expectedResult bool, + tag string, +) bool { + EmitterAddress, _ := vaa.StringToAddress(emitterAddressStr) + TxHash := []byte("0123456789012345678901234567890123456789012345678901234567890123") // 64 bytes, the size of a Solana signature. + Payload, _ := hex.DecodeString("010000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000002d8be6bf0baa74e0a907016679cae9190e80dd0a0002000000000000000000000000c10820983f33456ce7beb3a046f5a83fa34f027d0c200000000000000000000000000000000000000000000000000000000000000000") + + msgs := []*common.MessagePublication{} + for idx := 0; idx < 10; idx++ { + msg := common.MessagePublication{ + TxID: TxHash, + Timestamp: timestamp, + Nonce: uint32(0), + Sequence: sequence, + EmitterChain: vaa.ChainIDEthereum, + EmitterAddress: EmitterAddress, + ConsistencyLevel: uint8(15), + Payload: Payload, + } + + msgs = append(msgs, &msg) + sequence += 1 + } + + txResp, err := submit(ctx, logger, guardianSigner, wormchainConn, contract, msgs) + if err != nil { + logger.Error("failed to broadcast Observation request", zap.String("test", tag), zap.Error(err)) + return false + } + + responses, err := accountant.GetObservationResponses(txResp) + if err != nil { + logger.Error("failed to get responses", zap.Error(err)) + return false + } + + if len(responses) != len(msgs) { + logger.Error("number of responses does not match number of messages", zap.Int("numMsgs", len(msgs)), zap.Int("numResp", len(responses)), zap.Error(err)) + return false + } + + msgId := msgs[0].MessageIDString() + status, exists := responses[msgId] + if !exists { + logger.Info("test failed: did not receive an observation response for message", zap.String("test", tag), zap.String("msgId", msgId)) + return false + } + + committed := status.Type == "committed" + + if committed != expectedResult { + logger.Info("test failed", zap.String("test", tag), zap.Uint64("seqNo", sequence), zap.Bool("committed", committed), + zap.String("response", wormchainConn.BroadcastTxResponseToString(txResp))) + return false + } + + logger.Info("test of big batch succeeded", zap.String("test", tag)) + return true +} diff --git a/node/hack/evm_test/wstest.go b/node/hack/evm_test/wstest.go new file mode 100644 index 0000000000..adc8926f74 --- /dev/null +++ b/node/hack/evm_test/wstest.go @@ -0,0 +1,146 @@ +// This tool can be used to verify that an EVM endpoint works properly with go-ethereum websocket subscriptions. +// It can subscribe to latest blocks as well as log events from the Wormhole core contract and just logs them out. +// +// To run this tool, do: +// go run wstest.go --rpc [--contract ] [--blocks] +// +// where +// --contract` subscribes to log events from the specified Wormhole core contract +// --blocks subscribes to the latest blocks. +// +// To listen to log events from the SeiEVM test endpoint (what this was originally written for) do: +// go run wstest.go --rpc wss://evm-ws-testnet.sei-apis.com --contract 0xBB73cB66C26740F31d1FabDC6b7A46a038A300dd + +package main + +import ( + "context" + "flag" + "fmt" + "os" + "os/signal" + "syscall" + "time" + + "go.uber.org/zap" + + ethAbi "github.com/certusone/wormhole/node/pkg/watchers/evm/connectors/ethabi" + ethBind "github.com/ethereum/go-ethereum/accounts/abi/bind" + ethCommon "github.com/ethereum/go-ethereum/common" + ethTypes "github.com/ethereum/go-ethereum/core/types" + ethClient "github.com/ethereum/go-ethereum/ethclient" + ethRpc "github.com/ethereum/go-ethereum/rpc" +) + +var ( + rpc = flag.String("rpc", "", "Websocket URL, this parameter is required") + contract = flag.String("contract", "", "Core contract address, leave blank to not subscribe to the core contract") + blocks = flag.Bool("blocks", false, "Also subscribe to new blocks, default is false") +) + +func main() { + flag.Parse() + logger, _ := zap.NewDevelopment() + if *rpc == "" { + logger.Fatal(`The "--rpc" parameter is required`) + } + if *contract == "" && !*blocks { + logger.Fatal(`Must specify either "--contract" or "--blocks" or both`) + } + + logger.Info("Connecting to websocket endpoint", zap.String("webSocket", *rpc)) + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + rawClient, err := ethRpc.DialContext(ctx, *rpc) + if err != nil { + logger.Fatal("Failed to connect to RPC", zap.Error(err)) + } + + client := ethClient.NewClient(rawClient) + + errC := make(chan error) + + if *blocks { + logger.Info("Subscribing for latest blocks") + headSink := make(chan *ethTypes.Header, 2) + headerSubscription, err := client.SubscribeNewHead(ctx, headSink) + if err != nil { + logger.Fatal("Failed to subscribe to latest blocks", zap.Error(err)) + } + + go func() { + logger.Info("Waiting for latest block events") + defer headerSubscription.Unsubscribe() + for { + select { + case <-ctx.Done(): + return + case err := <-headerSubscription.Err(): + errC <- fmt.Errorf("block subscription failed: %w", err) + return + case block := <-headSink: + // These two pointers should have been checked before the event was placed on the channel, but just being safe. + if block == nil { + logger.Error("New header event is nil") + continue + } + logger.Info("Received a new block", zap.Any("block", block)) + } + } + }() + } + + if *contract != "" { + logger.Info("Subscribing to log events from contract", zap.String("contractAddr", *contract)) + filterer, err := ethAbi.NewAbiFilterer(ethCommon.BytesToAddress(ethCommon.HexToAddress(*contract).Bytes()), client) + if err != nil { + logger.Fatal("Failed to create filter", zap.Error(err)) + } + + timeout, cancel := context.WithTimeout(ctx, 15*time.Second) + defer cancel() + messageC := make(chan *ethAbi.AbiLogMessagePublished, 2) + messageSub, err := filterer.WatchLogMessagePublished(ðBind.WatchOpts{Context: timeout}, messageC, nil) + if err != nil { + logger.Fatal("Failed to subscribe to events", zap.Error(err)) + } + defer messageSub.Unsubscribe() + + logger.Info("Waiting for log events from contract") + go func() { + for { + select { + case <-ctx.Done(): + return + case err := <-messageSub.Err(): + errC <- fmt.Errorf("message subscription failed: %w", err) + return + case ev := <-messageC: + logger.Info("Received a log event from the contract", zap.Any("ev", ev)) + } + } + }() + } + + // Wait for SIGTERM. + logger.Info("Waiting for sigterm.") + sigterm := make(chan os.Signal, 1) + signal.Notify(sigterm, syscall.SIGTERM) + go func() { + <-sigterm + logger.Info("Received sigterm. exiting.") + cancel() + }() + + // Wait for either a shutdown or a fatal error from the permissions watcher. + select { + case <-ctx.Done(): + logger.Info("Context cancelled, exiting...") + break + case err := <-errC: + logger.Error("Encountered an error, exiting", zap.Error(err)) + break + } + +} diff --git a/node/hack/governor/src/index.ts b/node/hack/governor/src/index.ts index 3ce80de907..846b7d66d1 100644 --- a/node/hack/governor/src/index.ts +++ b/node/hack/governor/src/index.ts @@ -35,7 +35,17 @@ const expectedUSDDepeggs = [ "3-0100000000000000000000000000000000000000000000000000000075757364-UST", // Terra USD "2-000000000000000000000000dfdb7f72c1f195c5951a234e8db9806eb0635346-NFD", // Feisty Doge NFT "2-00000000000000000000000000c5ca160a968f47e7272a0cfcda36428f386cb6-USDEBT", // US Debt Meme coin - "4-00000000000000000000000011a38e06699b238d6d9a0c7a01f3ac63a07ad318-USDFI", // USDFI is a protocol, not a stablecoin + "4-00000000000000000000000011a38e06699b238d6d9a0c7a01f3ac63a07ad318-USDFI", // USDFI is a protocol, not a stablecoin, + "2-000000000000000000000000309627af60f0926daa6041b8279484312f2bf060-USDB", // USDB (USD Bancor) has been deactivated + "2-000000000000000000000000df574c24545e5ffecb9a659c229253d4111d87e1-HUSD", // HUSD has been depegged for a number of years now + "4-00000000000000000000000023e8a70534308a4aaf76fb8c32ec13d17a3bd89e-lUSD", // Previously exploited version of Linear Finance LUSD + "4-000000000000000000000000de7d1ce109236b12809c45b23d22f30dba0ef424-USDS", // Dead token called Spice USD + "11-0000000000000000000000000000000000000000000100000000000000000081-aUSD", // Acala USD being converted to aSEED, dead token + "12-0000000000000000000000000000000000000000000100000000000000000001-aUSD", // Same as above + "13-0000000000000000000000005c74070fdea071359b86082bd9f9b3deaafbe32b-KDAI", // Klatyn DAI Depegged since December 2023 + "13-000000000000000000000000754288077d0ff82af7a5317c7cb8c444d421d103-oUSDC", // Orbit bridge Klatyn USDC, depegged since December 2023 + "13-000000000000000000000000cee8faf64bb97a73bb51e115aa89c17ffa8dd167-oUSDT", // Orbit bridge Klatyn USDT, depegged since December 2023 + "16-000000000000000000000000ffffffff52c56a9257bb97f4b2b6f7b2d624ecda-xcaUSD", // Acala USD being converted to aSEED, dead token ] const axios = require("axios"); diff --git a/node/hack/parse_eth_tx/parse_eth_tx.go b/node/hack/parse_eth_tx/parse_eth_tx.go index 13e91f63a7..5f6fb0d9e1 100644 --- a/node/hack/parse_eth_tx/parse_eth_tx.go +++ b/node/hack/parse_eth_tx/parse_eth_tx.go @@ -1,5 +1,5 @@ // To compile: -// go build --ldflags '-extldflags "-Wl,--allow-multiple-definition"' -o parse_eth_tx +// go build -o parse_eth_tx // Usage: // ./parse_eth_tx -chainID=14 -ethRPC=wss://alfajores-forno.celo-testnet.org/ws -contractAddr=0x88505117CA88e7dd2eC6EA1E13f0948db2D50D56 -tx=0x20a1e7e491dd82b6b33db0820e88a96b58bac28d65770ea73af80e457745aab1 @@ -39,16 +39,9 @@ func main() { var ethIntf connectors.Connector var err error - if chainID == vaa.ChainIDCelo { - ethIntf, err = connectors.NewCeloConnector(ctx, "", *flagEthRPC, contractAddr, zap.L()) - if err != nil { - log.Fatalf("dialing eth client failed: %v", err) - } - } else { - ethIntf, err = connectors.NewEthereumBaseConnector(ctx, "", *flagEthRPC, contractAddr, zap.L()) - if err != nil { - log.Fatalf("dialing eth client failed: %v", err) - } + ethIntf, err = connectors.NewEthereumBaseConnector(ctx, "", *flagEthRPC, contractAddr, zap.L()) + if err != nil { + log.Fatalf("dialing eth client failed: %v", err) } transactionHash := ethCommon.HexToHash(*flagTx) diff --git a/node/hack/query/ccqlistener/Dockerfile b/node/hack/query/ccqlistener/Dockerfile index 0dfb3b36ef..51cb3988b8 100644 --- a/node/hack/query/ccqlistener/Dockerfile +++ b/node/hack/query/ccqlistener/Dockerfile @@ -18,7 +18,7 @@ ARG GO_BUILD_ARGS=-race RUN --mount=type=cache,target=/root/.cache --mount=type=cache,target=/go \ export CGO_ENABLED=1 && \ cd node/hack/query/ccqlistener && \ - go build ${GO_BUILD_ARGS} -gcflags="all=-N -l" --ldflags '-extldflags "-Wl,--allow-multiple-definition" -X "github.com/certusone/wormhole/node/cmd/guardiand.Build=dev"' -mod=readonly -o /ccqlistener ccqlistener.go && \ + go build ${GO_BUILD_ARGS} -gcflags="all=-N -l" --ldflags '-X "github.com/certusone/wormhole/node/cmd/guardiand.Build=dev"' -mod=readonly -o /ccqlistener ccqlistener.go && \ go get github.com/CosmWasm/wasmvm@v1.1.1 && \ cp /go/pkg/mod/github.com/!cosm!wasm/wasmvm@v1.1.1/internal/api/libwasmvm.x86_64.so /usr/lib/ diff --git a/node/hack/repair_terra/repair.go b/node/hack/repair_terra/repair.go index 224a596ad4..b9aa260bed 100644 --- a/node/hack/repair_terra/repair.go +++ b/node/hack/repair_terra/repair.go @@ -237,7 +237,7 @@ func EventsToMessagePublications(contract string, txHash string, events []gjson. continue } messagePublication := &common.MessagePublication{ - TxHash: txHashValue, + TxID: txHashValue.Bytes(), Timestamp: time.Unix(blockTimeInt, 0), Nonce: uint32(nonceInt), Sequence: sequenceInt, diff --git a/node/pkg/accountant/accountant_test.go b/node/pkg/accountant/accountant_test.go index aae4d50b71..265cf89747 100644 --- a/node/pkg/accountant/accountant_test.go +++ b/node/pkg/accountant/accountant_test.go @@ -137,13 +137,13 @@ func newAccountantForTest( return acct } -// Converts a string into a go-ethereum Hash object used as test input. -func hashFromString(str string) ethCommon.Hash { //nolint:unparam +// Converts a TxHash string into a byte array to be used as a TxID. +func hashToTxID(str string) []byte { if (len(str) > 2) && (str[0] == '0') && (str[1] == 'x') { str = str[2:] } - return ethCommon.HexToHash(str) + return ethCommon.HexToHash(str).Bytes() } // Note this method assumes 18 decimals for the amount. @@ -188,7 +188,7 @@ func TestVaaFromUninterestingEmitter(t *testing.T) { var payload = []byte{1, 97, 97, 97, 97, 97} msg := common.MessagePublication{ - TxHash: hashFromString("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063"), + TxID: hashToTxID("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4064"), Timestamp: time.Unix(int64(1654543099), 0), Nonce: uint32(1), Sequence: uint64(1), @@ -216,7 +216,7 @@ func TestVaaForUninterestingPayloadType(t *testing.T) { var payload = []byte{2, 97, 97, 97, 97, 97} msg := common.MessagePublication{ - TxHash: hashFromString("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063"), + TxID: hashToTxID("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063"), Timestamp: time.Unix(int64(1654543099), 0), Nonce: uint32(1), Sequence: uint64(1), @@ -251,7 +251,7 @@ func TestInterestingTransferShouldNotBeBlockedWhenNotEnforcingAccountant(t *test ) msg := common.MessagePublication{ - TxHash: hashFromString("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063"), + TxID: hashToTxID("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063"), Timestamp: time.Unix(int64(1654543099), 0), Nonce: uint32(1), Sequence: uint64(1), @@ -295,7 +295,7 @@ func TestInterestingTransferShouldBeBlockedWhenEnforcingAccountant(t *testing.T) ) msg := common.MessagePublication{ - TxHash: hashFromString("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063"), + TxID: hashToTxID("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063"), Timestamp: time.Unix(int64(1654543099), 0), Nonce: uint32(1), Sequence: uint64(1), @@ -347,7 +347,7 @@ func TestForDeadlock(t *testing.T) { ) msg := common.MessagePublication{ - TxHash: hashFromString("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063"), + TxID: hashToTxID("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063"), Timestamp: time.Unix(int64(1654543099), 0), Nonce: uint32(1), Sequence: uint64(1683136244), @@ -374,7 +374,7 @@ func TestForDeadlock(t *testing.T) { assert.Equal(t, 1, len(acct.msgChan)) msg2 := common.MessagePublication{ - TxHash: hashFromString("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063"), + TxID: hashToTxID("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063"), Timestamp: time.Unix(int64(1654543099), 0), Nonce: uint32(1), Sequence: uint64(1683136244), diff --git a/node/pkg/accountant/audit.go b/node/pkg/accountant/audit.go index ea8c6c6f98..a179764230 100644 --- a/node/pkg/accountant/audit.go +++ b/node/pkg/accountant/audit.go @@ -108,7 +108,7 @@ func (mo *MissingObservation) makeAuditKey() string { // makeAuditKey creates an audit map key from a pending observation entry. func (pe *pendingEntry) makeAuditKey() string { - return fmt.Sprintf("%d-%s", pe.msg.EmitterChain, strings.TrimPrefix(pe.msg.TxHash.String(), "0x")) + return fmt.Sprintf("%d-%s", pe.msg.EmitterChain, strings.TrimPrefix(pe.msg.TxIDString(), "0x")) } // audit is the runnable that executes the audit each interval. diff --git a/node/pkg/accountant/ntt_test.go b/node/pkg/accountant/ntt_test.go index eeafab8278..8fd78db451 100644 --- a/node/pkg/accountant/ntt_test.go +++ b/node/pkg/accountant/ntt_test.go @@ -50,7 +50,7 @@ func TestNttParseMsgSuccess(t *testing.T) { } msg := &common.MessagePublication{ - TxHash: hashFromString("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063"), + TxID: hashToTxID("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063"), Timestamp: time.Unix(int64(1654543099), 0), Nonce: uint32(42), Sequence: uint64(123456), @@ -77,7 +77,7 @@ func TestNttParseMsgWrongEmitterChain(t *testing.T) { } msg := &common.MessagePublication{ - TxHash: hashFromString("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063"), + TxID: hashToTxID("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063"), Timestamp: time.Unix(int64(1654543099), 0), Nonce: uint32(42), Sequence: uint64(123456), @@ -106,7 +106,7 @@ func TestNttParseMsgWrongEmitterAddress(t *testing.T) { } msg := &common.MessagePublication{ - TxHash: hashFromString("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063"), + TxID: hashToTxID("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063"), Timestamp: time.Unix(int64(1654543099), 0), Nonce: uint32(42), Sequence: uint64(123456), @@ -221,7 +221,7 @@ func TestNttParseArMsgSuccess(t *testing.T) { require.NoError(t, err) msg := &common.MessagePublication{ - TxHash: hashFromString("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063"), + TxID: hashToTxID("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063"), Timestamp: time.Unix(int64(1708575745), 0), Nonce: uint32(0), Sequence: uint64(259), @@ -258,7 +258,7 @@ func TestNttParseArMsgUnknownArEmitter(t *testing.T) { require.NoError(t, err) msg := &common.MessagePublication{ - TxHash: hashFromString("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063"), + TxID: hashToTxID("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063"), Timestamp: time.Unix(int64(1708575745), 0), Nonce: uint32(0), Sequence: uint64(259), diff --git a/node/pkg/accountant/submit_obs.go b/node/pkg/accountant/submit_obs.go index 513e14a210..622a5b904a 100644 --- a/node/pkg/accountant/submit_obs.go +++ b/node/pkg/accountant/submit_obs.go @@ -308,7 +308,7 @@ func SubmitObservationsToContract( obs := make([]Observation, len(msgs)) for idx, msg := range msgs { obs[idx] = Observation{ - TxHash: msg.TxHash.Bytes(), + TxHash: msg.TxID, Timestamp: uint32(msg.Timestamp.Unix()), Nonce: msg.Nonce, EmitterChain: uint16(msg.EmitterChain), @@ -321,7 +321,7 @@ func SubmitObservationsToContract( logger.Debug("in SubmitObservationsToContract, encoding observation", zap.String("contract", contract), zap.Int("idx", idx), - zap.String("txHash", msg.TxHash.String()), zap.String("encTxHash", hex.EncodeToString(obs[idx].TxHash[:])), + zap.String("txHash", msg.TxIDString()), zap.String("encTxHash", hex.EncodeToString(obs[idx].TxHash[:])), zap.Stringer("timeStamp", msg.Timestamp), zap.Uint32("encTimestamp", obs[idx].Timestamp), zap.Uint32("nonce", msg.Nonce), zap.Uint32("encNonce", obs[idx].Nonce), zap.Stringer("emitterChain", msg.EmitterChain), zap.Uint16("encEmitterChain", obs[idx].EmitterChain), diff --git a/node/pkg/accountant/watcher.go b/node/pkg/accountant/watcher.go index 52ccaf37ce..deace9deff 100644 --- a/node/pkg/accountant/watcher.go +++ b/node/pkg/accountant/watcher.go @@ -11,8 +11,6 @@ import ( "github.com/certusone/wormhole/node/pkg/common" "github.com/wormhole-foundation/wormhole/sdk/vaa" - ethCommon "github.com/ethereum/go-ethereum/common" - tmAbci "github.com/tendermint/tendermint/abci/types" tmHttp "github.com/tendermint/tendermint/rpc/client/http" tmCoreTypes "github.com/tendermint/tendermint/rpc/core/types" @@ -181,7 +179,7 @@ func (acct *Accountant) processPendingTransfer(xfer *WasmObservation, tag string ) msg := &common.MessagePublication{ - TxHash: ethCommon.BytesToHash(xfer.TxHash), + TxID: xfer.TxHash, Timestamp: time.Unix(int64(xfer.Timestamp), 0), Nonce: xfer.Nonce, Sequence: xfer.Sequence, diff --git a/node/pkg/adminrpc/adminserver.go b/node/pkg/adminrpc/adminserver.go index 2f345b9807..6f08776738 100644 --- a/node/pkg/adminrpc/adminserver.go +++ b/node/pkg/adminrpc/adminserver.go @@ -798,7 +798,7 @@ func (s *nodePrivilegedService) InjectGovernanceVAA(ctx context.Context, req *no vaaInjectionsTotal.Inc() s.injectC <- &common.MessagePublication{ - TxHash: ethcommon.Hash{}, + TxID: ethcommon.Hash{}.Bytes(), Timestamp: v.Timestamp, Nonce: v.Nonce, Sequence: v.Sequence, diff --git a/node/pkg/common/chainlock.go b/node/pkg/common/chainlock.go index 052d1bbd5b..54b0749189 100644 --- a/node/pkg/common/chainlock.go +++ b/node/pkg/common/chainlock.go @@ -7,19 +7,19 @@ import ( "encoding/json" "errors" "fmt" + "math" "time" + "github.com/ethereum/go-ethereum/common" "github.com/wormhole-foundation/wormhole/sdk/vaa" "go.uber.org/zap" - - "github.com/ethereum/go-ethereum/common" ) const HashLength = 32 const AddressLength = 32 type MessagePublication struct { - TxHash common.Hash // TODO: rename to identifier? on Solana, this isn't actually the tx hash + TxID []byte Timestamp time.Time Nonce uint32 @@ -35,6 +35,10 @@ type MessagePublication struct { Unreliable bool } +func (msg *MessagePublication) TxIDString() string { + return "0x" + hex.EncodeToString(msg.TxID) +} + func (msg *MessagePublication) MessageID() []byte { return []byte(msg.MessageIDString()) } @@ -48,7 +52,12 @@ const minMsgLength = 88 // Marshalled length with empty payload func (msg *MessagePublication) Marshal() ([]byte, error) { buf := new(bytes.Buffer) - buf.Write(msg.TxHash[:]) + if len(msg.TxID) > math.MaxUint8 { + return nil, errors.New("TxID too long") + } + vaa.MustWrite(buf, binary.BigEndian, uint8(len(msg.TxID))) + buf.Write(msg.TxID) + vaa.MustWrite(buf, binary.BigEndian, uint32(msg.Timestamp.Unix())) vaa.MustWrite(buf, binary.BigEndian, msg.Nonce) vaa.MustWrite(buf, binary.BigEndian, msg.Sequence) @@ -61,12 +70,10 @@ func (msg *MessagePublication) Marshal() ([]byte, error) { return buf.Bytes(), nil } -const oldMinMsgLength = 83 // Old marshalled length with empty payload - -// UnmarshalOldMessagePublicationBeforeIsReobservation deserializes a MessagePublication from prior to the addition of IsReobservation. +// UnmarshalOldMessagePublicationWithTxHash deserializes a MessagePublication from when the TxHash was a fixed size ethCommon.Hash. // This function can be deleted once all guardians have been upgraded. That's why the code is just duplicated. -func UnmarshalOldMessagePublicationBeforeIsReobservation(data []byte) (*MessagePublication, error) { - if len(data) < oldMinMsgLength { +func UnmarshalOldMessagePublicationWithTxHash(data []byte) (*MessagePublication, error) { + if len(data) < minMsgLength { return nil, errors.New("message is too short") } @@ -78,7 +85,7 @@ func UnmarshalOldMessagePublicationBeforeIsReobservation(data []byte) (*MessageP if n, err := reader.Read(txHash[:]); err != nil || n != HashLength { return nil, fmt.Errorf("failed to read TxHash [%d]: %w", n, err) } - msg.TxHash = txHash + msg.TxID = txHash.Bytes() unixSeconds := uint32(0) if err := binary.Read(reader, binary.BigEndian, &unixSeconds); err != nil { @@ -108,6 +115,10 @@ func UnmarshalOldMessagePublicationBeforeIsReobservation(data []byte) (*MessageP } msg.EmitterAddress = emitterAddress + if err := binary.Read(reader, binary.BigEndian, &msg.IsReobservation); err != nil { + return nil, fmt.Errorf("failed to read isReobservation: %w", err) + } + payload := make([]byte, reader.Len()) n, err := reader.Read(payload) if err != nil || n == 0 { @@ -121,18 +132,22 @@ func UnmarshalOldMessagePublicationBeforeIsReobservation(data []byte) (*MessageP // UnmarshalMessagePublication deserializes a MessagePublication func UnmarshalMessagePublication(data []byte) (*MessagePublication, error) { if len(data) < minMsgLength { - return nil, fmt.Errorf("message is too short") + return nil, errors.New("message is too short") } msg := &MessagePublication{} reader := bytes.NewReader(data[:]) - txHash := common.Hash{} - if n, err := reader.Read(txHash[:]); err != nil || n != HashLength { - return nil, fmt.Errorf("failed to read TxHash [%d]: %w", n, err) + txIdLen := uint8(0) + if err := binary.Read(reader, binary.BigEndian, &txIdLen); err != nil { + return nil, fmt.Errorf("failed to read TxID len: %w", err) + } + + msg.TxID = make([]byte, txIdLen) + if n, err := reader.Read(msg.TxID[:]); err != nil || n != int(txIdLen) { + return nil, fmt.Errorf("failed to read TxID [%d]: %w", n, err) } - msg.TxHash = txHash unixSeconds := uint32(0) if err := binary.Read(reader, binary.BigEndian, &unixSeconds); err != nil { @@ -229,7 +244,7 @@ func (msg *MessagePublication) CreateDigest() string { // TODO refactor the codebase to use this function instead of manually logging the message with inconsistent fields func (msg *MessagePublication) ZapFields(fields ...zap.Field) []zap.Field { return append(fields, - zap.Stringer("tx", msg.TxHash), + zap.String("tx", msg.TxIDString()), zap.Time("timestamp", msg.Timestamp), zap.Uint32("nonce", msg.Nonce), zap.Uint8("consistency", msg.ConsistencyLevel), diff --git a/node/pkg/common/chainlock_test.go b/node/pkg/common/chainlock_test.go index 2ec27793f4..add2a03a03 100644 --- a/node/pkg/common/chainlock_test.go +++ b/node/pkg/common/chainlock_test.go @@ -51,7 +51,7 @@ func TestSerializeAndDeserializeOfMessagePublication(t *testing.T) { payloadBytes1 := encodePayloadBytes(payload1) msg1 := &MessagePublication{ - TxHash: eth_common.HexToHash("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063"), + TxID: eth_common.HexToHash("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063").Bytes(), Timestamp: time.Unix(int64(1654516425), 0), Nonce: 123456, Sequence: 789101112131415, @@ -74,6 +74,118 @@ func TestSerializeAndDeserializeOfMessagePublication(t *testing.T) { assert.Equal(t, payload1, payload2) } +func TestSerializeAndDeserializeOfMessagePublicationWithEmptyTxID(t *testing.T) { + originAddress, err := vaa.StringToAddress("0xDDb64fE46a91D46ee29420539FC25FD07c5FEa3E") //nolint:gosec + require.NoError(t, err) + + targetAddress, err := vaa.StringToAddress("0x707f9118e33a9b8998bea41dd0d46f38bb963fc8") + require.NoError(t, err) + + tokenBridgeAddress, err := vaa.StringToAddress("0x707f9118e33a9b8998bea41dd0d46f38bb963fc8") + require.NoError(t, err) + + payload1 := &vaa.TransferPayloadHdr{ + Type: 0x01, + Amount: big.NewInt(27000000000), + OriginAddress: originAddress, + OriginChain: vaa.ChainIDEthereum, + TargetAddress: targetAddress, + TargetChain: vaa.ChainIDPolygon, + } + + payloadBytes1 := encodePayloadBytes(payload1) + + msg1 := &MessagePublication{ + TxID: []byte{}, + Timestamp: time.Unix(int64(1654516425), 0), + Nonce: 123456, + Sequence: 789101112131415, + EmitterChain: vaa.ChainIDEthereum, + EmitterAddress: tokenBridgeAddress, + Payload: payloadBytes1, + ConsistencyLevel: 32, + } + + bytes, err := msg1.Marshal() + require.NoError(t, err) + + msg2, err := UnmarshalMessagePublication(bytes) + require.NoError(t, err) + assert.Equal(t, msg1, msg2) + + payload2, err := vaa.DecodeTransferPayloadHdr(msg2.Payload) + require.NoError(t, err) + + assert.Equal(t, payload1, payload2) +} + +func TestSerializeAndDeserializeOfMessagePublicationWithArbitraryTxID(t *testing.T) { + originAddress, err := vaa.StringToAddress("0xDDb64fE46a91D46ee29420539FC25FD07c5FEa3E") //nolint:gosec + require.NoError(t, err) + + targetAddress, err := vaa.StringToAddress("0x707f9118e33a9b8998bea41dd0d46f38bb963fc8") + require.NoError(t, err) + + tokenBridgeAddress, err := vaa.StringToAddress("0x707f9118e33a9b8998bea41dd0d46f38bb963fc8") + require.NoError(t, err) + + payload1 := &vaa.TransferPayloadHdr{ + Type: 0x01, + Amount: big.NewInt(27000000000), + OriginAddress: originAddress, + OriginChain: vaa.ChainIDEthereum, + TargetAddress: targetAddress, + TargetChain: vaa.ChainIDPolygon, + } + + payloadBytes1 := encodePayloadBytes(payload1) + + msg1 := &MessagePublication{ + TxID: []byte("This is some arbitrary string with just some random junk in it. This is to prove that the TxID does not have to be a ethCommon.Hash"), + Timestamp: time.Unix(int64(1654516425), 0), + Nonce: 123456, + Sequence: 789101112131415, + EmitterChain: vaa.ChainIDEthereum, + EmitterAddress: tokenBridgeAddress, + Payload: payloadBytes1, + ConsistencyLevel: 32, + } + + bytes, err := msg1.Marshal() + require.NoError(t, err) + + msg2, err := UnmarshalMessagePublication(bytes) + require.NoError(t, err) + assert.Equal(t, msg1, msg2) + + payload2, err := vaa.DecodeTransferPayloadHdr(msg2.Payload) + require.NoError(t, err) + + assert.Equal(t, payload1, payload2) +} + +func TestTxIDStringTooLongShouldFail(t *testing.T) { + tokenBridgeAddress, err := vaa.StringToAddress("0x707f9118e33a9b8998bea41dd0d46f38bb963fc8") + require.NoError(t, err) + + // This is limited to 255. Make it 256 and the marshal should fail. + txID := []byte("0123456789012345678901234567890123456789012345678901234567890123012345678901234567890123456789012345678901234567890123456789012301234567890123456789012345678901234567890123456789012345678901230123456789012345678901234567890123456789012345678901234567890123") + + msg := &MessagePublication{ + TxID: txID, + Timestamp: time.Unix(int64(1654516425), 0), + Nonce: 123456, + Sequence: 789101112131415, + EmitterChain: vaa.ChainIDEthereum, + EmitterAddress: tokenBridgeAddress, + Payload: []byte("Hello, World!"), + ConsistencyLevel: 32, + } + + _, err = msg.Marshal() + assert.ErrorContains(t, err, "TxID too long") +} + func TestSerializeAndDeserializeOfMessagePublicationWithBigPayload(t *testing.T) { tokenBridgeAddress, err := vaa.StringToAddress("0x707f9118e33a9b8998bea41dd0d46f38bb963fc8") require.NoError(t, err) @@ -86,7 +198,7 @@ func TestSerializeAndDeserializeOfMessagePublicationWithBigPayload(t *testing.T) } msg1 := &MessagePublication{ - TxHash: eth_common.HexToHash("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063"), + TxID: eth_common.HexToHash("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063").Bytes(), Timestamp: time.Unix(int64(1654516425), 0), Nonce: 123456, Sequence: 789101112131415, @@ -127,7 +239,53 @@ func TestMarshalUnmarshalJSONOfMessagePublication(t *testing.T) { payloadBytes1 := encodePayloadBytes(payload1) msg1 := &MessagePublication{ - TxHash: eth_common.HexToHash("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063"), + TxID: eth_common.HexToHash("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063").Bytes(), + Timestamp: time.Unix(int64(1654516425), 0), + Nonce: 123456, + Sequence: 789101112131415, + EmitterChain: vaa.ChainIDEthereum, + EmitterAddress: tokenBridgeAddress, + Payload: payloadBytes1, + ConsistencyLevel: 32, + } + + bytes, err := msg1.MarshalJSON() + require.NoError(t, err) + + var msg2 MessagePublication + err = msg2.UnmarshalJSON(bytes) + require.NoError(t, err) + assert.Equal(t, *msg1, msg2) + + payload2, err := vaa.DecodeTransferPayloadHdr(msg2.Payload) + require.NoError(t, err) + + assert.Equal(t, *payload1, *payload2) +} + +func TestMarshalUnmarshalJSONOfMessagePublicationWithArbitraryTxID(t *testing.T) { + originAddress, err := vaa.StringToAddress("0xDDb64fE46a91D46ee29420539FC25FD07c5FEa3E") //nolint:gosec + require.NoError(t, err) + + targetAddress, err := vaa.StringToAddress("0x707f9118e33a9b8998bea41dd0d46f38bb963fc8") + require.NoError(t, err) + + tokenBridgeAddress, err := vaa.StringToAddress("0x707f9118e33a9b8998bea41dd0d46f38bb963fc8") + require.NoError(t, err) + + payload1 := &vaa.TransferPayloadHdr{ + Type: 0x01, + Amount: big.NewInt(27000000000), + OriginAddress: originAddress, + OriginChain: vaa.ChainIDEthereum, + TargetAddress: targetAddress, + TargetChain: vaa.ChainIDPolygon, + } + + payloadBytes1 := encodePayloadBytes(payload1) + + msg1 := &MessagePublication{ + TxID: []byte("This is some arbitrary string with just some random junk in it. This is to prove that the TxID does not have to be a ethCommon.Hash"), Timestamp: time.Unix(int64(1654516425), 0), Nonce: 123456, Sequence: 789101112131415, @@ -220,3 +378,23 @@ func TestMessageID(t *testing.T) { }) } } + +func TestTxIDStringMatchesHashToString(t *testing.T) { + tokenBridgeAddress, err := vaa.StringToAddress("0x707f9118e33a9b8998bea41dd0d46f38bb963fc8") + require.NoError(t, err) + + expectedHashID := "0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063" + + msg := &MessagePublication{ + TxID: eth_common.HexToHash(expectedHashID).Bytes(), + Timestamp: time.Unix(int64(1654516425), 0), + Nonce: 123456, + Sequence: 789101112131415, + EmitterChain: vaa.ChainIDEthereum, + EmitterAddress: tokenBridgeAddress, + Payload: []byte("Hello, World!"), + ConsistencyLevel: 32, + } + + assert.Equal(t, expectedHashID, msg.TxIDString()) +} diff --git a/node/pkg/db/accountant.go b/node/pkg/db/accountant.go index 2883ec4d59..3e2877fdaa 100644 --- a/node/pkg/db/accountant.go +++ b/node/pkg/db/accountant.go @@ -3,10 +3,13 @@ package db import ( "encoding/json" "fmt" + "time" "github.com/certusone/wormhole/node/pkg/common" "github.com/dgraph-io/badger/v3" + "github.com/wormhole-foundation/wormhole/sdk/vaa" + ethCommon "github.com/ethereum/go-ethereum/common" "go.uber.org/zap" ) @@ -31,10 +34,10 @@ func (d *MockAccountantDB) AcctGetData(logger *zap.Logger) ([]*common.MessagePub return nil, nil } -const acctOldPendingTransfer = "ACCT:PXFER:" +const acctOldPendingTransfer = "ACCT:PXFER2:" const acctOldPendingTransferLen = len(acctOldPendingTransfer) -const acctPendingTransfer = "ACCT:PXFER2:" +const acctPendingTransfer = "ACCT:PXFER3:" const acctPendingTransferLen = len(acctPendingTransfer) const acctMinMsgIdLen = len("1/0000000000000000000000000290fb167208af455bb137780163b7b7a9a10c16/0") @@ -59,6 +62,11 @@ func acctIsPendingTransfer(keyBytes []byte) bool { func (d *Database) AcctGetData(logger *zap.Logger) ([]*common.MessagePublication, error) { pendingTransfers := []*common.MessagePublication{} var err error + + if err = d.convertOldTransfersToNewFormat(logger); err != nil { + return pendingTransfers, fmt.Errorf("failed to convert old pending transfers to the new format: %w", err) + } + { prefixBytes := []byte(acctPendingTransfer) err = d.db.View(func(txn *badger.Txn) error { @@ -84,7 +92,7 @@ func (d *Database) AcctGetData(logger *zap.Logger) ([]*common.MessagePublication pendingTransfers = append(pendingTransfers, &pt) } else { - return fmt.Errorf("unexpected accountant pending transfer key '%s'", string(key)) + return fmt.Errorf("failed to load accountant pending transfer, unexpected key '%s'", string(key)) } } @@ -92,53 +100,6 @@ func (d *Database) AcctGetData(logger *zap.Logger) ([]*common.MessagePublication }) } - // Any pending transfers in the old format are long since obsolete. Just delete them. - if err == nil { - oldPendingTransfers := []string{} - prefixBytes := []byte(acctOldPendingTransfer) - err = d.db.View(func(txn *badger.Txn) error { - opts := badger.DefaultIteratorOptions - opts.PrefetchSize = 10 - it := txn.NewIterator(opts) - defer it.Close() - for it.Seek(prefixBytes); it.ValidForPrefix(prefixBytes); it.Next() { - item := it.Item() - key := item.Key() - val, err := item.ValueCopy(nil) - if err != nil { - return err - } - - if acctIsOldPendingTransfer(key) { - pt, err := common.UnmarshalOldMessagePublicationBeforeIsReobservation(val) - if err != nil { - logger.Error("failed to unmarshal old pending transfer for key", zap.String("key", string(key[:])), zap.Error(err)) - continue - } - - oldPendingTransfers = append(oldPendingTransfers, pt.MessageIDString()) - } else { - return fmt.Errorf("unexpected accountant pending transfer key '%s'", string(key)) - } - } - - return nil - }) - - if err == nil && len(oldPendingTransfers) != 0 { - for _, pt := range oldPendingTransfers { - key := acctOldPendingTransferMsgID(pt) - logger.Info("deleting obsolete pending transfer", zap.String("msgId", pt), zap.String("key", string(key))) - if err := d.db.Update(func(txn *badger.Txn) error { - err := txn.Delete(key) - return err - }); err != nil { - return pendingTransfers, fmt.Errorf("failed to delete old pending msg for key [%v]: %w", pt, err) - } - } - } - } - return pendingTransfers, err } @@ -170,3 +131,113 @@ func (d *Database) AcctDeletePendingTransfer(msgId string) error { return nil } + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// The code below here is used to read and convert old Pending transfers. Once the db has been migrated away from those, this can be deleted. +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +// OldMessagePublication is used to unmarshal old JSON which has the TxHash rather than the TxID. +type OldMessagePublication struct { + TxHash ethCommon.Hash + Timestamp time.Time + + Nonce uint32 + Sequence uint64 + ConsistencyLevel uint8 + EmitterChain vaa.ChainID + EmitterAddress vaa.Address + Payload []byte + IsReobservation bool + Unreliable bool +} + +func (msg *OldMessagePublication) UnmarshalJSON(data []byte) error { + type Alias OldMessagePublication + aux := &struct { + Timestamp int64 + *Alias + }{ + Alias: (*Alias)(msg), + } + if err := json.Unmarshal(data, &aux); err != nil { + return err + } + msg.Timestamp = time.Unix(aux.Timestamp, 0) + return nil +} + +// convertOldToNew converts an OldMessagePublication to a MessagePublication. +func convertOldToNew(old *OldMessagePublication) *common.MessagePublication { + return &common.MessagePublication{ + TxID: old.TxHash.Bytes(), + Timestamp: old.Timestamp, + Nonce: old.Nonce, + Sequence: old.Sequence, + EmitterChain: old.EmitterChain, + EmitterAddress: old.EmitterAddress, + Payload: old.Payload, + ConsistencyLevel: old.ConsistencyLevel, + IsReobservation: old.IsReobservation, + Unreliable: old.Unreliable, + } +} + +// convertOldTransfersToNewFormat loads any pending transfers in the old format, writes them in the new format and deletes the old ones. +func (d *Database) convertOldTransfersToNewFormat(logger *zap.Logger) error { + pendingTransfers := []*common.MessagePublication{} + prefixBytes := []byte(acctOldPendingTransfer) + err := d.db.View(func(txn *badger.Txn) error { + opts := badger.DefaultIteratorOptions + opts.PrefetchSize = 10 + it := txn.NewIterator(opts) + defer it.Close() + for it.Seek(prefixBytes); it.ValidForPrefix(prefixBytes); it.Next() { + item := it.Item() + key := item.Key() + val, err := item.ValueCopy(nil) + if err != nil { + return err + } + + if acctIsOldPendingTransfer(key) { + var pt OldMessagePublication + err := json.Unmarshal(val, &pt) + if err != nil { + return fmt.Errorf("failed to unmarshal old pending transfer for key '%s': %w", string(key), err) + } + + pendingTransfers = append(pendingTransfers, convertOldToNew(&pt)) + } else { + return fmt.Errorf("failed to convert old accountant pending transfer, unexpected key '%s'", string(key)) + } + } + + return nil + }) + + if err != nil { + return err + } + + if len(pendingTransfers) != 0 { + for _, pt := range pendingTransfers { + logger.Info("converting old pending transfer to new format", zap.String("msgId", pt.MessageIDString())) + if err := d.AcctStorePendingTransfer(pt); err != nil { + return fmt.Errorf("failed to convert old pending transfer for key [%v]: %w", pt, err) + } + } + + for _, pt := range pendingTransfers { + key := acctOldPendingTransferMsgID(pt.MessageIDString()) + logger.Info("deleting old pending transfer", zap.String("msgId", pt.MessageIDString()), zap.String("key", string(key))) + if err := d.db.Update(func(txn *badger.Txn) error { + err := txn.Delete(key) + return err + }); err != nil { + return fmt.Errorf("failed to delete old pending transfer for key [%v]: %w", pt, err) + } + } + } + + return nil +} diff --git a/node/pkg/db/accountant_test.go b/node/pkg/db/accountant_test.go index c79728bc1b..9e5f387c06 100644 --- a/node/pkg/db/accountant_test.go +++ b/node/pkg/db/accountant_test.go @@ -1,9 +1,10 @@ package db import ( - "bytes" - "encoding/binary" + "encoding/json" + "fmt" "os" + "sort" "testing" "time" @@ -16,6 +17,9 @@ import ( "github.com/stretchr/testify/require" "go.uber.org/zap" + "go.uber.org/zap/zapcore" + "go.uber.org/zap/zaptest" + "go.uber.org/zap/zaptest/observer" ) func TestAcctPendingTransferMsgID(t *testing.T) { @@ -23,7 +27,7 @@ func TestAcctPendingTransferMsgID(t *testing.T) { require.NoError(t, err) msg1 := &common.MessagePublication{ - TxHash: eth_common.HexToHash("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063"), + TxID: eth_common.HexToHash("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063").Bytes(), Timestamp: time.Unix(int64(1654516425), 0), Nonce: 123456, Sequence: 789101112131415, @@ -33,22 +37,22 @@ func TestAcctPendingTransferMsgID(t *testing.T) { ConsistencyLevel: 16, } - assert.Equal(t, []byte("ACCT:PXFER:"+"2/0000000000000000000000000290fb167208af455bb137780163b7b7a9a10c16/789101112131415"), acctOldPendingTransferMsgID(msg1.MessageIDString())) - assert.Equal(t, []byte("ACCT:PXFER2:"+"2/0000000000000000000000000290fb167208af455bb137780163b7b7a9a10c16/789101112131415"), acctPendingTransferMsgID(msg1.MessageIDString())) + assert.Equal(t, []byte("ACCT:PXFER2:"+"2/0000000000000000000000000290fb167208af455bb137780163b7b7a9a10c16/789101112131415"), acctOldPendingTransferMsgID(msg1.MessageIDString())) + assert.Equal(t, []byte("ACCT:PXFER3:"+"2/0000000000000000000000000290fb167208af455bb137780163b7b7a9a10c16/789101112131415"), acctPendingTransferMsgID(msg1.MessageIDString())) } func TestAcctIsPendingTransfer(t *testing.T) { - assert.Equal(t, true, acctIsPendingTransfer([]byte("ACCT:PXFER2:"+"2/0000000000000000000000000290fb167208af455bb137780163b7b7a9a10c16/789101112131415"))) - assert.Equal(t, false, acctIsPendingTransfer([]byte("ACCT:PXFER2:"))) - assert.Equal(t, false, acctIsPendingTransfer([]byte("ACCT:PXFER2:1"))) - assert.Equal(t, false, acctIsPendingTransfer([]byte("ACCT:PXFER2:1/1/1"))) - assert.Equal(t, false, acctIsPendingTransfer([]byte("ACCT:PXFER2:"+"1/0000000000000000000000000290fb167208af455bb137780163b7b7a9a10c16/"))) - assert.Equal(t, true, acctIsPendingTransfer([]byte("ACCT:PXFER2:"+"1/0000000000000000000000000290fb167208af455bb137780163b7b7a9a10c16/0"))) + assert.Equal(t, true, acctIsPendingTransfer([]byte("ACCT:PXFER3:"+"2/0000000000000000000000000290fb167208af455bb137780163b7b7a9a10c16/789101112131415"))) + assert.Equal(t, false, acctIsPendingTransfer([]byte("ACCT:PXFER3:"))) + assert.Equal(t, false, acctIsPendingTransfer([]byte("ACCT:PXFER3:1"))) + assert.Equal(t, false, acctIsPendingTransfer([]byte("ACCT:PXFER3:1/1/1"))) + assert.Equal(t, false, acctIsPendingTransfer([]byte("ACCT:PXFER3:"+"1/0000000000000000000000000290fb167208af455bb137780163b7b7a9a10c16/"))) + assert.Equal(t, true, acctIsPendingTransfer([]byte("ACCT:PXFER3:"+"1/0000000000000000000000000290fb167208af455bb137780163b7b7a9a10c16/0"))) assert.Equal(t, false, acctIsPendingTransfer([]byte("GOV:PENDING:"+"2/0000000000000000000000000290fb167208af455bb137780163b7b7a9a10c16/789101112131415"))) assert.Equal(t, false, acctIsPendingTransfer([]byte{0x01, 0x02, 0x03, 0x04})) assert.Equal(t, false, acctIsPendingTransfer([]byte{})) - assert.Equal(t, true, acctIsOldPendingTransfer([]byte("ACCT:PXFER:"+"2/0000000000000000000000000290fb167208af455bb137780163b7b7a9a10c16/789101112131415"))) - assert.Equal(t, false, acctIsOldPendingTransfer([]byte("ACCT:PXFER2:"+"2/0000000000000000000000000290fb167208af455bb137780163b7b7a9a10c16/789101112131415"))) + assert.Equal(t, true, acctIsOldPendingTransfer([]byte("ACCT:PXFER2:"+"2/0000000000000000000000000290fb167208af455bb137780163b7b7a9a10c16/789101112131415"))) + assert.Equal(t, false, acctIsOldPendingTransfer([]byte("ACCT:PXFER3:"+"2/0000000000000000000000000290fb167208af455bb137780163b7b7a9a10c16/789101112131415"))) } func TestAcctStoreAndDeletePendingTransfers(t *testing.T) { @@ -60,7 +64,7 @@ func TestAcctStoreAndDeletePendingTransfers(t *testing.T) { require.NoError(t, err) msg1 := &common.MessagePublication{ - TxHash: eth_common.HexToHash("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063"), + TxID: eth_common.HexToHash("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063").Bytes(), Timestamp: time.Unix(int64(1654516425), 0), Nonce: 123456, Sequence: 789101112131415, @@ -71,7 +75,7 @@ func TestAcctStoreAndDeletePendingTransfers(t *testing.T) { } msg2 := &common.MessagePublication{ - TxHash: eth_common.HexToHash("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4064"), + TxID: eth_common.HexToHash("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4064").Bytes(), Timestamp: time.Unix(int64(1654516425), 0), Nonce: 123457, Sequence: 789101112131416, @@ -99,7 +103,7 @@ func TestAcctStoreAndDeletePendingTransfers(t *testing.T) { // Delete something that doesn't exist. msg3 := &common.MessagePublication{ - TxHash: eth_common.HexToHash("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4064"), + TxID: eth_common.HexToHash("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4064").Bytes(), Timestamp: time.Unix(int64(1654516425), 0), Nonce: 123457, Sequence: 789101112131417, @@ -146,7 +150,7 @@ func TestAcctGetData(t *testing.T) { require.NoError(t, err) msg1 := &common.MessagePublication{ - TxHash: eth_common.HexToHash("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063"), + TxID: eth_common.HexToHash("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063").Bytes(), Timestamp: time.Unix(int64(1654516425), 0), Nonce: 123456, Sequence: 789101112131415, @@ -157,7 +161,7 @@ func TestAcctGetData(t *testing.T) { } msg2 := &common.MessagePublication{ - TxHash: eth_common.HexToHash("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4064"), + TxID: eth_common.HexToHash("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4064").Bytes(), Timestamp: time.Unix(int64(1654516425), 0), Nonce: 123457, Sequence: 789101112131416, @@ -189,13 +193,13 @@ func TestAcctGetData(t *testing.T) { assert.Equal(t, *msg2, *pendings[1]) } -func TestAcctLoadingWhereOldPendingsGetDropped(t *testing.T) { +func TestAcctLoadingWhereOldPendingGetsUpdated(t *testing.T) { dbPath := t.TempDir() db := OpenDb(zap.NewNop(), &dbPath) defer db.Close() defer os.Remove(dbPath) - logger := zap.NewNop() + logger, zapObserver := setupLogsCapture(t) tokenBridgeAddr, err := vaa.StringToAddress("0x0290fb167208af455bb137780163b7b7a9a10c16") require.NoError(t, err) @@ -203,7 +207,7 @@ func TestAcctLoadingWhereOldPendingsGetDropped(t *testing.T) { now := time.Unix(time.Now().Unix(), 0) // Write the first pending event in the old format. - pending1 := &common.MessagePublication{ + pending1 := &OldMessagePublication{ TxHash: eth_common.HexToHash("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063"), Timestamp: now, Nonce: 123456, @@ -215,14 +219,14 @@ func TestAcctLoadingWhereOldPendingsGetDropped(t *testing.T) { // IsReobservation will not be serialized. It should be set to false on reload. } - db.acctStoreOldPendingTransfer(t, pending1) + err = db.acctStoreOldPendingTransfer(pending1) require.Nil(t, err) now2 := now.Add(time.Second * 5) // Write the second one in the new format. pending2 := &common.MessagePublication{ - TxHash: eth_common.HexToHash("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063"), + TxID: eth_common.HexToHash("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063").Bytes(), Timestamp: now2, Nonce: 123456, Sequence: 789101112131418, @@ -236,35 +240,111 @@ func TestAcctLoadingWhereOldPendingsGetDropped(t *testing.T) { err = db.AcctStorePendingTransfer(pending2) require.Nil(t, err) - // When we reload the data, the first one should get dropped, so we should get back only one. + // When we reload the data, the first one should get converted and returned here. pendings, err := db.AcctGetData(logger) require.NoError(t, err) - require.Equal(t, 1, len(pendings)) + require.Equal(t, 2, len(pendings)) + + // Verify that we converted and deleted the old one. + loggedEntries := zapObserver.FilterMessage("converting old pending transfer to new format").All() + require.Equal(t, 1, len(loggedEntries)) + loggedEntries = zapObserver.FilterMessage("deleting old pending transfer").All() + require.Equal(t, 1, len(loggedEntries)) - assert.Equal(t, *pending2, *pendings[0]) + sort.SliceStable(pendings, func(i, j int) bool { + return pendings[i].Timestamp.Before(pendings[j].Timestamp) + }) + + assert.Equal(t, *convertOldToNew(pending1), *pendings[0]) + assert.Equal(t, *pending2, *pendings[1]) - // Make sure we can still reload things after deleting the old one. + // Make sure we can still reload things after updating the old one. + logger, zapObserver = setupLogsCapture(t) pendings2, err := db.AcctGetData(logger) require.Nil(t, err) - require.Equal(t, 1, len(pendings2)) + require.Equal(t, 2, len(pendings2)) - assert.Equal(t, pending2, pendings2[0]) -} + // Verify that we didn't do any conversions the second time. + loggedEntries = zapObserver.FilterMessage("converting old pending transfer to new format").All() + require.Equal(t, 0, len(loggedEntries)) + loggedEntries = zapObserver.FilterMessage("deleting old pending transfer").All() + require.Equal(t, 0, len(loggedEntries)) -func (d *Database) acctStoreOldPendingTransfer(t *testing.T, msg *common.MessagePublication) { - buf := new(bytes.Buffer) + assert.Equal(t, *convertOldToNew(pending1), *pendings[0]) + assert.Equal(t, *pending2, *pendings[1]) - b := marshalOldMessagePublication(msg) + sort.SliceStable(pendings, func(i, j int) bool { + return pendings[i].Timestamp.Before(pendings[j].Timestamp) + }) - vaa.MustWrite(buf, binary.BigEndian, b) + assert.Equal(t, *convertOldToNew(pending1), *pendings[0]) + assert.Equal(t, *pending2, *pendings[1]) +} + +// setupLogsCapture is a helper function for making a zap logger/observer combination for testing that certain logs have been made +func setupLogsCapture(t testing.TB) (*zap.Logger, *observer.ObservedLogs) { + t.Helper() + observedCore, observedLogs := observer.New(zap.InfoLevel) + consoleLogger := zaptest.NewLogger(t, zaptest.Level(zap.InfoLevel)) + parentLogger := zap.New(zapcore.NewTee(observedCore, consoleLogger.Core())) + return parentLogger, observedLogs +} + +func (d *Database) acctStoreOldPendingTransfer(msg *OldMessagePublication) error { + b, _ := json.Marshal(msg) err := d.db.Update(func(txn *badger.Txn) error { - if err := txn.Set(acctOldPendingTransferMsgID(msg.MessageIDString()), buf.Bytes()); err != nil { + if err := txn.Set(acctOldPendingTransferMsgID(msg.MessageIDString()), b); err != nil { return err } return nil }) + if err != nil { + return fmt.Errorf("failed to commit old accountant pending transfer for tx %s: %w", msg.MessageIDString(), err) + } + + return nil +} + +// The standard json Marshal / Unmarshal of time.Time gets confused between local and UTC time. +func (msg *OldMessagePublication) MarshalJSON() ([]byte, error) { + type Alias OldMessagePublication + return json.Marshal(&struct { + Timestamp int64 + *Alias + }{ + Timestamp: msg.Timestamp.Unix(), + Alias: (*Alias)(msg), + }) +} + +func (msg *OldMessagePublication) MessageIDString() string { + return fmt.Sprintf("%v/%v/%v", uint16(msg.EmitterChain), msg.EmitterAddress, msg.Sequence) +} + +func TestUnmarshalOldJSON(t *testing.T) { + jsn := ` + { + "TxID": "SGVsbG8=", + "Timestamp": 1654516425, + "TxHash": "0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063", + "Nonce": 123456, + "Sequence": 789101112131415, + "ConsistencyLevel": 32, + "EmitterChain": 2, + "EmitterAddress": "000000000000000000000000707f9118e33a9b8998bea41dd0d46f38bb963fc8", + "Payload": "AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZJU04AAAAAAAAAAAAAAAAA3bZP5GqR1G7ilCBTn8Jf0Hxf6j4AAgAAAAAAAAAAAAAAAHB/kRjjOpuJmL6kHdDUbzi7lj/IAAU=", + "IsReobservation": false, + "Unreliable": false + } + ` + + var oldMsg OldMessagePublication + err := json.Unmarshal([]byte(jsn), &oldMsg) require.NoError(t, err) + + newMsg := convertOldToNew(&oldMsg) + assert.Equal(t, oldMsg.TxHash.String(), newMsg.TxIDString()) } diff --git a/node/pkg/db/governor.go b/node/pkg/db/governor.go index 48bcc9d0e5..08419c2f34 100644 --- a/node/pkg/db/governor.go +++ b/node/pkg/db/governor.go @@ -268,7 +268,7 @@ func UnmarshalPendingTransfer(data []byte, isOld bool) (*PendingTransfer, error) var msg *common.MessagePublication if isOld { - msg, err = common.UnmarshalOldMessagePublicationBeforeIsReobservation(buf) + msg, err = common.UnmarshalOldMessagePublicationWithTxHash(buf) } else { msg, err = common.UnmarshalMessagePublication(buf) } @@ -287,13 +287,13 @@ const transfer = "GOV:XFER3:" const transferLen = len(transfer) // Since we are changing the DB format of pending entries, we will use a new tag in the pending key field. -// The first time we run this new release, any existing entries with the "GOV:PENDING2" tag will get converted -// to the new format and given the "GOV:PENDING3" format. In a future release, the "GOV:PENDING2" code can be deleted. +// The first time we run this new release, any existing entries with the old tag will get converted +// to the new format and the new tag. In a future release, code for the old format can be deleted. -const oldPending = "GOV:PENDING2:" +const oldPending = "GOV:PENDING3:" const oldPendingLen = len(oldPending) -const pending = "GOV:PENDING3:" +const pending = "GOV:PENDING4:" const pendingLen = len(pending) const minMsgIdLen = len("1/0000000000000000000000000290fb167208af455bb137780163b7b7a9a10c16/0") diff --git a/node/pkg/db/governor_test.go b/node/pkg/db/governor_test.go index 0b0b2d17b0..eca60efdff 100644 --- a/node/pkg/db/governor_test.go +++ b/node/pkg/db/governor_test.go @@ -65,7 +65,7 @@ func TestPendingMsgID(t *testing.T) { require.NoError(t, err) msg1 := &common.MessagePublication{ - TxHash: eth_common.HexToHash("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063"), + TxID: eth_common.HexToHash("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063").Bytes(), Timestamp: time.Unix(int64(1654516425), 0), Nonce: 123456, Sequence: 789101112131415, @@ -75,7 +75,7 @@ func TestPendingMsgID(t *testing.T) { ConsistencyLevel: 16, } - assert.Equal(t, []byte("GOV:PENDING3:"+"2/0000000000000000000000000290fb167208af455bb137780163b7b7a9a10c16/789101112131415"), PendingMsgID(msg1)) + assert.Equal(t, []byte("GOV:PENDING4:"+"2/0000000000000000000000000290fb167208af455bb137780163b7b7a9a10c16/789101112131415"), PendingMsgID(msg1)) } func TestTransferMsgID(t *testing.T) { @@ -120,18 +120,18 @@ func TestIsTransfer(t *testing.T) { } func TestIsPendingMsg(t *testing.T) { - assert.Equal(t, true, IsPendingMsg([]byte("GOV:PENDING3:"+"2/0000000000000000000000000290fb167208af455bb137780163b7b7a9a10c16/789101112131415"))) + assert.Equal(t, true, IsPendingMsg([]byte("GOV:PENDING4:"+"2/0000000000000000000000000290fb167208af455bb137780163b7b7a9a10c16/789101112131415"))) assert.Equal(t, false, IsPendingMsg([]byte("GOV:XFER3:"+"2/0000000000000000000000000290fb167208af455bb137780163b7b7a9a10c16/789101112131415"))) - assert.Equal(t, false, IsPendingMsg([]byte("GOV:PENDING3:"))) - assert.Equal(t, false, IsPendingMsg([]byte("GOV:PENDING3:"+"1"))) - assert.Equal(t, false, IsPendingMsg([]byte("GOV:PENDING3:"+"1/1/1"))) - assert.Equal(t, false, IsPendingMsg([]byte("GOV:PENDING3:"+"1/0000000000000000000000000290fb167208af455bb137780163b7b7a9a10c16/"))) - assert.Equal(t, true, IsPendingMsg([]byte("GOV:PENDING3:"+"1/0000000000000000000000000290fb167208af455bb137780163b7b7a9a10c16/0"))) - assert.Equal(t, false, IsPendingMsg([]byte("GOV:PENDING2:"+"2/0000000000000000000000000290fb167208af455bb137780163b7b7a9a10c16/789101112131415"))) + assert.Equal(t, false, IsPendingMsg([]byte("GOV:PENDING4:"))) + assert.Equal(t, false, IsPendingMsg([]byte("GOV:PENDING4:"+"1"))) + assert.Equal(t, false, IsPendingMsg([]byte("GOV:PENDING4:"+"1/1/1"))) + assert.Equal(t, false, IsPendingMsg([]byte("GOV:PENDING4:"+"1/0000000000000000000000000290fb167208af455bb137780163b7b7a9a10c16/"))) + assert.Equal(t, true, IsPendingMsg([]byte("GOV:PENDING4:"+"1/0000000000000000000000000290fb167208af455bb137780163b7b7a9a10c16/0"))) + assert.Equal(t, false, IsPendingMsg([]byte("GOV:PENDING3:"+"2/0000000000000000000000000290fb167208af455bb137780163b7b7a9a10c16/789101112131415"))) assert.Equal(t, false, IsPendingMsg([]byte{0x01, 0x02, 0x03, 0x04})) assert.Equal(t, false, IsPendingMsg([]byte{})) - assert.Equal(t, true, isOldPendingMsg([]byte("GOV:PENDING2:"+"2/0000000000000000000000000290fb167208af455bb137780163b7b7a9a10c16/789101112131415"))) - assert.Equal(t, false, isOldPendingMsg([]byte("GOV:PENDING3:"+"2/0000000000000000000000000290fb167208af455bb137780163b7b7a9a10c16/789101112131415"))) + assert.Equal(t, true, isOldPendingMsg([]byte("GOV:PENDING3:"+"2/0000000000000000000000000290fb167208af455bb137780163b7b7a9a10c16/789101112131415"))) + assert.Equal(t, false, isOldPendingMsg([]byte("GOV:PENDING4:"+"2/0000000000000000000000000290fb167208af455bb137780163b7b7a9a10c16/789101112131415"))) } func TestGetChainGovernorData(t *testing.T) { @@ -228,7 +228,7 @@ func TestStorePendingMsg(t *testing.T) { assert.NoError(t, err2) msg := &common.MessagePublication{ - TxHash: eth_common.HexToHash("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063"), + TxID: eth_common.HexToHash("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063").Bytes(), Timestamp: time.Unix(int64(1654516425), 0), Nonce: 123456, Sequence: 789101112131415, @@ -253,7 +253,7 @@ func TestDeletePendingMsg(t *testing.T) { assert.NoError(t, err2) msg := &common.MessagePublication{ - TxHash: eth_common.HexToHash("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063"), + TxID: eth_common.HexToHash("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063").Bytes(), Timestamp: time.Unix(int64(1654516425), 0), Nonce: 123456, Sequence: 789101112131415, @@ -283,7 +283,7 @@ func TestSerializeAndDeserializeOfPendingTransfer(t *testing.T) { require.NoError(t, err) msg := common.MessagePublication{ - TxHash: eth_common.HexToHash("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063"), + TxID: eth_common.HexToHash("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063").Bytes(), Timestamp: time.Unix(int64(1654516425), 0), Nonce: 123456, Sequence: 789101112131415, @@ -307,7 +307,7 @@ func TestSerializeAndDeserializeOfPendingTransfer(t *testing.T) { assert.Equal(t, pending1, pending2) - expectedPendingKey := "GOV:PENDING3:2/0000000000000000000000000290fb167208af455bb137780163b7b7a9a10c16/789101112131415" + expectedPendingKey := "GOV:PENDING4:2/0000000000000000000000000290fb167208af455bb137780163b7b7a9a10c16/789101112131415" assert.Equal(t, expectedPendingKey, string(PendingMsgID(&pending2.Msg))) } @@ -361,7 +361,7 @@ func TestStoreAndReloadTransfers(t *testing.T) { pending1 := &PendingTransfer{ ReleaseTime: time.Unix(int64(1654516435+72*60*60), 0), Msg: common.MessagePublication{ - TxHash: eth_common.HexToHash("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063"), + TxID: eth_common.HexToHash("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063").Bytes(), Timestamp: time.Unix(int64(1654516435), 0), Nonce: 123456, Sequence: 789101112131417, @@ -378,7 +378,7 @@ func TestStoreAndReloadTransfers(t *testing.T) { pending2 := &PendingTransfer{ ReleaseTime: time.Unix(int64(1654516440+72*60*60), 0), Msg: common.MessagePublication{ - TxHash: eth_common.HexToHash("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063"), + TxID: eth_common.HexToHash("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063").Bytes(), Timestamp: time.Unix(int64(1654516440), 0), Nonce: 123456, Sequence: 789101112131418, @@ -524,7 +524,7 @@ func TestUnmarshalPendingTransferFailures(t *testing.T) { require.NoError(t, err) msg := common.MessagePublication{ - TxHash: eth_common.HexToHash("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063"), + TxID: eth_common.HexToHash("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063").Bytes(), Timestamp: time.Unix(int64(1654516425), 0), Nonce: 123456, Sequence: 789101112131415, @@ -585,13 +585,14 @@ func (d *Database) storeOldPendingMsg(t *testing.T, p *PendingTransfer) { func marshalOldMessagePublication(msg *common.MessagePublication) []byte { buf := new(bytes.Buffer) - buf.Write(msg.TxHash[:]) + buf.Write(msg.TxID[:]) vaa.MustWrite(buf, binary.BigEndian, uint32(msg.Timestamp.Unix())) vaa.MustWrite(buf, binary.BigEndian, msg.Nonce) vaa.MustWrite(buf, binary.BigEndian, msg.Sequence) vaa.MustWrite(buf, binary.BigEndian, msg.ConsistencyLevel) vaa.MustWrite(buf, binary.BigEndian, msg.EmitterChain) buf.Write(msg.EmitterAddress[:]) + vaa.MustWrite(buf, binary.BigEndian, msg.IsReobservation) buf.Write(msg.Payload) return buf.Bytes() @@ -674,13 +675,12 @@ func TestLoadingOldPendingTransfers(t *testing.T) { err = db.StoreTransfer(newXfer2) require.NoError(t, err) - now := time.Unix(time.Now().Unix(), 0) - // Write the first pending event in the old format. + now := time.Unix(time.Now().Unix(), 0) pending1 := &PendingTransfer{ ReleaseTime: now.Add(time.Hour * 71), // Setting it to 71 hours so we can confirm it didn't get set to the default., Msg: common.MessagePublication{ - TxHash: eth_common.HexToHash("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063"), + TxID: eth_common.HexToHash("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063").Bytes(), Timestamp: now, Nonce: 123456, Sequence: 789101112131417, @@ -695,14 +695,13 @@ func TestLoadingOldPendingTransfers(t *testing.T) { db.storeOldPendingMsg(t, pending1) require.NoError(t, err) - now2 := now.Add(time.Second * 5) - // Write the second one in the new format. + now = now.Add(time.Second * 5) pending2 := &PendingTransfer{ - ReleaseTime: now2.Add(time.Hour * 71), // Setting it to 71 hours so we can confirm it didn't get set to the default. + ReleaseTime: now.Add(time.Hour * 71), // Setting it to 71 hours so we can confirm it didn't get set to the default. Msg: common.MessagePublication{ - TxHash: eth_common.HexToHash("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063"), - Timestamp: now2, + TxID: eth_common.HexToHash("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063").Bytes(), + Timestamp: now, Nonce: 123456, Sequence: 789101112131418, EmitterChain: vaa.ChainIDEthereum, @@ -716,12 +715,39 @@ func TestLoadingOldPendingTransfers(t *testing.T) { err = db.StorePendingMsg(pending2) require.NoError(t, err) - logger := zap.NewNop() + // Write the third pending event in the old format. + now = now.Add(time.Second * 5) + pending3 := &PendingTransfer{ + ReleaseTime: now.Add(time.Hour * 71), // Setting it to 71 hours so we can confirm it didn't get set to the default., + Msg: common.MessagePublication{ + TxID: eth_common.HexToHash("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4064").Bytes(), + Timestamp: now, + Nonce: 123456, + Sequence: 789101112131419, + EmitterChain: vaa.ChainIDEthereum, + EmitterAddress: ethereumTokenBridgeAddr, + Payload: []byte{4, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + ConsistencyLevel: 16, + // IsReobservation will not be serialized. It should be set to false on reload. + }, + } + + db.storeOldPendingMsg(t, pending3) + require.NoError(t, err) + + logger, zapObserver := setupLogsCapture(t) + xfers, pendings, err := db.GetChainGovernorDataForTime(logger, now) require.NoError(t, err) require.Equal(t, 4, len(xfers)) - require.Equal(t, 2, len(pendings)) + require.Equal(t, 3, len(pendings)) + + // Verify that we converted the two old pending transfers and the two old completed transfers. + loggedEntries := zapObserver.FilterMessage("updating format of database entry for pending vaa").All() + require.Equal(t, 2, len(loggedEntries)) + loggedEntries = zapObserver.FilterMessage("updating format of database entry for completed transfer").All() + require.Equal(t, 2, len(loggedEntries)) sort.SliceStable(xfers, func(i, j int) bool { return xfers[i].Timestamp.Before(xfers[j].Timestamp) @@ -739,14 +765,23 @@ func TestLoadingOldPendingTransfers(t *testing.T) { assert.Equal(t, pending1.Msg, pendings[0].Msg) assert.Equal(t, pending2.Msg, pendings[1].Msg) + assert.Equal(t, pending3.Msg, pendings[2].Msg) // Make sure we can reload the updated pendings. + logger, zapObserver = setupLogsCapture(t) + xfers2, pendings2, err := db.GetChainGovernorDataForTime(logger, now) require.NoError(t, err) require.Equal(t, 4, len(xfers2)) - require.Equal(t, 2, len(pendings2)) + require.Equal(t, 3, len(pendings2)) + + // This time we shouldn't have updated anything. + loggedEntries = zapObserver.FilterMessage("updating format of database entry for pending vaa").All() + require.Equal(t, 0, len(loggedEntries)) + loggedEntries = zapObserver.FilterMessage("updating format of database entry for completed transfer").All() + require.Equal(t, 0, len(loggedEntries)) sort.SliceStable(xfers2, func(i, j int) bool { return xfers2[i].Timestamp.Before(xfers2[j].Timestamp) diff --git a/node/pkg/governor/generated_mainnet_tokens.go b/node/pkg/governor/generated_mainnet_tokens.go index 64f73693cb..69f14853b5 100644 --- a/node/pkg/governor/generated_mainnet_tokens.go +++ b/node/pkg/governor/generated_mainnet_tokens.go @@ -1,1609 +1,1633 @@ // This file contains the token config to be used in the mainnet environment. // -// This file was generated: Mon Dec 02 2024 13:38:04 GMT+0000 (Coordinated Universal Time) using a min notional of 0 +// This file was generated: Wed Jan 01 2025 00:13:58 GMT+0000 (Coordinated Universal Time) using a min notional of 0 package governor func generatedMainnetTokenList() []tokenConfigEntry { return []tokenConfigEntry{ - {chain: 1, addr: "017009a9390d6d6e7777a27675f05e1692fe09561cf25879203a0d282f8b3408", symbol: "SHILL", coinGeckoId: "shill-token", decimals: 6, price: 0.00081203}, // Addr: 6cVgJUqo4nmvQpbgrDZwyfd6RwWw5bfnCamS3M9N1fd, Notional: 2.7620322645570003 - {chain: 1, addr: "0266eb1428607b1c110941decd0ebe34eab6586ffba3e15820aa9c63b4110b10", symbol: "", coinGeckoId: "zignaly", decimals: 9, price: 0.14653}, // Addr: ANqY8h3sRSwkC29FvGJenAh7VGRABVVx7Ls6Mq4BuGT, Notional: 439.5900038786491 - {chain: 1, addr: "02a88b06fab40a8cd293f0c527587e62d2ffab766fca08b7f6f3c919ee731b12", symbol: "BNSOL", coinGeckoId: "binance-staked-sol", decimals: 9, price: 226.94}, // Addr: BNso1VUJnh4zcfpZa6986Ea66P6TCp59hvtNJ8b1X85, Notional: 28.56357616 - {chain: 1, addr: "03481237c86b4ff57b5c845a97ecee44f3b4c459954b607a232869cfb2bfb345", symbol: "BONKFA", coinGeckoId: "bonk-of-america", decimals: 6, price: 0.00011948}, // Addr: DoxsC4PpVHiUxCKYeKSkPXVVVSJYzidZZJxW4XCFF2t, Notional: 2.3978441200000002 - {chain: 1, addr: "0479d9c7cc1035de7211f99eb48c09d70b2bdf5bdf9e2e56b8a1fbb5a2ea3327", symbol: "JUP", coinGeckoId: "jupiter-exchange-solana", decimals: 6, price: 1.14}, // Addr: JUPyiwrYJFskUPiHa7hkeR8VUtAeFoSYbKedZNsDvCN, Notional: 10461.04302876 - {chain: 1, addr: "049a250bfacf558c6b6407a8d3716ff17c8c062a29b26a868e7ba5e7422ffd15", symbol: "mockJUP", coinGeckoId: "mockjup", decimals: 9, price: 0.00060827}, // Addr: JxxWsvm9jHt4ah7DT9NuLyVLYZcZLUdPD93PcPQ71Ka, Notional: 0.0669335839831061 + {chain: 1, addr: "00587a642600d6f2bd3bbfdf116dbd613c45cfa659b55a1fbc7cbc28e6092699", symbol: "Skibidi", coinGeckoId: "skibidi-dop-dop", decimals: 6, price: 0.00002261}, // Addr: 12MFXb5CGJ65S3mP3s4eMLaosGp6xGnQe3PxQD38nfJp, Notional: 420.3493149859188 + {chain: 1, addr: "017009a9390d6d6e7777a27675f05e1692fe09561cf25879203a0d282f8b3408", symbol: "SHILL", coinGeckoId: "shill-token", decimals: 6, price: 0.00083352}, // Addr: 6cVgJUqo4nmvQpbgrDZwyfd6RwWw5bfnCamS3M9N1fd, Notional: 2.8351281764880003 + {chain: 1, addr: "0266eb1428607b1c110941decd0ebe34eab6586ffba3e15820aa9c63b4110b10", symbol: "", coinGeckoId: "zignaly", decimals: 9, price: 0.112528}, // Addr: ANqY8h3sRSwkC29FvGJenAh7VGRABVVx7Ls6Mq4BuGT, Notional: 337.5840029786162 + {chain: 1, addr: "02a88b06fab40a8cd293f0c527587e62d2ffab766fca08b7f6f3c919ee731b12", symbol: "BNSOL", coinGeckoId: "binance-staked-sol", decimals: 9, price: 195.72}, // Addr: BNso1VUJnh4zcfpZa6986Ea66P6TCp59hvtNJ8b1X85, Notional: 24.65367408 + {chain: 1, addr: "03481237c86b4ff57b5c845a97ecee44f3b4c459954b607a232869cfb2bfb345", symbol: "BONKFA", coinGeckoId: "bonk-of-america", decimals: 6, price: 0.00013558}, // Addr: DoxsC4PpVHiUxCKYeKSkPXVVVSJYzidZZJxW4XCFF2t, Notional: 2.72095502 + {chain: 1, addr: "0479d9c7cc1035de7211f99eb48c09d70b2bdf5bdf9e2e56b8a1fbb5a2ea3327", symbol: "JUP", coinGeckoId: "jupiter-exchange-solana", decimals: 6, price: 0.821136}, // Addr: JUPyiwrYJFskUPiHa7hkeR8VUtAeFoSYbKedZNsDvCN, Notional: 15748.746237510097 + {chain: 1, addr: "049a250bfacf558c6b6407a8d3716ff17c8c062a29b26a868e7ba5e7422ffd15", symbol: "mockJUP", coinGeckoId: "mockjup", decimals: 9, price: 0.00075929}, // Addr: JxxWsvm9jHt4ah7DT9NuLyVLYZcZLUdPD93PcPQ71Ka, Notional: 0.0835517138483447 {chain: 1, addr: "049c63b95b6f586200bc5571c3deee5f0d404434c2bb1418f473c661893771cd", symbol: "clSUI", coinGeckoId: "cloned-sui", decimals: 8, price: 0.792309}, // Addr: JzwfZvJGdsqbrKZQUvzJpWhbHcZUix7CYcCaoiNpjxg, Notional: 0.792309 - {chain: 1, addr: "051687499457f76f90ed11ff8133233eee9f139718c36a85dff99950b7adabf1", symbol: "LARIX", coinGeckoId: "larix", decimals: 6, price: 0.0000969}, // Addr: Lrxqnh6ZHKbGy3dcrCED43nsoLkM1LTzU2jRfWe8qUC, Notional: 0.006783 - {chain: 1, addr: "052e7f80a14a1e7a5254e9a1c27f7fc48563bfc35f0be177a8d556ae8ba1add6", symbol: "MEAN", coinGeckoId: "meanfi", decimals: 6, price: 0.00731877}, // Addr: MEANeD3XDdUmNMsRGjASkSWdC8prLYsoRJ61pPeHctD, Notional: 0.0360083484 - {chain: 1, addr: "0537996f2699674fb7086e468fb33b4fde1449f47a8befd8b342bf6b33cff372", symbol: "MNDE", coinGeckoId: "marinade", decimals: 9, price: 0.129754}, // Addr: MNDEFzGvMt87ueuHvVU9VcTqsAP5b3fTGPsHuuPA5ey, Notional: 6.55361116143818 - {chain: 1, addr: "0545d1ee9805764e58b3ef5bcb54177517dfe7980e6e44e67a628bdb9d2a7bd1", symbol: "MNGO", coinGeckoId: "mango-markets", decimals: 6, price: 0.02853345}, // Addr: MangoCzJ36AjZyKwVj3VnYU4GTonjfVEnJmvvWaxLac, Notional: 0.014266725 - {chain: 1, addr: "05718b04572312d73aa71deaec43c89d77844b0b7ff9e3e72da8510182627455", symbol: "BLOCK", coinGeckoId: "blockasset", decimals: 6, price: 0.130061}, // Addr: NFTUkR4u7wKxy9QLaX2TGvd9oZSWoMo4jqSJqdMb7Nk, Notional: 3217082.6338479146 - {chain: 1, addr: "058bf1f00d167d3df31491dae204d6006b9d596870eecf5d305035df8a3f96dd", symbol: "NEON", coinGeckoId: "neon", decimals: 9, price: 0.416309}, // Addr: NeonTjSjsuo3rexg9o6vHuMXw62f9V7zvmu8M8Zut44, Notional: 45.79399 - {chain: 1, addr: "05be68ae2977ce39f15086f2c761b24cf054a40b22a2a5b33ef583c50f1cfdb7", symbol: "", coinGeckoId: "prism", decimals: 6, price: 0.00184594}, // Addr: PRSMNsEPqhGVCH1TtWiJqPjJyh2cKrLostPZTNy1o5x, Notional: 5.4744403109465205 - {chain: 1, addr: "05be6c87eec2d40a2e26e1fc0a8423a379820ca454982348adfc9563b5157725", symbol: "PRT", coinGeckoId: "parrot-protocol", decimals: 6, price: 0.00009678}, // Addr: PRT88RkA4Kg5z7pKnezeNH4mafTvtQdfFgpQTGRjz44, Notional: 0.02794828198986 - {chain: 1, addr: "05beb884b642b260d9c2b53cb3d876b8b4de72aea0d787d779bf4266688a3935", symbol: "", coinGeckoId: "solanaprime", decimals: 9, price: 0.00331269}, // Addr: PRiME7gDoiG1vGr95a3CRMv9xHY7UGjd4JKvfSkmQu2, Notional: 0.35114514 - {chain: 1, addr: "061391c556ba0106d4b1b2ccf939d47caf9fb30639a58bf9cc315d024f1cb458", symbol: "", coinGeckoId: "tudabirds", decimals: 9, price: 0.00081187}, // Addr: Qikhhhg9Ta3Jg7WoDFbSYuCAE14hx9hPvdz1zVp3zUw, Notional: 0.55613095 - {chain: 1, addr: "063ba2f4697205f531b6de49bb9605fd2ca6a9ddf243bed251fda6552ef0e571", symbol: "", coinGeckoId: "rollbit-coin", decimals: 2, price: 0.109263}, // Addr: RLBxxFkseAZ4RgJH3Sqn8jXxhmGoz9jWxDNJMh8pL7a, Notional: 1795.9985435699998 - {chain: 1, addr: "0679db01ce2a84f71c139e7c9942f6da3b331fdec3319d02f899eba70134737e", symbol: "SHDW", coinGeckoId: "genesysgo-shadow", decimals: 9, price: 0.445767}, // Addr: SHDWyBxihqiCj6YekG2GUr7wqKLeLAMK1gHZck9pL6y, Notional: 89.59916700000001 - {chain: 1, addr: "067d3988ce882945c63a0717a92538addd9a37550ce5cd711f76ca74a4c89786", symbol: "", coinGeckoId: "solcial", decimals: 9, price: 0.00020249}, // Addr: SLCLww7nc1PD2gQPQdGayHviVVcpMthnqUz2iWKhNQV, Notional: 0.0018492191191525 - {chain: 1, addr: "067fc27abcad2df07cc40437330da4fe8851680ae2b242c2ea1d86e2cfa10064", symbol: "SNS", coinGeckoId: "synesis-one", decimals: 9, price: 0.03561527}, // Addr: SNSNkV9zfG5ZKWQs6x4hxvBRV6s8SqMfSGCtECDvdMd, Notional: 6191.793345303812 - {chain: 1, addr: "068310861a98327d0550574d84418aa6e10c3352ddaa7fd7f58152cceeb23887", symbol: "SRM", coinGeckoId: "serum", decimals: 6, price: 0.03891126}, // Addr: SRMuApVNdxXokk5GT7XD5cUUgXMBCoAz2LHeuAoKWRt, Notional: 1019.5325954506912 - {chain: 1, addr: "068677427842ef204cf58abdf76271228b5a485abb6dfa465e6ed7ee8b7d5e79", symbol: "SUNNY", coinGeckoId: "sunny-aggregator", decimals: 6, price: 0.00004153}, // Addr: SUNNYWgPQmFxe9wTZzNK7iPnJ3vYDrkgnxJRJm1s3ag, Notional: 0.12150809171634999 - {chain: 1, addr: "068d824d56f0eebb7566e6ee1d65a9d260ff509a4b5c69b6269ad64de3cd50bc", symbol: "SBR", coinGeckoId: "saber", decimals: 6, price: 0.00272886}, // Addr: Saber2gLauYim4Mvftnrasomsv6NvAuncvMEZwcLpD1, Notional: 9.6538237709913 - {chain: 1, addr: "069501a7f73f3b05dfff8b104d2393e9c39e1ee2fe6b329ccf9847ccfa2af594", symbol: "SHEESH", coinGeckoId: "sheeshin-on-solana", decimals: 6, price: 0.03001481}, // Addr: ShEEsukacNfbBpULD1xtCZKjeMMzvc78xufMDuE3jvB, Notional: 9.65564996054428 - {chain: 1, addr: "069b8857feab8184fb687f634618c035dac439dc1aeb3b5598a0f00000000001", symbol: "SOL", coinGeckoId: "wrapped-solana", decimals: 9, price: 222.86}, // Addr: So11111111111111111111111111111111111111112, Notional: 150750740.7636939 - {chain: 1, addr: "06a1ec5bd82ad9c032a9f7d466ba2c728b0ef36a8b773ed219d69650d3472bd6", symbol: "", coinGeckoId: "step-finance", decimals: 9, price: 0.088258}, // Addr: StepAscQoEioFxxWGnh2sLBDFp9d8rvKz2Yp39iDpyT, Notional: 7.736434753011821 - {chain: 1, addr: "06cf442fd1ea50d2b18629079232396c075d29c1eda912d38fd75049f827e3a3", symbol: "TAKI", coinGeckoId: "taki", decimals: 9, price: 0.00192391}, // Addr: Taki7fi3Zicv7Du1xNAWLaf6mRK7ikdn77HeGzgwvo4, Notional: 67755.3477003371 - {chain: 1, addr: "06e44836998a9e52bde7b5182fdbbdde4e2789cbffe5ab0e9762cb13651c8bda", symbol: "TULIP", coinGeckoId: "solfarm", decimals: 6, price: 0.342763}, // Addr: TuLipcqtGVXP9XR62wM8WWCm6a9vhLs7T1uoWBk6FDs, Notional: 0.000685526 - {chain: 1, addr: "0704152a9efdde41a8971e72c23f18079623cad2b3a8d4330cc7ee0072aba7a1", symbol: "UPT", coinGeckoId: "uprock", decimals: 9, price: 0.0174666}, // Addr: UPTx1d24aBWuRgwxVnFmX4gNraj3QGFzL3QqBgxtWQG, Notional: 0.428421115529328 - {chain: 1, addr: "0707305232e6160c18b4099da5b66bd387bc6469ad2244f283f73ff2a8e40338", symbol: "", coinGeckoId: "usdh", decimals: 6, price: 0.96996}, // Addr: USDH1SM1ojwWUga67PGrgFWUHibbjqMvuMaDkRJTgkX, Notional: 9.67292028024 - {chain: 1, addr: "070d0b9bee96609a69a17a10833705370fb116a06adb20d5efd866e68051c132", symbol: "", coinGeckoId: "uxd-protocol-token", decimals: 9, price: 0.01513344}, // Addr: UXPhBoR3qG4UCiGNJfV7MqhHyFqKN68g45GoYvAeL2M, Notional: 12.747232495252147 - {chain: 1, addr: "072844c94ab6a7097e1134511934be65304b482d6e8850493ce05ac78755dbea", symbol: "UWU", coinGeckoId: "unicorn-3", decimals: 6, price: 0.00035563}, // Addr: UwU8RVXB69Y6Dcju6cN2Qef6fykkq6UUNpB15rZku6Z, Notional: 243154.6180543812 - {chain: 1, addr: "077cf63a56ff0afb124f6f68875a02adce4e320bbfcc1072e67a0a4ffa46c295", symbol: "WEN", coinGeckoId: "wen-4", decimals: 5, price: 0.00013679}, // Addr: WENWENvqqNya429ubCdR81ZmD69brwQaaBYY6p3LCpk, Notional: 706.9170112331282 - {chain: 1, addr: "08742da77f532cb2337402e2ab66187b63a2907c9a62107dab7013a28deb4657", symbol: "ABR", coinGeckoId: "allbridge", decimals: 9, price: 0.116295}, // Addr: a11bdAAuV8iB2fu7X6AxAvDTo1QZ8FXB3kk5eecdasp, Notional: 0.7665907364517 - {chain: 1, addr: "08808616ce71e6e2e483262f0dc1cf87122c2001543cbfc95fd75fab46ac2893", symbol: "HAPPI", coinGeckoId: "happi-cat", decimals: 6, price: 0.00011643}, // Addr: aBvs3Zv9JYmvUCKqRJvGctDQSCt6R7NAMELid3FeqsQ, Notional: 192.5936532236803 - {chain: 1, addr: "08d2e970f93c7b3d50191e611acd93aa80a546b45ec965e18b0587155699c8ac", symbol: "", coinGeckoId: "blazestake-staked-sol", decimals: 9, price: 261.17}, // Addr: bSo13r4TkiE4KumL71LsHTPpL2euBYLFx6h9HP3piy1, Notional: 27.1916753745 - {chain: 1, addr: "08ea6f14a48ad8d63068ce1114a7f5148c0dc909a8564c958e57e4ddea0e6cbf", symbol: "BOBAOPPA", coinGeckoId: "boba-oppa", decimals: 6, price: 0.0019002}, // Addr: bobaM3u8QmqZhY1HwAtnvze9DLXvkgKYk3td3t8MLva, Notional: 0.14220299286059998 - {chain: 1, addr: "08eaab49809a0d284791dcf38d96b4dde48d41807f3a795dcfaf325205943057", symbol: "Boo", coinGeckoId: "boo-2", decimals: 9, price: 0.00005478}, // Addr: booe3XGMztBMB9RhCgNodhJQeaaMmhdGehMCVPMGza2, Notional: 1.3923655010486695 - {chain: 1, addr: "0936990e30118f3e824ab4ad611dbacae303117a46ab833c9c911acb736a7ecf", symbol: "", coinGeckoId: "solchicks-token", decimals: 9, price: 0.00006916}, // Addr: cxxShYRVcepDudXhe7U62QHvw8uBJoKFifmzggGKVC2, Notional: 0.00774592 - {chain: 1, addr: "0a732093918561f7dd7fcbec4abd8513deca1a967f7ad7a39d63b41ed893808b", symbol: "HNT", coinGeckoId: "helium", decimals: 8, price: 8.05}, // Addr: hntyVP6YFm1Hg25TN9WGLqM12b8TQmcknKrdu1oxWux, Notional: 0.09124562300000001 - {chain: 1, addr: "0afcf8968b8dab88481e2d2ae689c952c757aeba643e3919e89f2e55795c76c1", symbol: "JTO", coinGeckoId: "jito-governance-token", decimals: 9, price: 3.37}, // Addr: jtojtomepa8beP8AuQc6eXt5FriJwfFMwQx2v2f9mCL, Notional: 138.2652568581 - {chain: 1, addr: "0b32c16d6e18acb932405c63adbf490ed2e214adf8860590fafcc3c869556b26", symbol: "", coinGeckoId: "kineko", decimals: 9, price: 0.00024525}, // Addr: kiNeKo77w1WBEzFFCXrTDRWGRWGP8yHvKC9rX6dqjQh, Notional: 0.026988936471022504 - {chain: 1, addr: "0b3338a0ab2cc841d5b014bc6a3cf756291874b319c9517d9bbfa9e4e9661ef9", symbol: "KIN", coinGeckoId: "kin", decimals: 5, price: 0.0000127}, // Addr: kinXdEcpDQeHPEuQnqmUgtYykqKGVFq6CeVX5iAHJq6, Notional: 1.608134837572 - {chain: 1, addr: "0b62ba074f722c9d4114f2d8f70a00c66002337b9bf90c873657a6d201db4c80", symbol: "mSOL", coinGeckoId: "msol", decimals: 9, price: 276.03}, // Addr: mSoLzYCxHdYgdzU16g5QSh3i5K3z3KZK7ytfqcJm7So, Notional: 134.5252990059 - {chain: 1, addr: "0b8bba91467afe97500d18b35605e1c5842b2310a97ebfb863d17f32f1943fb1", symbol: "PEEP", coinGeckoId: "peepo-sol", decimals: 6, price: 0.0000115}, // Addr: n54ZwXEcLnc3o7zK48nhrLV4KTU5wWD4iq7Gvdt5tik, Notional: 0.0000115 - {chain: 1, addr: "0c00d0afeb8614da7f19aba02d40f18c692585f65020dfced3d5e5f9a9c0c4e1", symbol: "ORCA", coinGeckoId: "orca", decimals: 6, price: 3.3}, // Addr: orcaEKTdK7LKz57vaAYr9QeNsVEPfiu6QeMU1kektZE, Notional: 70.5449184 + {chain: 1, addr: "051687499457f76f90ed11ff8133233eee9f139718c36a85dff99950b7adabf1", symbol: "LARIX", coinGeckoId: "larix", decimals: 6, price: 0.00009183}, // Addr: Lrxqnh6ZHKbGy3dcrCED43nsoLkM1LTzU2jRfWe8qUC, Notional: 0.006428099999999999 + {chain: 1, addr: "052e7f80a14a1e7a5254e9a1c27f7fc48563bfc35f0be177a8d556ae8ba1add6", symbol: "MEAN", coinGeckoId: "meanfi", decimals: 6, price: 0.00088285}, // Addr: MEANeD3XDdUmNMsRGjASkSWdC8prLYsoRJ61pPeHctD, Notional: 0.004343622 + {chain: 1, addr: "0537996f2699674fb7086e468fb33b4fde1449f47a8befd8b342bf6b33cff372", symbol: "MNDE", coinGeckoId: "marinade", decimals: 9, price: 0.120143}, // Addr: MNDEFzGvMt87ueuHvVU9VcTqsAP5b3fTGPsHuuPA5ey, Notional: 6.06817906013431 + {chain: 1, addr: "0545d1ee9805764e58b3ef5bcb54177517dfe7980e6e44e67a628bdb9d2a7bd1", symbol: "MNGO", coinGeckoId: "mango-markets", decimals: 6, price: 0.02209587}, // Addr: MangoCzJ36AjZyKwVj3VnYU4GTonjfVEnJmvvWaxLac, Notional: 0.011047935 + {chain: 1, addr: "05718b04572312d73aa71deaec43c89d77844b0b7ff9e3e72da8510182627455", symbol: "BLOCK", coinGeckoId: "blockasset", decimals: 6, price: 0.085819}, // Addr: NFTUkR4u7wKxy9QLaX2TGvd9oZSWoMo4jqSJqdMb7Nk, Notional: 2239397.9397194996 + {chain: 1, addr: "058bf1f00d167d3df31491dae204d6006b9d596870eecf5d305035df8a3f96dd", symbol: "NEON", coinGeckoId: "neon", decimals: 9, price: 0.373403}, // Addr: NeonTjSjsuo3rexg9o6vHuMXw62f9V7zvmu8M8Zut44, Notional: 41.074329999999996 + {chain: 1, addr: "05be68ae2977ce39f15086f2c761b24cf054a40b22a2a5b33ef583c50f1cfdb7", symbol: "", coinGeckoId: "prism", decimals: 6, price: 0.00108237}, // Addr: PRSMNsEPqhGVCH1TtWiJqPjJyh2cKrLostPZTNy1o5x, Notional: 3.2099472135384604 + {chain: 1, addr: "05be6c87eec2d40a2e26e1fc0a8423a379820ca454982348adfc9563b5157725", symbol: "PRT", coinGeckoId: "parrot-protocol", decimals: 6, price: 0.00006157}, // Addr: PRT88RkA4Kg5z7pKnezeNH4mafTvtQdfFgpQTGRjz44, Notional: 0.01778028231159 + {chain: 1, addr: "05beb884b642b260d9c2b53cb3d876b8b4de72aea0d787d779bf4266688a3935", symbol: "", coinGeckoId: "solanaprime", decimals: 9, price: 14.81}, // Addr: PRiME7gDoiG1vGr95a3CRMv9xHY7UGjd4JKvfSkmQu2, Notional: 1569.8600000000001 + {chain: 1, addr: "061391c556ba0106d4b1b2ccf939d47caf9fb30639a58bf9cc315d024f1cb458", symbol: "", coinGeckoId: "tudabirds", decimals: 9, price: 0.00082191}, // Addr: Qikhhhg9Ta3Jg7WoDFbSYuCAE14hx9hPvdz1zVp3zUw, Notional: 0.56300835 + {chain: 1, addr: "063ba2f4697205f531b6de49bb9605fd2ca6a9ddf243bed251fda6552ef0e571", symbol: "", coinGeckoId: "rollbit-coin", decimals: 2, price: 0.112137}, // Addr: RLBxxFkseAZ4RgJH3Sqn8jXxhmGoz9jWxDNJMh8pL7a, Notional: 1843.2396024299999 + {chain: 1, addr: "0679db01ce2a84f71c139e7c9942f6da3b331fdec3319d02f899eba70134737e", symbol: "SHDW", coinGeckoId: "genesysgo-shadow", decimals: 9, price: 0.664709}, // Addr: SHDWyBxihqiCj6YekG2GUr7wqKLeLAMK1gHZck9pL6y, Notional: 133.606509 + {chain: 1, addr: "067d3988ce882945c63a0717a92538addd9a37550ce5cd711f76ca74a4c89786", symbol: "", coinGeckoId: "solcial", decimals: 9, price: 0.00017513}, // Addr: SLCLww7nc1PD2gQPQdGayHviVVcpMthnqUz2iWKhNQV, Notional: 0.0015993567303925 + {chain: 1, addr: "067fc27abcad2df07cc40437330da4fe8851680ae2b242c2ea1d86e2cfa10064", symbol: "SNS", coinGeckoId: "synesis-one", decimals: 9, price: 0.01384187}, // Addr: SNSNkV9zfG5ZKWQs6x4hxvBRV6s8SqMfSGCtECDvdMd, Notional: 2515.13315677366 + {chain: 1, addr: "068310861a98327d0550574d84418aa6e10c3352ddaa7fd7f58152cceeb23887", symbol: "SRM", coinGeckoId: "serum", decimals: 6, price: 0.03198372}, // Addr: SRMuApVNdxXokk5GT7XD5cUUgXMBCoAz2LHeuAoKWRt, Notional: 838.0207956197816 + {chain: 1, addr: "068677427842ef204cf58abdf76271228b5a485abb6dfa465e6ed7ee8b7d5e79", symbol: "SUNNY", coinGeckoId: "sunny-aggregator", decimals: 6, price: 0.00002564}, // Addr: SUNNYWgPQmFxe9wTZzNK7iPnJ3vYDrkgnxJRJm1s3ag, Notional: 0.0750172759838 + {chain: 1, addr: "068d824d56f0eebb7566e6ee1d65a9d260ff509a4b5c69b6269ad64de3cd50bc", symbol: "SBR", coinGeckoId: "saber", decimals: 6, price: 0.00208324}, // Addr: Saber2gLauYim4Mvftnrasomsv6NvAuncvMEZwcLpD1, Notional: 7.3698290981142 + {chain: 1, addr: "069501a7f73f3b05dfff8b104d2393e9c39e1ee2fe6b329ccf9847ccfa2af594", symbol: "SHEESH", coinGeckoId: "sheeshin-on-solana", decimals: 6, price: 0.02458333}, // Addr: ShEEsukacNfbBpULD1xtCZKjeMMzvc78xufMDuE3jvB, Notional: 7.90836354934604 + {chain: 1, addr: "069b8857feab8184fb687f634618c035dac439dc1aeb3b5598a0f00000000001", symbol: "SOL", coinGeckoId: "wrapped-solana", decimals: 9, price: 190.69}, // Addr: So11111111111111111111111111111111111111112, Notional: 130204615.67853324 + {chain: 1, addr: "06a1ec5bd82ad9c032a9f7d466ba2c728b0ef36a8b773ed219d69650d3472bd6", symbol: "", coinGeckoId: "step-finance", decimals: 9, price: 0.116467}, // Addr: StepAscQoEioFxxWGnh2sLBDFp9d8rvKz2Yp39iDpyT, Notional: 10.20915210382093 + {chain: 1, addr: "06cf442fd1ea50d2b18629079232396c075d29c1eda912d38fd75049f827e3a3", symbol: "TAKI", coinGeckoId: "taki", decimals: 9, price: 0.0021849}, // Addr: Taki7fi3Zicv7Du1xNAWLaf6mRK7ikdn77HeGzgwvo4, Notional: 77012.3445918788 + {chain: 1, addr: "06e44836998a9e52bde7b5182fdbbdde4e2789cbffe5ab0e9762cb13651c8bda", symbol: "TULIP", coinGeckoId: "solfarm", decimals: 6, price: 0.259281}, // Addr: TuLipcqtGVXP9XR62wM8WWCm6a9vhLs7T1uoWBk6FDs, Notional: 0.000518562 + {chain: 1, addr: "0704152a9efdde41a8971e72c23f18079623cad2b3a8d4330cc7ee0072aba7a1", symbol: "UPT", coinGeckoId: "uprock", decimals: 9, price: 0.01209396}, // Addr: UPTx1d24aBWuRgwxVnFmX4gNraj3QGFzL3QqBgxtWQG, Notional: 0.2966408937267168 + {chain: 1, addr: "0707305232e6160c18b4099da5b66bd387bc6469ad2244f283f73ff2a8e40338", symbol: "", coinGeckoId: "usdh", decimals: 6, price: 0.998286}, // Addr: USDH1SM1ojwWUga67PGrgFWUHibbjqMvuMaDkRJTgkX, Notional: 9.955401145284 + {chain: 1, addr: "070d0b9bee96609a69a17a10833705370fb116a06adb20d5efd866e68051c132", symbol: "", coinGeckoId: "uxd-protocol-token", decimals: 9, price: 0.01534078}, // Addr: UXPhBoR3qG4UCiGNJfV7MqhHyFqKN68g45GoYvAeL2M, Notional: 12.921879580486276 + {chain: 1, addr: "072844c94ab6a7097e1134511934be65304b482d6e8850493ce05ac78755dbea", symbol: "UWU", coinGeckoId: "unicorn-3", decimals: 6, price: 0.00026089}, // Addr: UwU8RVXB69Y6Dcju6cN2Qef6fykkq6UUNpB15rZku6Z, Notional: 139558.4580037889 + {chain: 1, addr: "077cf63a56ff0afb124f6f68875a02adce4e320bbfcc1072e67a0a4ffa46c295", symbol: "WEN", coinGeckoId: "wen-4", decimals: 5, price: 0.0000825}, // Addr: WENWENvqqNya429ubCdR81ZmD69brwQaaBYY6p3LCpk, Notional: 430.4977327662 + {chain: 1, addr: "07bb093e9f7decab41a717b15946f6db587868a6721c0a6e3c4281ed3fef0e09", symbol: "XBG", coinGeckoId: "xborg", decimals: 9, price: 0.350592}, // Addr: XBGdqJ9P175hCC1LangCEyXWNeCPHaKWA17tymz2PrY, Notional: 3483.0115400621803 + {chain: 1, addr: "08742da77f532cb2337402e2ab66187b63a2907c9a62107dab7013a28deb4657", symbol: "ABR", coinGeckoId: "allbridge", decimals: 9, price: 0.096751}, // Addr: a11bdAAuV8iB2fu7X6AxAvDTo1QZ8FXB3kk5eecdasp, Notional: 0.63776104168226 + {chain: 1, addr: "08808616ce71e6e2e483262f0dc1cf87122c2001543cbfc95fd75fab46ac2893", symbol: "HAPPI", coinGeckoId: "happi-cat", decimals: 6, price: 0.0000679}, // Addr: aBvs3Zv9JYmvUCKqRJvGctDQSCt6R7NAMELid3FeqsQ, Notional: 112.31734994320959 + {chain: 1, addr: "08d2e970f93c7b3d50191e611acd93aa80a546b45ec965e18b0587155699c8ac", symbol: "", coinGeckoId: "blazestake-staked-sol", decimals: 9, price: 225.2}, // Addr: bSo13r4TkiE4KumL71LsHTPpL2euBYLFx6h9HP3piy1, Notional: 23.44666422 + {chain: 1, addr: "08ea6f14a48ad8d63068ce1114a7f5148c0dc909a8564c958e57e4ddea0e6cbf", symbol: "BOBAOPPA", coinGeckoId: "boba-oppa", decimals: 6, price: 0.0015667}, // Addr: bobaM3u8QmqZhY1HwAtnvze9DLXvkgKYk3td3t8MLva, Notional: 0.1172452525601 + {chain: 1, addr: "08eaab49809a0d284791dcf38d96b4dde48d41807f3a795dcfaf325205943057", symbol: "Boo", coinGeckoId: "boo-2", decimals: 9, price: 0.00005436}, // Addr: booe3XGMztBMB9RhCgNodhJQeaaMmhdGehMCVPMGza2, Notional: 1.381690190525843 + {chain: 1, addr: "0936990e30118f3e824ab4ad611dbacae303117a46ab833c9c911acb736a7ecf", symbol: "", coinGeckoId: "solchicks-token", decimals: 9, price: 0.00005649}, // Addr: cxxShYRVcepDudXhe7U62QHvw8uBJoKFifmzggGKVC2, Notional: 0.00632688 + {chain: 1, addr: "0a732093918561f7dd7fcbec4abd8513deca1a967f7ad7a39d63b41ed893808b", symbol: "HNT", coinGeckoId: "helium", decimals: 8, price: 5.88}, // Addr: hntyVP6YFm1Hg25TN9WGLqM12b8TQmcknKrdu1oxWux, Notional: 0.0666489768 + {chain: 1, addr: "0afcf8968b8dab88481e2d2ae689c952c757aeba643e3919e89f2e55795c76c1", symbol: "JTO", coinGeckoId: "jito-governance-token", decimals: 9, price: 3.35}, // Addr: jtojtomepa8beP8AuQc6eXt5FriJwfFMwQx2v2f9mCL, Notional: 137.4446915355 + {chain: 1, addr: "0b32c16d6e18acb932405c63adbf490ed2e214adf8860590fafcc3c869556b26", symbol: "", coinGeckoId: "kineko", decimals: 9, price: 0.00023768}, // Addr: kiNeKo77w1WBEzFFCXrTDRWGRWGP8yHvKC9rX6dqjQh, Notional: 0.026155883467615198 + {chain: 1, addr: "0b3338a0ab2cc841d5b014bc6a3cf756291874b319c9517d9bbfa9e4e9661ef9", symbol: "KIN", coinGeckoId: "kin", decimals: 5, price: 0.00001236}, // Addr: kinXdEcpDQeHPEuQnqmUgtYykqKGVFq6CeVX5iAHJq6, Notional: 1.5650824088496 + {chain: 1, addr: "0b62ba074f722c9d4114f2d8f70a00c66002337b9bf90c873657a6d201db4c80", symbol: "mSOL", coinGeckoId: "msol", decimals: 9, price: 239}, // Addr: mSoLzYCxHdYgdzU16g5QSh3i5K3z3KZK7ytfqcJm7So, Notional: 116.47844966999999 + {chain: 1, addr: "0b8bba91467afe97500d18b35605e1c5842b2310a97ebfb863d17f32f1943fb1", symbol: "PEEP", coinGeckoId: "peepo-sol", decimals: 6, price: 0.00000454}, // Addr: n54ZwXEcLnc3o7zK48nhrLV4KTU5wWD4iq7Gvdt5tik, Notional: 0.00000454 + {chain: 1, addr: "0c00d0afeb8614da7f19aba02d40f18c692585f65020dfced3d5e5f9a9c0c4e1", symbol: "ORCA", coinGeckoId: "orca", decimals: 6, price: 3.93}, // Addr: orcaEKTdK7LKz57vaAYr9QeNsVEPfiu6QeMU1kektZE, Notional: 84.01258464000001 {chain: 1, addr: "0c96450628904429a41300a3eeb390680414f8c0a2e1a2442610df748aca371e", symbol: "DAOJONES", coinGeckoId: "fractionalized-smb-2367", decimals: 2, price: 0.197795}, // Addr: r8nuuzXCchjtqsmQZVZDPXXq928tuk7KVH479GsKVpy, Notional: 0.197795 - {chain: 1, addr: "0cc10f516aaae9c14ba9471f60abd392dcd786d57354abedeee7289dd40a0a0a", symbol: "RENDER", coinGeckoId: "render-token", decimals: 8, price: 8.23}, // Addr: rndrizKT3MK1iimdxRdWabcF7Zg7AR5T4nud4EkHBof, Notional: 4311.898770218901 - {chain: 1, addr: "0cea8ee4d02b332af25488b03f6b02b11cd5ca4b7f051ee72575c50b55addd40", symbol: "sRLY", coinGeckoId: "rally-solana", decimals: 9, price: 0.00198602}, // Addr: sRLY3migNrkC1HLgqotpvi66qGkdNedqPZ9TJpAQhyh, Notional: 27.280651321109918 - {chain: 1, addr: "0d8323c076f0e28718ca60d77e6b39cee8f23f43cfc4ff1f5852b8fc1b94a293", symbol: "BOME", coinGeckoId: "book-of-meme", decimals: 6, price: 0.00867428}, // Addr: ukHH6c7mMyiWCf1b9pnWe25TSpkDDt3H5pQZgZ74J82, Notional: 202821.513723713 - {chain: 1, addr: "0e217f1d89397a8a2cdfcf5e46b64ac4e04206a3f396cd87b23734049eff9cae", symbol: "xALGO", coinGeckoId: "wrapped-algo", decimals: 6, price: 0.726056}, // Addr: xALGoH1zUfRmpCriy94qbfoMXHtK6NDnMKzT4Xdvgms, Notional: 18.641014411488 - {chain: 1, addr: "0e56395e3c860143802e9b94a02cc6d04f75fec72a3fbb715268355e0cd7cd89", symbol: "SLIM", coinGeckoId: "solanium", decimals: 6, price: 0.132029}, // Addr: xxxxa1sKNGwFtw2kFn8XauW9xq8hBZ5kVtcSesTT9fW, Notional: 5.69148632765 - {chain: 1, addr: "0ec49e1c77e79828f9ae8a051b662e2088c728069cedb70fef8521b94acf74f8", symbol: "", coinGeckoId: "zebec-protocol", decimals: 9, price: 0.00107021}, // Addr: zebeczgi5fSEtbpfQKVZKCJ3WgYXxjkMUkNNx7fLKAF, Notional: 337.1094445877295 - {chain: 1, addr: "1076469c1041d9e9b39fc2ede11333973b3e95732a4439207193a61cc4108d43", symbol: "JLP", coinGeckoId: "jupiter-perpetuals-liquidity-provider-token", decimals: 6, price: 4.11}, // Addr: 27G8MtK7VtTcCHkpASjSDdkWWYfoqT6ggEuKidVJidD4, Notional: 2.055 - {chain: 1, addr: "11615a73ca119d91ad275cf19659f206265356fbd4161175b6c2cee43ceb267a", symbol: "STATE", coinGeckoId: "new-world-order", decimals: 3, price: 9.242e-12}, // Addr: 2Ar2n5DJSiQuMhY4XeSzg7C5AGMezZPoLUt98VmmjsAR, Notional: 112.8766202719914 - {chain: 1, addr: "11f6454055669087f8f46c16a81e0ec3df5f68187b6bb8f1ecb954d07b7d3339", symbol: "GNOME", coinGeckoId: "gnomeland", decimals: 9, price: 0.00033993}, // Addr: 2D7jZLpUUAMboqzHMeyaxZfLWpf4JZUoR4i82Zva7sxU, Notional: 11182.887259867432 - {chain: 1, addr: "128bcb647d8bad1e7250e3b834bcfa9fd986f4d477d1bbb9054e602b11ebe061", symbol: "ETH", coinGeckoId: "wrapped-ethereum-sollet", decimals: 6, price: 820.25}, // Addr: 2FPyTwcZLUg1MDrwsyoP4D6s1tM7hAkHYRjkNb5w6Pxk, Notional: 8.2025 - {chain: 1, addr: "131fec1ab25c75e93eceea35ea3d3d82e6a3fd3d1e1f45a68ee0c14245aebaf6", symbol: "SAO", coinGeckoId: "sator", decimals: 9, price: 0.00019851}, // Addr: 2HeykdKjzHKGm2LKHw8pDYwjKPiFEoXAz74dirhUgQvq, Notional: 6788.3481207744735 - {chain: 1, addr: "139fc1fba8ff288c85d542130fc2caf2caf15d4dc9fce4ac81c1de0fdd3e5be1", symbol: "KURO", coinGeckoId: "kurobi", decimals: 6, price: 0.00003125}, // Addr: 2Kc38rfQ49DFaKHQaWbijkE7fcymUMLY5guUiUsDmFfn, Notional: 0.32266526675 - {chain: 1, addr: "16360094fd16e58867412ca58e622fe81a71fe47b8a8bf3b612e9d96a403d33b", symbol: "EUROe", coinGeckoId: "euroe-stablecoin", decimals: 6, price: 1.056}, // Addr: 2VhjJ9WxaGC3EZFwJG9BDUs9KxKCAjQY4vgd1qxgYWVg, Notional: 5.28 - {chain: 1, addr: "17e700a49c421ef60ab1bb731357d11093c809d0056852d3e9e1e6c2653c81e9", symbol: "", coinGeckoId: "plutonian-dao", decimals: 6, price: 0.00292102}, // Addr: 2cJgFtnqjaoiu9fKVX3fny4Z4pRzuaqfJ3PBTMk2D9ur, Notional: 0.292102 - {chain: 1, addr: "1a4fede1c16f0065b6988359bf11e8dad051daba0f615395b80faeee4ed8ad97", symbol: "POGAI", coinGeckoId: "pogai-sol", decimals: 5, price: 0.00001068}, // Addr: 2miHpQbYLPvXxC2V234jrrrtnJdejd5xW883a5ToNW3g, Notional: 0.33804206205959997 - {chain: 1, addr: "1d0b90f13cac323097379dfaa8c11f7d6cf3a7bed333042be6fe572281cdfca0", symbol: "NINJA", coinGeckoId: "shinobi-2", decimals: 9, price: 0.00026832}, // Addr: 2xP43MawHfU7pwPUmvkc6AUWg4GX8xPQLTGMkSZfCEJT, Notional: 0.0053664 - {chain: 1, addr: "1de8220d15414f8be688949bb1a2e853c45d49fb9c17b70ff4250c82c0518cb1", symbol: "GP", coinGeckoId: "graphite-protocol", decimals: 9, price: 0.052367}, // Addr: 31k88G5Mq7ptbRDf3AM13HAq6wRQHXHikR8hik7wPygk, Notional: 0.02870154520086 - {chain: 1, addr: "204cc66e5cc71f4795cfafe7b922d9e9bfe57b6ae41fb5ab6d9e65a8845ee90f", symbol: "BILLY", coinGeckoId: "billy", decimals: 6, price: 0.03587022}, // Addr: 3B5wuUrMEi5yATD7on46hKfej3pfmd7t1RKgrsN3pump, Notional: 33.11111356185942 - {chain: 1, addr: "208a634ca68fc16843f70bbfcba1726110efb9ecfeafc0ac828d749cc62fe72b", symbol: "CAPRICORN", coinGeckoId: "capricorn-2", decimals: 6, price: 0.00268008}, // Addr: 3C2SN1FjzE9MiLFFVRp7Jhkp8Gjwpk29S2TCSJ2jkHn2, Notional: 6591.287925629587 + {chain: 1, addr: "0cc10f516aaae9c14ba9471f60abd392dcd786d57354abedeee7289dd40a0a0a", symbol: "RENDER", coinGeckoId: "render-token", decimals: 8, price: 6.79}, // Addr: rndrizKT3MK1iimdxRdWabcF7Zg7AR5T4nud4EkHBof, Notional: 3557.4474665597004 + {chain: 1, addr: "0cea8ee4d02b332af25488b03f6b02b11cd5ca4b7f051ee72575c50b55addd40", symbol: "sRLY", coinGeckoId: "rally-solana", decimals: 9, price: 0.00178091}, // Addr: sRLY3migNrkC1HLgqotpvi66qGkdNedqPZ9TJpAQhyh, Notional: 24.463190070733358 + {chain: 1, addr: "0d8323c076f0e28718ca60d77e6b39cee8f23f43cfc4ff1f5852b8fc1b94a293", symbol: "BOME", coinGeckoId: "book-of-meme", decimals: 6, price: 0.00634642}, // Addr: ukHH6c7mMyiWCf1b9pnWe25TSpkDDt3H5pQZgZ74J82, Notional: 156684.5903153697 + {chain: 1, addr: "0e21542327931809efbf3b282c09eb7ef5f82c68e5c35024c97da4f89a2234c7", symbol: "DONK", coinGeckoId: "donk", decimals: 5, price: 3.37741e-10}, // Addr: xABfKiG2KCHi6keTeLycW1iK7B52wJmchSWXu3YrsDp, Notional: 0.057220080220000004 + {chain: 1, addr: "0e217f1d89397a8a2cdfcf5e46b64ac4e04206a3f396cd87b23734049eff9cae", symbol: "xALGO", coinGeckoId: "wrapped-algo", decimals: 6, price: 0.609507}, // Addr: xALGoH1zUfRmpCriy94qbfoMXHtK6NDnMKzT4Xdvgms, Notional: 15.648694826436 + {chain: 1, addr: "0e56395e3c860143802e9b94a02cc6d04f75fec72a3fbb715268355e0cd7cd89", symbol: "SLIM", coinGeckoId: "solanium", decimals: 6, price: 0.09621}, // Addr: xxxxa1sKNGwFtw2kFn8XauW9xq8hBZ5kVtcSesTT9fW, Notional: 4.1474062485 + {chain: 1, addr: "0ec49e1c77e79828f9ae8a051b662e2088c728069cedb70fef8521b94acf74f8", symbol: "", coinGeckoId: "zebec-protocol", decimals: 9, price: 0.0006357}, // Addr: zebeczgi5fSEtbpfQKVZKCJ3WgYXxjkMUkNNx7fLKAF, Notional: 200.24151701480986 + {chain: 1, addr: "1076469c1041d9e9b39fc2ede11333973b3e95732a4439207193a61cc4108d43", symbol: "JLP", coinGeckoId: "jupiter-perpetuals-liquidity-provider-token", decimals: 6, price: 4.18}, // Addr: 27G8MtK7VtTcCHkpASjSDdkWWYfoqT6ggEuKidVJidD4, Notional: 2.09 + {chain: 1, addr: "11615a73ca119d91ad275cf19659f206265356fbd4161175b6c2cee43ceb267a", symbol: "STATE", coinGeckoId: "new-world-order", decimals: 3, price: 6.284e-12}, // Addr: 2Ar2n5DJSiQuMhY4XeSzg7C5AGMezZPoLUt98VmmjsAR, Notional: 76.74926225808203 + {chain: 1, addr: "11f6454055669087f8f46c16a81e0ec3df5f68187b6bb8f1ecb954d07b7d3339", symbol: "GNOME", coinGeckoId: "gnomeland", decimals: 9, price: 0.00022658}, // Addr: 2D7jZLpUUAMboqzHMeyaxZfLWpf4JZUoR4i82Zva7sxU, Notional: 7453.942268528116 + {chain: 1, addr: "128bcb647d8bad1e7250e3b834bcfa9fd986f4d477d1bbb9054e602b11ebe061", symbol: "ETH", coinGeckoId: "wrapped-ethereum-sollet", decimals: 6, price: 831.66}, // Addr: 2FPyTwcZLUg1MDrwsyoP4D6s1tM7hAkHYRjkNb5w6Pxk, Notional: 8.3166 + {chain: 1, addr: "131fec1ab25c75e93eceea35ea3d3d82e6a3fd3d1e1f45a68ee0c14245aebaf6", symbol: "SAO", coinGeckoId: "sator", decimals: 9, price: 0.00018337}, // Addr: 2HeykdKjzHKGm2LKHw8pDYwjKPiFEoXAz74dirhUgQvq, Notional: 6270.613041692687 + {chain: 1, addr: "139fc1fba8ff288c85d542130fc2caf2caf15d4dc9fce4ac81c1de0fdd3e5be1", symbol: "KURO", coinGeckoId: "kurobi", decimals: 6, price: 0.00003161}, // Addr: 2Kc38rfQ49DFaKHQaWbijkE7fcymUMLY5guUiUsDmFfn, Notional: 0.32638237062296 + {chain: 1, addr: "16360094fd16e58867412ca58e622fe81a71fe47b8a8bf3b612e9d96a403d33b", symbol: "EUROe", coinGeckoId: "euroe-stablecoin", decimals: 6, price: 1.03}, // Addr: 2VhjJ9WxaGC3EZFwJG9BDUs9KxKCAjQY4vgd1qxgYWVg, Notional: 5.15 + {chain: 1, addr: "17e700a49c421ef60ab1bb731357d11093c809d0056852d3e9e1e6c2653c81e9", symbol: "", coinGeckoId: "plutonian-dao", decimals: 6, price: 0.00311387}, // Addr: 2cJgFtnqjaoiu9fKVX3fny4Z4pRzuaqfJ3PBTMk2D9ur, Notional: 0.31138699999999997 + {chain: 1, addr: "1a4fede1c16f0065b6988359bf11e8dad051daba0f615395b80faeee4ed8ad97", symbol: "POGAI", coinGeckoId: "pogai-sol", decimals: 5, price: 0.00000882}, // Addr: 2miHpQbYLPvXxC2V234jrrrtnJdejd5xW883a5ToNW3g, Notional: 0.2791695681054 + {chain: 1, addr: "1d0b90f13cac323097379dfaa8c11f7d6cf3a7bed333042be6fe572281cdfca0", symbol: "NINJA", coinGeckoId: "shinobi-2", decimals: 9, price: 0.00019985}, // Addr: 2xP43MawHfU7pwPUmvkc6AUWg4GX8xPQLTGMkSZfCEJT, Notional: 0.0039970000000000006 + {chain: 1, addr: "1de8220d15414f8be688949bb1a2e853c45d49fb9c17b70ff4250c82c0518cb1", symbol: "GP", coinGeckoId: "graphite-protocol", decimals: 9, price: 0.0631}, // Addr: 31k88G5Mq7ptbRDf3AM13HAq6wRQHXHikR8hik7wPygk, Notional: 0.034584136998000004 + {chain: 1, addr: "204cc66e5cc71f4795cfafe7b922d9e9bfe57b6ae41fb5ab6d9e65a8845ee90f", symbol: "BILLY", coinGeckoId: "billy", decimals: 6, price: 0.01898077}, // Addr: 3B5wuUrMEi5yATD7on46hKfej3pfmd7t1RKgrsN3pump, Notional: 17.52078551404297 + {chain: 1, addr: "208a634ca68fc16843f70bbfcba1726110efb9ecfeafc0ac828d749cc62fe72b", symbol: "CAPRICORN", coinGeckoId: "capricorn-2", decimals: 6, price: 0.00261927}, // Addr: 3C2SN1FjzE9MiLFFVRp7Jhkp8Gjwpk29S2TCSJ2jkHn2, Notional: 6473.444573906899 + {chain: 1, addr: "20dc94caa1c4d02e8d2d5d955438684fa2fc1558a68ffe079b4b813554301119", symbol: "HM", coinGeckoId: "holdium", decimals: 9, price: 0.00054704}, // Addr: 3DH8WZ6C2HdDR4J9ekYnTfai8Tx8mxn92mW8zcYmP4px, Notional: 0.00218816 {chain: 1, addr: "2109ce397c41f14a97da3d94eb68a2fcbc62fdd568e73b3d8a8c62d18a691b80", symbol: "", coinGeckoId: "arenum", decimals: 6, price: 0.00004401}, // Addr: 3Dy8KFyvpUJ8nfRCbvk4HLWjNRRzxiVhTeE9PQF9RARD, Notional: 0.007348613671980001 - {chain: 1, addr: "224b49876149714cc03053b6738ec0533f346a62459bfbad2c93c8eb54e3912f", symbol: "PISCES", coinGeckoId: "pisces", decimals: 6, price: 0.00341508}, // Addr: 3JsSsmGzjWDNe9XCw2L9vznC5JU9wSqQeB6ns5pAkPeE, Notional: 8338.820003321547 - {chain: 1, addr: "2427c13d88770be13f5907d01ba6c18f72f0241307c721a88b95f53dceada211", symbol: "MOTHER", coinGeckoId: "mother-iggy", decimals: 6, price: 0.04760669}, // Addr: 3S8qX1MsMqRbiwKg2cQyx7nis1oHMgaCuc9c4VfvVdPN, Notional: 6989.804485555732 - {chain: 1, addr: "25a608f065296572c67bdf0a455f0f0069d17a8b7a716bb1396448f1a1e249e3", symbol: "DIP", coinGeckoId: "doginthpool", decimals: 6, price: 0.00123918}, // Addr: 3XxvmED354933DwSPJuzB7SE9uiWpD1ErydDuhmbFRMk, Notional: 1.2391800000000002 - {chain: 1, addr: "2688c77a2a9c9ad17318699dcb85b3d9a23762c6e7156bc7f83b3052953293f2", symbol: "LIKE", coinGeckoId: "only1", decimals: 9, price: 0.04052777}, // Addr: 3bRTivrVsitbmCTGtqwp7hxXPsybkjn4XLNtPsHqa3zR, Notional: 0.3270591039 - {chain: 1, addr: "28baefb80baafbc803106976f26f343eb62d796b8f96a8c6b81a425b9ac0f388", symbol: "FLOOF", coinGeckoId: "floof", decimals: 1, price: 7.35628e-7}, // Addr: 3jzdrXXKxwkBk82u2eCWASZLCKoZs1LQTg87HBEAmBJw, Notional: 0.000002206884 + {chain: 1, addr: "224b49876149714cc03053b6738ec0533f346a62459bfbad2c93c8eb54e3912f", symbol: "PISCES", coinGeckoId: "pisces", decimals: 6, price: 0.00292776}, // Addr: 3JsSsmGzjWDNe9XCw2L9vznC5JU9wSqQeB6ns5pAkPeE, Notional: 7366.51201650251 + {chain: 1, addr: "2427c13d88770be13f5907d01ba6c18f72f0241307c721a88b95f53dceada211", symbol: "MOTHER", coinGeckoId: "mother-iggy", decimals: 6, price: 0.02804422}, // Addr: 3S8qX1MsMqRbiwKg2cQyx7nis1oHMgaCuc9c4VfvVdPN, Notional: 4120.503212714677 + {chain: 1, addr: "25a608f065296572c67bdf0a455f0f0069d17a8b7a716bb1396448f1a1e249e3", symbol: "DIP", coinGeckoId: "doginthpool", decimals: 6, price: 0.00154716}, // Addr: 3XxvmED354933DwSPJuzB7SE9uiWpD1ErydDuhmbFRMk, Notional: 1.5471599999999999 + {chain: 1, addr: "2688c77a2a9c9ad17318699dcb85b3d9a23762c6e7156bc7f83b3052953293f2", symbol: "LIKE", coinGeckoId: "only1", decimals: 9, price: 0.02757968}, // Addr: 3bRTivrVsitbmCTGtqwp7hxXPsybkjn4XLNtPsHqa3zR, Notional: 0.2225680176 + {chain: 1, addr: "28baefb80baafbc803106976f26f343eb62d796b8f96a8c6b81a425b9ac0f388", symbol: "FLOOF", coinGeckoId: "floof", decimals: 1, price: 3.82731e-7}, // Addr: 3jzdrXXKxwkBk82u2eCWASZLCKoZs1LQTg87HBEAmBJw, Notional: 0.000001148193 {chain: 1, addr: "2903e3b75ce4a7a17e88a51089e5ab74c0337016511bd471870e26012321a296", symbol: "", coinGeckoId: "wagmi-on-solana", decimals: 6, price: 2.87597e-7}, // Addr: 3m7A2A8HHdqmiDrjAfaddj7Hxd88FrBHA1KSoqjoELtu, Notional: 0.0000287597 - {chain: 1, addr: "2ae45f86dd41432f582f58321d9bf302527cce303a285d36d915c5fc9e87fbbe", symbol: "pepe", coinGeckoId: "pepecoin-on-sol", decimals: 9, price: 0.00028432}, // Addr: 3tS6fbLh2P8tzxXuqCiHZpZhsxJpmrR3Xb9psmypnp69, Notional: 130.7463775305069 - {chain: 1, addr: "2ccec8f92e8942182bef15efc347d609a7b2010db68d678664fae043b5f6e707", symbol: "BOGUS", coinGeckoId: "bogus", decimals: 9, price: 0.00242705}, // Addr: 41upazdWAgLjfCkLGQwGDgj2knovnpPyr4q2ZVNjifLz, Notional: 7020.566174903802 - {chain: 1, addr: "2cdc841aa0053fa5a1a39de2d59ef07fecd3e1220b6ec63b7a3ca1662f8adc6a", symbol: "SAUCE", coinGeckoId: "sauce", decimals: 9, price: 0.00007123}, // Addr: 427xvZVKbFj7ZyfFoYS9iFpNuNsrijm6T9VP8znfko9j, Notional: 0.0028491999999999996 - {chain: 1, addr: "2d36764d010cc1a6962ed97f6f9da736f885232ea23e6980142d6d9fa26156ff", symbol: "STNK", coinGeckoId: "stonks-4", decimals: 9, price: 153}, // Addr: 43VWkd99HjqkhFTZbWBpMpRhjG469nWa7x7uEsgSH7We, Notional: 153 - {chain: 1, addr: "2f64669f9f8ad5ee900c4050cf06c756f3d10a02c908f803c1e43ed7a145d3a0", symbol: "SWOLE", coinGeckoId: "swole-doge", decimals: 9, price: 0.0000068}, // Addr: 4BzxVoBQzwKoqm1dQc78r42Yby3EzAeZmMiYFdCjeu5Z, Notional: 12.661862555053911 - {chain: 1, addr: "2f982c219d581e23f410f320ee59a543dadda9d7925d6995a88982eb5e63f39f", symbol: "DADDY", coinGeckoId: "daddy-tate", decimals: 6, price: 0.062693}, // Addr: 4Cnk9EPnW5ixfLZatCPJjDB1PUtcRpVVgTQukm9epump, Notional: 0.1316553 - {chain: 1, addr: "300e2e338a5ee89798c860ff877f2e6986cdec0ecee68f23874a7cc386b34e55", symbol: "WGC", coinGeckoId: "wild-goat-coin-2", decimals: 6, price: 0.00021898}, // Addr: 4Eb7ReeT936hX25KMBfYtyP1RWDdd9iixEwGJroACeLC, Notional: 656062.2791667231 - {chain: 1, addr: "33660fff0fbce64c4da91c3b3e6e77e58d059df2e05e6c53608de170455ba938", symbol: "SCT", coinGeckoId: "solclout", decimals: 9, price: 0.00151194}, // Addr: 4Te4KJgjtnZe4aE2zne8G4NPfrPjCwDmaiEx9rKnyDVZ, Notional: 1290861.206131733 - {chain: 1, addr: "3398844e5c88d23bf0fde5120ffd5b8d81893dea2fb950ad305923b40562e58c", symbol: "JALA", coinGeckoId: "jalapeno-finance", decimals: 9, price: 0.00005233}, // Addr: 4UQgPwwcyTfELvJViUUJEa229K7RQEzCrc4Cnuxa7zxs, Notional: 444.86319096 + {chain: 1, addr: "2ae45f86dd41432f582f58321d9bf302527cce303a285d36d915c5fc9e87fbbe", symbol: "pepe", coinGeckoId: "pepecoin-on-sol", decimals: 9, price: 0.00028205}, // Addr: 3tS6fbLh2P8tzxXuqCiHZpZhsxJpmrR3Xb9psmypnp69, Notional: 138.15573921619196 + {chain: 1, addr: "2ccec8f92e8942182bef15efc347d609a7b2010db68d678664fae043b5f6e707", symbol: "BOGUS", coinGeckoId: "bogus", decimals: 9, price: 0.00064923}, // Addr: 41upazdWAgLjfCkLGQwGDgj2knovnpPyr4q2ZVNjifLz, Notional: 1877.9844575648606 + {chain: 1, addr: "2cdc841aa0053fa5a1a39de2d59ef07fecd3e1220b6ec63b7a3ca1662f8adc6a", symbol: "SAUCE", coinGeckoId: "sauce", decimals: 9, price: 0.00005642}, // Addr: 427xvZVKbFj7ZyfFoYS9iFpNuNsrijm6T9VP8znfko9j, Notional: 0.0022567999999999998 + {chain: 1, addr: "2d36764d010cc1a6962ed97f6f9da736f885232ea23e6980142d6d9fa26156ff", symbol: "STNK", coinGeckoId: "stonks-4", decimals: 9, price: 95.39}, // Addr: 43VWkd99HjqkhFTZbWBpMpRhjG469nWa7x7uEsgSH7We, Notional: 95.39 + {chain: 1, addr: "2f64669f9f8ad5ee900c4050cf06c756f3d10a02c908f803c1e43ed7a145d3a0", symbol: "SWOLE", coinGeckoId: "swole-doge", decimals: 9, price: 0.0000032}, // Addr: 4BzxVoBQzwKoqm1dQc78r42Yby3EzAeZmMiYFdCjeu5Z, Notional: 5.958523555319488 + {chain: 1, addr: "2f982c219d581e23f410f320ee59a543dadda9d7925d6995a88982eb5e63f39f", symbol: "DADDY", coinGeckoId: "daddy-tate", decimals: 6, price: 0.055267}, // Addr: 4Cnk9EPnW5ixfLZatCPJjDB1PUtcRpVVgTQukm9epump, Notional: 0.1160607 + {chain: 1, addr: "300e2e338a5ee89798c860ff877f2e6986cdec0ecee68f23874a7cc386b34e55", symbol: "WGC", coinGeckoId: "wild-goat-coin-2", decimals: 6, price: 0.00019088}, // Addr: 4Eb7ReeT936hX25KMBfYtyP1RWDdd9iixEwGJroACeLC, Notional: 557546.774804292 + {chain: 1, addr: "33660fff0fbce64c4da91c3b3e6e77e58d059df2e05e6c53608de170455ba938", symbol: "SCT", coinGeckoId: "solclout", decimals: 9, price: 0.00099435}, // Addr: 4Te4KJgjtnZe4aE2zne8G4NPfrPjCwDmaiEx9rKnyDVZ, Notional: 848954.217969687 + {chain: 1, addr: "3398844e5c88d23bf0fde5120ffd5b8d81893dea2fb950ad305923b40562e58c", symbol: "JALA", coinGeckoId: "jalapeno-finance", decimals: 9, price: 0.00004311}, // Addr: 4UQgPwwcyTfELvJViUUJEa229K7RQEzCrc4Cnuxa7zxs, Notional: 366.48293832 {chain: 1, addr: "33b8d6efc25f5766808494c4ec2c62ad1409a96266eab2113b72b3148ebede0f", symbol: "XSB", coinGeckoId: "solareum-wallet", decimals: 9, price: 0.00006227}, // Addr: 4UuGQgkD3rSeoXatXRWwRfRd21G87d5LiCfkVzNNv1Tt, Notional: 0.00031135 - {chain: 1, addr: "35fe161e6828028ece9caa2d89bcd7a1fd1bf140ad838d0c17d7b57c9b1aa238", symbol: "SNY", coinGeckoId: "synthetify-token", decimals: 6, price: 0.00446628}, // Addr: 4dmKkXNHdgYsXqBHCuMikNQWwVomZURhYvkkX5c4pQ7y, Notional: 3.573024e-8 + {chain: 1, addr: "35fe161e6828028ece9caa2d89bcd7a1fd1bf140ad838d0c17d7b57c9b1aa238", symbol: "SNY", coinGeckoId: "synthetify-token", decimals: 6, price: 0.00376307}, // Addr: 4dmKkXNHdgYsXqBHCuMikNQWwVomZURhYvkkX5c4pQ7y, Notional: 3.0104559999999996e-8 {chain: 1, addr: "360c012e23f5bf12d1e47e985682d8814e6bb1715920852acca33346708fa968", symbol: "MIM", coinGeckoId: "mim", decimals: 9, price: 0.0000013}, // Addr: 4dydh8EGNEdTz6grqnGBxpduRg55eLnwNZXoNZJetadu, Notional: 0.014634626727097002 - {chain: 1, addr: "37998ccbf2d0458b615cbcc6b1a367c4749e9fef7306622e1b1b58910120bc9a", symbol: "RAY", coinGeckoId: "raydium", decimals: 6, price: 4.87}, // Addr: 4k3Dyjzvzp8eMZWUXbBCjEvwSkkk59S5iCNLY3QrkX6R, Notional: 150457.27346041 - {chain: 1, addr: "3a0147829f94ff731beb78f4bf79f8247eb6db6ff78cbdbd778004547c3cfb15", symbol: "", coinGeckoId: "playground-waves-floor-index", decimals: 2, price: 0.111419}, // Addr: 4uRn7vxRPWYP4HuAa4UNXwEPLRL8oQ71YByMhr6yBnL4, Notional: 2.116961 - {chain: 1, addr: "3a5dbacb04d71ef866691d531287d96c7c36bfdf444418fc74a4dd1b7017f76b", symbol: "WYNN", coinGeckoId: "anita-max-wynn", decimals: 6, price: 0.00180999}, // Addr: 4vqYQTjmKjxrWGtbL2tVkbAU1EVAz9JwcYtd2VE3PbVU, Notional: 162.8991 - {chain: 1, addr: "3af4e2d8b5cb7182c097ad3b67e18e9ff9f28ad4a1ca8161809e1ff94e0e2216", symbol: "FATGF", coinGeckoId: "fatgf", decimals: 6, price: 0.0009219}, // Addr: 4y9E3tJpGNzRr1592oWTPECgyp2VDSc1Bf3DqAm5FZsK, Notional: 0.0009219 - {chain: 1, addr: "3b15c6089ac9e1722434f64313f16131fa6dab386951f47f2a6f02f3a9ab602a", symbol: "CTUS", coinGeckoId: "contractus", decimals: 9, price: 0.00282635}, // Addr: 4yeK2cCyxNNz28fVqEbkLYNCb1T9qPadsuJWeZ44Evcq, Notional: 339956.62988095183 - {chain: 1, addr: "3b1f93f67db7d561ba257575f5935a4b2b8a7f0365015043ba2ebab4d94abeb8", symbol: "EGG", coinGeckoId: "egg", decimals: 9, price: 0.00002117}, // Addr: 4ynyx6BzY2XGFgjjun9Cruj1bSRo8FLsAqNnPsW6jDsu, Notional: 0.00146073 - {chain: 1, addr: "3ba8d09f68b3cc2546ac682aafba3d585690ebba80c218a9cc3807524ecc5957", symbol: "", coinGeckoId: "apexit-finance", decimals: 9, price: 0.00427533}, // Addr: 51tMb3zBKDiQhNwGqpgwbavaGH54mk8fXFzxTc1xnasg, Notional: 0.012825989999999999 - {chain: 1, addr: "3df04a3638c2fb63cdbe8dfef12a3ac5398999227bcab5f97742f11c9bdb75ff", symbol: "DOLLAR", coinGeckoId: "dollar-2", decimals: 6, price: 0.00037628}, // Addr: 5AnPDx9GposBi9jSW2dFfE5QQD3FmXbudoquMNDxpump, Notional: 11120.519854882916 - {chain: 1, addr: "3ffd20f06c83bba88002f87f9d56050a5ef941fbbb0ea0293c829a82f11e3891", symbol: "APYS", coinGeckoId: "apyswap", decimals: 9, price: 0.00636373}, // Addr: 5JnZ667P3VcjDinkJFysWh2K2KtViy63FZ3oL5YghEhW, Notional: 0.43909737 - {chain: 1, addr: "4099261906e4d99a6926404cb79d4a2de516b4aef140e4bf48d35b4ba22654e4", symbol: "ACS", coinGeckoId: "access-protocol", decimals: 6, price: 0.00198343}, // Addr: 5MAYDfq5yxtudAhtfyuMBuHZjgAbaS9tbEyEQYAhDS5y, Notional: 119.08031561257637 - {chain: 1, addr: "41f6388b9c6a78895d16cb6f8ccb8705e0d68640c14d908ef943fb13d693cbcf", symbol: "SIGMA", coinGeckoId: "sigma", decimals: 6, price: 0.04735381}, // Addr: 5SVG3T9CNQsm2kEwzbRq6hASqh1oGfjqTtLXYUibpump, Notional: 2.3676905 - {chain: 1, addr: "4262f09434e938b2714803d3aa425d1d543a735ba324109087760d83deae653d", symbol: "SPWN", coinGeckoId: "bitspawn", decimals: 9, price: 0.00004114}, // Addr: 5U9QqCPhqXAJcEv9uyzFJd5zhN93vuPk1aNNkXnUfPnt, Notional: 0.0041140000000000005 - {chain: 1, addr: "430badff7f2921f4811389b1c6d633b143f0fddcc7b5b2750e906bb8852b174b", symbol: "HER", coinGeckoId: "her-ai", decimals: 6, price: 0.00598314}, // Addr: 5WieRrJ5oFthgxaH4nCEkwJiBTxuRpEn9qmFRkVzkc98, Notional: 0.05983139999999999 - {chain: 1, addr: "45a5161476cc9df6ef8583b581a3111b4416ebcea65f4eca5bb961124c3399df", symbol: "", coinGeckoId: "xhashtag", decimals: 6, price: 0.03031135}, // Addr: 5gs8nf4wojB5EXgDUWNLwXpknzgV2YWDhveAeBZpVLbp, Notional: 30179.11949932296 - {chain: 1, addr: "46dd37dd6a92fc21467d58d83c526393cd94492b97fec5124970fc4ea5a68be6", symbol: "BRAWL", coinGeckoId: "bitbrawl", decimals: 9, price: 0.00043084}, // Addr: 5mdBkZ4dTP94SE7PyiuWseTDAd1kYxSk6oYaWB7186s7, Notional: 121985.85788243593 - {chain: 1, addr: "4757899fb8bedba28778aacd67e568e73470cce90bcd532b6cb618297628824e", symbol: "INF", coinGeckoId: "socean-staked-sol", decimals: 9, price: 280.4}, // Addr: 5oVNBeEEQvYi1cX3ir8Dx5n1P7pdxydbGF2X4TxVusJm, Notional: 281.674645124 - {chain: 1, addr: "485493b637792cca16fe9d53fc4879c23dbf52cf6d9af4e61fe92df15c17c98d", symbol: "", coinGeckoId: "bamboo-coin", decimals: 9, price: 0.00000342}, // Addr: 5sM9xxcBTM9rWza6nEgq2cShA87JjTBx1Cu82LjgmaEg, Notional: 1.026 - {chain: 1, addr: "48972c3e59cc0c7a094c2948f847381cfef470e1ddf0711f0c858070711876f3", symbol: "WAG", coinGeckoId: "waggle-network", decimals: 9, price: 0.00082668}, // Addr: 5tN42n9vMi6ubp67Uy4NnmM5DMZYN8aS8GeB3bEDHr6E, Notional: 0.004216068 - {chain: 1, addr: "4a05e1f7f53477602c239f1a2b8da4277ccd279ff26128cb361c3791b5a9156c", symbol: "Fronk", coinGeckoId: "fronk", decimals: 5, price: 1.0002e-8}, // Addr: 5yxNbU8DgYJZNi3mPD9rs4XLh9ckXrhPjJ5VCujUWg5H, Notional: 189.9004006820549 - {chain: 1, addr: "4a0b628dff0f5cdd497907e62510e77277360c2e9dc2081898dd62e4ffe39caf", symbol: "PONKE", coinGeckoId: "ponke", decimals: 9, price: 0.533725}, // Addr: 5z3EqYQo9HiCEs3R84RCDMu2n7anpDMxRhdK8PSWmrRC, Notional: 6.176748747811249 - {chain: 1, addr: "4a6b1a6b92df4ed3059e120bd0e5e4b6a97fd0e8db832c163a15fd284e4d46c7", symbol: "DILLY", coinGeckoId: "dilly", decimals: 9, price: 0.0000675}, // Addr: 61VtkXr9mRXtrFYe2T9arWYX52sbJnkAUQgfjGuCzox2, Notional: 228.05499777301551 - {chain: 1, addr: "4ae3d320820544fffa2e6dae60f8ed2bc3426d8de3d7f77ddf350c18fd6b3194", symbol: "GIGA", coinGeckoId: "gigachad-2", decimals: 5, price: 0.03800316}, // Addr: 63LfDmNb3MQ8mw9MtZ2To9bEA2M71kZUUGq5tiJxcqj9, Notional: 10715.274914010888 - {chain: 1, addr: "518ecf30942036e11b4eb4f2f5a05d32661f9ada0a6a4402c5df098ea6c4fbce", symbol: "wHAPI", coinGeckoId: "hapi", decimals: 9, price: 12.88}, // Addr: 6VNKqgz9hk7zRShTFdg5AnkfKwZUcojzwAkzxSH3bnUm, Notional: 0.38746285760000004 - {chain: 1, addr: "5468187df701e428898565f1c522b352ad481d0dcb40d8b6e1036ba153e5e3af", symbol: "pog", coinGeckoId: "pog", decimals: 6, price: 0.00121212}, // Addr: 6gVJwfHxWov8HxdAZ4v4tt2RpZZst6du74y4bUCdpump, Notional: 0.12727259999999999 - {chain: 1, addr: "547b309eace670a9af4c6da12402ddbbc60d43c10e2c177b9533bdbc1888576f", symbol: "BSKT", coinGeckoId: "basket", decimals: 5, price: 0.00000242}, // Addr: 6gnCPhXtLnUD76HjQuSYPENLSZdG8RvDB1pTLM5aLSJA, Notional: 193394.55396348378 - {chain: 1, addr: "558bfd9cf2fcdc18de6a9463c3d2a372e961c63264900d3d3cb5d86560c4655b", symbol: "SAIL", coinGeckoId: "sail", decimals: 6, price: 0.00594667}, // Addr: 6kwTqmdQkJd8qRr9RjSnUX9XJ24RmJRSrU1rsragP97Y, Notional: 0.03568002 - {chain: 1, addr: "560d05641b74bbada05fdd6b3fd731b5df7cd417fd1d8cf129476a7aaa55b308", symbol: "", coinGeckoId: "wrapped-busd-allbridge-from-bsc", decimals: 9, price: 1.004}, // Addr: 6nuaX3ogrr2CaoAPjtaKHAoBNWok32BMcRozuf32s2QF, Notional: 259.2621460666 - {chain: 1, addr: "56405db9a54ee121b5acf6d28c359e5b50caae6bcd6439d814696ea95a99a3e9", symbol: "RETARDIO", coinGeckoId: "retardio", decimals: 6, price: 0.098538}, // Addr: 6ogzHhzdrQr9Pgv6hZ2MNze7UrzBMAFyBBWUYp1Fhitx, Notional: 70.572539381916 - {chain: 1, addr: "58d2e009e5166d2e61063ed79f0fc83cdca913520383969208143c66ca0d2d8d", symbol: "Chud", coinGeckoId: "chudjak", decimals: 6, price: 0.01219591}, // Addr: 6yjNqPzTSanBWSa6dxVEgTjePXBrZ2FoHLDQwYwEsyM6, Notional: 13200.578828163245 - {chain: 1, addr: "59174309f88fbd80970c5b2e2e69708a0d6e76eb4cf35ebf801bceae476211a6", symbol: "CUTE", coinGeckoId: "pepe-uwu", decimals: 7, price: 1.7803e-8}, // Addr: 6zmrmNUGdRwrqcchshVkBgAyLhLwZ7QvJRQiKktqVQLV, Notional: 6384.828888152696 + {chain: 1, addr: "37998ccbf2d0458b615cbcc6b1a367c4749e9fef7306622e1b1b58910120bc9a", symbol: "RAY", coinGeckoId: "raydium", decimals: 6, price: 4.85}, // Addr: 4k3Dyjzvzp8eMZWUXbBCjEvwSkkk59S5iCNLY3QrkX6R, Notional: 148193.86942089998 + {chain: 1, addr: "3a0147829f94ff731beb78f4bf79f8247eb6db6ff78cbdbd778004547c3cfb15", symbol: "", coinGeckoId: "playground-waves-floor-index", decimals: 2, price: 0.070205}, // Addr: 4uRn7vxRPWYP4HuAa4UNXwEPLRL8oQ71YByMhr6yBnL4, Notional: 1.333895 + {chain: 1, addr: "3a5dbacb04d71ef866691d531287d96c7c36bfdf444418fc74a4dd1b7017f76b", symbol: "WYNN", coinGeckoId: "anita-max-wynn", decimals: 6, price: 0.0020306}, // Addr: 4vqYQTjmKjxrWGtbL2tVkbAU1EVAz9JwcYtd2VE3PbVU, Notional: 182.754 + {chain: 1, addr: "3af4e2d8b5cb7182c097ad3b67e18e9ff9f28ad4a1ca8161809e1ff94e0e2216", symbol: "FATGF", coinGeckoId: "fatgf", decimals: 6, price: 0.00075766}, // Addr: 4y9E3tJpGNzRr1592oWTPECgyp2VDSc1Bf3DqAm5FZsK, Notional: 0.00075766 + {chain: 1, addr: "3b15c6089ac9e1722434f64313f16131fa6dab386951f47f2a6f02f3a9ab602a", symbol: "CTUS", coinGeckoId: "contractus", decimals: 9, price: 0.00297575}, // Addr: 4yeK2cCyxNNz28fVqEbkLYNCb1T9qPadsuJWeZ44Evcq, Notional: 357958.7183108883 + {chain: 1, addr: "3b1f93f67db7d561ba257575f5935a4b2b8a7f0365015043ba2ebab4d94abeb8", symbol: "EGG", coinGeckoId: "egg", decimals: 9, price: 0.00001776}, // Addr: 4ynyx6BzY2XGFgjjun9Cruj1bSRo8FLsAqNnPsW6jDsu, Notional: 0.00122544 + {chain: 1, addr: "3ba8d09f68b3cc2546ac682aafba3d585690ebba80c218a9cc3807524ecc5957", symbol: "", coinGeckoId: "apexit-finance", decimals: 9, price: 0.00288818}, // Addr: 51tMb3zBKDiQhNwGqpgwbavaGH54mk8fXFzxTc1xnasg, Notional: 0.00866454 + {chain: 1, addr: "3df04a3638c2fb63cdbe8dfef12a3ac5398999227bcab5f97742f11c9bdb75ff", symbol: "DOLLAR", coinGeckoId: "dollar-2", decimals: 6, price: 0.00036931}, // Addr: 5AnPDx9GposBi9jSW2dFfE5QQD3FmXbudoquMNDxpump, Notional: 9743.379347797812 + {chain: 1, addr: "3ffd20f06c83bba88002f87f9d56050a5ef941fbbb0ea0293c829a82f11e3891", symbol: "APYS", coinGeckoId: "apyswap", decimals: 9, price: 0.00334385}, // Addr: 5JnZ667P3VcjDinkJFysWh2K2KtViy63FZ3oL5YghEhW, Notional: 0.23072565 + {chain: 1, addr: "4099261906e4d99a6926404cb79d4a2de516b4aef140e4bf48d35b4ba22654e4", symbol: "ACS", coinGeckoId: "access-protocol", decimals: 6, price: 0.00187431}, // Addr: 5MAYDfq5yxtudAhtfyuMBuHZjgAbaS9tbEyEQYAhDS5y, Notional: 112.52901607609445 + {chain: 1, addr: "41f6388b9c6a78895d16cb6f8ccb8705e0d68640c14d908ef943fb13d693cbcf", symbol: "SIGMA", coinGeckoId: "sigma", decimals: 6, price: 0.03552318}, // Addr: 5SVG3T9CNQsm2kEwzbRq6hASqh1oGfjqTtLXYUibpump, Notional: 1.776159 + {chain: 1, addr: "4262f09434e938b2714803d3aa425d1d543a735ba324109087760d83deae653d", symbol: "SPWN", coinGeckoId: "bitspawn", decimals: 9, price: 0.00001587}, // Addr: 5U9QqCPhqXAJcEv9uyzFJd5zhN93vuPk1aNNkXnUfPnt, Notional: 0.0015869999999999999 + {chain: 1, addr: "430badff7f2921f4811389b1c6d633b143f0fddcc7b5b2750e906bb8852b174b", symbol: "HER", coinGeckoId: "her-ai", decimals: 6, price: 0.00329219}, // Addr: 5WieRrJ5oFthgxaH4nCEkwJiBTxuRpEn9qmFRkVzkc98, Notional: 0.0329219 + {chain: 1, addr: "45a5161476cc9df6ef8583b581a3111b4416ebcea65f4eca5bb961124c3399df", symbol: "", coinGeckoId: "xhashtag", decimals: 6, price: 0.0325533}, // Addr: 5gs8nf4wojB5EXgDUWNLwXpknzgV2YWDhveAeBZpVLbp, Notional: 32411.28919686223 + {chain: 1, addr: "46dd37dd6a92fc21467d58d83c526393cd94492b97fec5124970fc4ea5a68be6", symbol: "BRAWL", coinGeckoId: "bitbrawl", decimals: 9, price: 0.00038547}, // Addr: 5mdBkZ4dTP94SE7PyiuWseTDAd1kYxSk6oYaWB7186s7, Notional: 108734.16404000985 + {chain: 1, addr: "4757899fb8bedba28778aacd67e568e73470cce90bcd532b6cb618297628824e", symbol: "INF", coinGeckoId: "socean-staked-sol", decimals: 9, price: 241.81}, // Addr: 5oVNBeEEQvYi1cX3ir8Dx5n1P7pdxydbGF2X4TxVusJm, Notional: 242.9092223161 + {chain: 1, addr: "485493b637792cca16fe9d53fc4879c23dbf52cf6d9af4e61fe92df15c17c98d", symbol: "", coinGeckoId: "bamboo-coin", decimals: 9, price: 0.00000349}, // Addr: 5sM9xxcBTM9rWza6nEgq2cShA87JjTBx1Cu82LjgmaEg, Notional: 1.047 + {chain: 1, addr: "48972c3e59cc0c7a094c2948f847381cfef470e1ddf0711f0c858070711876f3", symbol: "WAG", coinGeckoId: "waggle-network", decimals: 9, price: 0.00062952}, // Addr: 5tN42n9vMi6ubp67Uy4NnmM5DMZYN8aS8GeB3bEDHr6E, Notional: 0.0032105519999999993 + {chain: 1, addr: "4a05e1f7f53477602c239f1a2b8da4277ccd279ff26128cb361c3791b5a9156c", symbol: "Fronk", coinGeckoId: "fronk", decimals: 5, price: 7.93e-9}, // Addr: 5yxNbU8DgYJZNi3mPD9rs4XLh9ckXrhPjJ5VCujUWg5H, Notional: 151.89362524438266 + {chain: 1, addr: "4a0b628dff0f5cdd497907e62510e77277360c2e9dc2081898dd62e4ffe39caf", symbol: "PONKE", coinGeckoId: "ponke", decimals: 9, price: 0.299656}, // Addr: 5z3EqYQo9HiCEs3R84RCDMu2n7anpDMxRhdK8PSWmrRC, Notional: 3.4678904356627993 + {chain: 1, addr: "4a6b1a6b92df4ed3059e120bd0e5e4b6a97fd0e8db832c163a15fd284e4d46c7", symbol: "DILLY", coinGeckoId: "dilly", decimals: 9, price: 0.00003904}, // Addr: 61VtkXr9mRXtrFYe2T9arWYX52sbJnkAUQgfjGuCzox2, Notional: 131.90025352679297 + {chain: 1, addr: "4ae3d320820544fffa2e6dae60f8ed2bc3426d8de3d7f77ddf350c18fd6b3194", symbol: "GIGA", coinGeckoId: "gigachad-2", decimals: 5, price: 0.069726}, // Addr: 63LfDmNb3MQ8mw9MtZ2To9bEA2M71kZUUGq5tiJxcqj9, Notional: 19000.30683278778 + {chain: 1, addr: "518ecf30942036e11b4eb4f2f5a05d32661f9ada0a6a4402c5df098ea6c4fbce", symbol: "wHAPI", coinGeckoId: "hapi", decimals: 9, price: 9.68}, // Addr: 6VNKqgz9hk7zRShTFdg5AnkfKwZUcojzwAkzxSH3bnUm, Notional: 0.2911987936 + {chain: 1, addr: "5468187df701e428898565f1c522b352ad481d0dcb40d8b6e1036ba153e5e3af", symbol: "pog", coinGeckoId: "pog", decimals: 6, price: 0.00036143}, // Addr: 6gVJwfHxWov8HxdAZ4v4tt2RpZZst6du74y4bUCdpump, Notional: 0.03795015 + {chain: 1, addr: "547b309eace670a9af4c6da12402ddbbc60d43c10e2c177b9533bdbc1888576f", symbol: "BSKT", coinGeckoId: "basket", decimals: 5, price: 0.00000153}, // Addr: 6gnCPhXtLnUD76HjQuSYPENLSZdG8RvDB1pTLM5aLSJA, Notional: 124236.15613214427 + {chain: 1, addr: "558bfd9cf2fcdc18de6a9463c3d2a372e961c63264900d3d3cb5d86560c4655b", symbol: "SAIL", coinGeckoId: "sail", decimals: 6, price: 0.00675815}, // Addr: 6kwTqmdQkJd8qRr9RjSnUX9XJ24RmJRSrU1rsragP97Y, Notional: 0.0405489 + {chain: 1, addr: "560d05641b74bbada05fdd6b3fd731b5df7cd417fd1d8cf129476a7aaa55b308", symbol: "", coinGeckoId: "wrapped-busd-allbridge-from-bsc", decimals: 9, price: 1.003}, // Addr: 6nuaX3ogrr2CaoAPjtaKHAoBNWok32BMcRozuf32s2QF, Notional: 259.00391683744994 + {chain: 1, addr: "56405db9a54ee121b5acf6d28c359e5b50caae6bcd6439d814696ea95a99a3e9", symbol: "RETARDIO", coinGeckoId: "retardio", decimals: 6, price: 0.06253}, // Addr: 6ogzHhzdrQr9Pgv6hZ2MNze7UrzBMAFyBBWUYp1Fhitx, Notional: 44.783747260460004 + {chain: 1, addr: "58d2e009e5166d2e61063ed79f0fc83cdca913520383969208143c66ca0d2d8d", symbol: "Chud", coinGeckoId: "chudjak", decimals: 6, price: 0.00986392}, // Addr: 6yjNqPzTSanBWSa6dxVEgTjePXBrZ2FoHLDQwYwEsyM6, Notional: 10793.343133966682 + {chain: 1, addr: "59174309f88fbd80970c5b2e2e69708a0d6e76eb4cf35ebf801bceae476211a6", symbol: "CUTE", coinGeckoId: "pepe-uwu", decimals: 7, price: 6.6569e-8}, // Addr: 6zmrmNUGdRwrqcchshVkBgAyLhLwZ7QvJRQiKktqVQLV, Notional: 23874.16021206745 {chain: 1, addr: "5970e12d014491b2ca2f4b15f6348ff255076d62422140f01e3d955896ccc619", symbol: "Leancoin", coinGeckoId: "leancoin", decimals: 9, price: 0.00004726}, // Addr: 7297kX7SEZ1do223VsjTAC2MS9gLxPJoxFs9UMwiG4oS, Notional: 1.22876e-11 - {chain: 1, addr: "5be23d7c881e445a9387e65ee9b2ba25a1ffa3429008b591784fbe6300091d06", symbol: "SLERF", coinGeckoId: "slerf", decimals: 9, price: 0.259119}, // Addr: 7BgBvyjrZX1YKz4oh9mjb8ZScatkkwb8DzFx7LoiVkM3, Notional: 75.10189849456204 - {chain: 1, addr: "5c9e9d5fa309864acd7d8118d326313cde7b86df18e197924a03186ffe9f3d7a", symbol: "SILLY", coinGeckoId: "silly-dragon", decimals: 9, price: 0.01408905}, // Addr: 7EYnhQoR9YM3N7UoaKRoA44Uy8JeaZV3qyouov87awMs, Notional: 59.72914912154137 - {chain: 1, addr: "5d0b159affcbccf165c09bc2f5d4bafb4aa6345af793b9b3222daa40293a950d", symbol: "POPCAT", coinGeckoId: "popcat", decimals: 9, price: 1.14}, // Addr: 7GCihgDB8fe6KNjn2MYtkzZcRjQy3t9GHdC8uHYmW2hr, Notional: 70641.6720360942 - {chain: 1, addr: "61926627585b9be4953991b827eb7d0ecc061afe1bf9a0a9079e009ccd695ae7", symbol: "LIBRA", coinGeckoId: "libra-4", decimals: 6, price: 0.00273664}, // Addr: 7Zt2KUh5mkpEpPGcNcFy51aGkh9Ycb5ELcqRH1n2GmAe, Notional: 6776.424238854519 - {chain: 1, addr: "6271cb7119476b9dce00d815c8ff315fc8bf7d2848633d34942adfd535f2defe", symbol: "stSOL", coinGeckoId: "lido-staked-sol", decimals: 9, price: 270.43}, // Addr: 7dHbWXmci3dT8UFYWYZweBLXgycu7Y3iL6trKn1Y7ARj, Notional: 169191.9863843929 - {chain: 1, addr: "6386d5114f2b5a344f6265cb7e334e78ae569abd44a39b718d8e02fc487d9c02", symbol: "CAT", coinGeckoId: "catcoin-cash", decimals: 3, price: 2.84432e-10}, // Addr: 7hWcHohzwtLddDUG81H2PkWq6KEkMtSDNkYXsso18Fy3, Notional: 85.08761301936856 - {chain: 1, addr: "63abd0967076f58ba2edadb41f10719df1354abe118f29a8f30ee6639474b947", symbol: "", coinGeckoId: "stepn", decimals: 9, price: 0.207966}, // Addr: 7i5KKsX2weiTkry7jA4ZwSuXGhs5eJBEjY8vVxR4pfRx, Notional: 464.4453915849416 - {chain: 1, addr: "63ef9d2e6be295552062ac55bdd693bea2bb7f6e6221edc9d308d843d293650b", symbol: "SOLR", coinGeckoId: "solrazr", decimals: 6, price: 0.02774101}, // Addr: 7j7H7sgsnNDeCngAPjpaCN4aaaru4HS7NAFYSEUyzJ3k, Notional: 0.02774101 - {chain: 1, addr: "6752055c20b3e9d8746656ddf73855507f87ab6d87523e4c76a7fa36096a99eb", symbol: "SAMO", coinGeckoId: "samoyedcoin", decimals: 9, price: 0.00910973}, // Addr: 7xKXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgAsU, Notional: 3.680967501464492 - {chain: 1, addr: "676179b0b67070a1d3e299cac3bddc85e6b6b60600a99ddceae0f96b521cae33", symbol: "DOGEVERSE", coinGeckoId: "dogeverse", decimals: 8, price: 0.00001402}, // Addr: 7xZCdhj7rGhnKndRpU3NHgZhbFMkPLP2ErDr1AS8Chsx, Notional: 107.42869864 - {chain: 1, addr: "689ac099ef657e5d3b7efaf1e36ab8b897e2746232d8a9261b3e49b35c1dead4", symbol: "xUSD", coinGeckoId: "synthetic-usd", decimals: 6, price: 0.592755}, // Addr: 83LGLCm7QKpYZbX8q4W2kYWbtt8NJBwbVwEepzkVnJ9y, Notional: 5.909526098715 - {chain: 1, addr: "6927fdc01ea906f96d7137874cdd7adad00ca35764619310e54196c781d84d5b", symbol: "W", coinGeckoId: "wormhole", decimals: 6, price: 0.318945}, // Addr: 85VBFQZC9TZkfaptBWjvUw7YbZjy52A6mjtPGjstQAmQ, Notional: 56884.71680452407 - {chain: 1, addr: "69302bef50efd86a9bc1c2ac763ff56633e9fda1709eb0b858088e9cfbdcfe0f", symbol: "Rizzmas", coinGeckoId: "rizzmas", decimals: 6, price: 0.00003163}, // Addr: 85cQsFgbi8mBZxiPppbpPXuV7j1hA8tBwhjF4gKW6mHg, Notional: 17.3041404 - {chain: 1, addr: "6afc09bb2ca898b2a734540d93a61ea2dd46ab6bd318a3e3283c8fbe86b93f3e", symbol: "LEO", coinGeckoId: "leo-2", decimals: 6, price: 0.00315803}, // Addr: 8Cd7wXoPb5Yt9cUGtmHNqAEmpMDrhfcVqnGbLC48b8Qm, Notional: 7103.239420346965 - {chain: 1, addr: "6b054395432c64d8250648371121f271fc3b8e36621384b9e91956bf02307c13", symbol: "DOKI", coinGeckoId: "doki", decimals: 6, price: 0.00042}, // Addr: 8CmHC7Y2715VFaMkMZMwWDqRYQwPLAsM57Xiu3Ho4TjG, Notional: 15.999957058680002 - {chain: 1, addr: "6cccc33e6627899bd00d679cca0b56d788a1861b8de1ea3691e870710b92447c", symbol: "LOCKIN", coinGeckoId: "lock-in", decimals: 9, price: 0.04562095}, // Addr: 8Ki8DpuWNxu9VsS3kQbarsCWMcFGWkzzA8pUPto9zBd5, Notional: 42.176501468137026 - {chain: 1, addr: "6dbb85629db6a38eeb2fec793974b4c7e9c5fdc9e70165303b4f73106e5e62ba", symbol: "", coinGeckoId: "rope-token", decimals: 9, price: 0.02526629}, // Addr: 8PMHT4swUMtBzgHnh5U564N5sjPSiUz2cjEQzFnnP1Fo, Notional: 0.02526629 - {chain: 1, addr: "73512a31b0ae74aae6fbce469044131a230a122b1ea6f4af3a4e93c9158b538e", symbol: "JOWNES", coinGeckoId: "alux-jownes", decimals: 6, price: 0.0002687}, // Addr: 8m9fjYycXAFva1kScttQgsESVZT7yELhjZASqfHBuMa5, Notional: 23.8211865984846 - {chain: 1, addr: "7589fb28d63e11a5f134a97a6bc85399e6cbe2fddb268d496f91204d5271ff05", symbol: "GRAPE", coinGeckoId: "grape-2", decimals: 6, price: 0.00077759}, // Addr: 8upjSpvjcdpuzhfR1zriwg5NXkwDruejqNE9WNbPRtyA, Notional: 0.018040088 - {chain: 1, addr: "75fa185aaff1c781b07269a4dfd7849add90a6db207bf61cff506c9b3d525376", symbol: "GME", coinGeckoId: "gme", decimals: 9, price: 0.00493014}, // Addr: 8wXtPeU6557ETkp9WHFY1n1EcU6NxDvbAggHGsMYiHsB, Notional: 9998.758294655761 - {chain: 1, addr: "7618e3a4b6365218d0473a17c3386761b449f05d4e5dc213bd7966edde409f24", symbol: "SAGIT", coinGeckoId: "sagittarius", decimals: 6, price: 0.00282802}, // Addr: 8x17zMmVjJxqswjX4hNpxVPc7Tr5UabVJF3kv8TKq8Y3, Notional: 7028.931358099046 - {chain: 1, addr: "766d8eac4c0ae9f5d006f7a74ca87eaa78b50411e9385154b12fcc17c21b41d3", symbol: "KITTY", coinGeckoId: "kitty-ai", decimals: 6, price: 0.0003578}, // Addr: 8yJ15ee2AUQmwbWPxXLTTeBTzyMGn4MtSRKMqVHw1J1G, Notional: 10.734 - {chain: 1, addr: "7747dce1ae5735f0fe877af40fc4b972847edabdb0abb1e04a432c4025606496", symbol: "MONKEY", coinGeckoId: "monkey", decimals: 1, price: 7.53173e-10}, // Addr: 92d5AncUVELq79xqLWNQ5Zoxz7fn9XHwijYswYWFrKtR, Notional: 4.959682887061473 - {chain: 1, addr: "777c026899a52a4c61329b0a098e74fbcd720d34665a41782bca2e2713410082", symbol: "ZERO", coinGeckoId: "analysoor", decimals: 9, price: 0.158288}, // Addr: 93RC484oMK5T9H89rzT5qiAXKHGP9jscXfFfrihNbe57, Notional: 0.158288 - {chain: 1, addr: "78404f497a9523d5d2530469f1d76f4ac5cfafad2423341f61aa08021efc459c", symbol: "$POPO", coinGeckoId: "popo-pepe-s-dog", decimals: 9, price: 0.00003736}, // Addr: 96QoNkZLTKH7Gecf6dKMRXBQXW1wqh378uF9pnTejgAw, Notional: 4.086376944943625 + {chain: 1, addr: "5be23d7c881e445a9387e65ee9b2ba25a1ffa3429008b591784fbe6300091d06", symbol: "SLERF", coinGeckoId: "slerf", decimals: 9, price: 0.16792}, // Addr: 7BgBvyjrZX1YKz4oh9mjb8ZScatkkwb8DzFx7LoiVkM3, Notional: 48.669185953970405 + {chain: 1, addr: "5c9e9d5fa309864acd7d8118d326313cde7b86df18e197924a03186ffe9f3d7a", symbol: "SILLY", coinGeckoId: "silly-dragon", decimals: 9, price: 0.00988318}, // Addr: 7EYnhQoR9YM3N7UoaKRoA44Uy8JeaZV3qyouov87awMs, Notional: 41.8987747232805 + {chain: 1, addr: "5d0b159affcbccf165c09bc2f5d4bafb4aa6345af793b9b3222daa40293a950d", symbol: "POPCAT", coinGeckoId: "popcat", decimals: 9, price: 0.732817}, // Addr: 7GCihgDB8fe6KNjn2MYtkzZcRjQy3t9GHdC8uHYmW2hr, Notional: 67948.15053765647 + {chain: 1, addr: "61926627585b9be4953991b827eb7d0ecc061afe1bf9a0a9079e009ccd695ae7", symbol: "LIBRA", coinGeckoId: "libra-4", decimals: 6, price: 0.00256888}, // Addr: 7Zt2KUh5mkpEpPGcNcFy51aGkh9Ycb5ELcqRH1n2GmAe, Notional: 6824.284193591056 + {chain: 1, addr: "6270a9646bd0d4a8daeb0deba12c396b88fa79f4bf3c16f844ed91af004a4723", symbol: "GCR", coinGeckoId: "golden-celestial-ratio", decimals: 9, price: 0.00046471}, // Addr: 7dGbPgUxKpB5qWiLRKcTQSC3om1fPzUpgGAFfwej9hXx, Notional: 17853.22878 + {chain: 1, addr: "6271cb7119476b9dce00d815c8ff315fc8bf7d2848633d34942adfd535f2defe", symbol: "stSOL", coinGeckoId: "lido-staked-sol", decimals: 9, price: 231.29}, // Addr: 7dHbWXmci3dT8UFYWYZweBLXgycu7Y3iL6trKn1Y7ARj, Notional: 144704.4134557787 + {chain: 1, addr: "6386d5114f2b5a344f6265cb7e334e78ae569abd44a39b718d8e02fc487d9c02", symbol: "CAT", coinGeckoId: "catcoin-cash", decimals: 3, price: 1.96287e-10}, // Addr: 7hWcHohzwtLddDUG81H2PkWq6KEkMtSDNkYXsso18Fy3, Notional: 58.71910437901782 + {chain: 1, addr: "63abd0967076f58ba2edadb41f10719df1354abe118f29a8f30ee6639474b947", symbol: "", coinGeckoId: "stepn", decimals: 9, price: 0.151428}, // Addr: 7i5KKsX2weiTkry7jA4ZwSuXGhs5eJBEjY8vVxR4pfRx, Notional: 349.643391673253 + {chain: 1, addr: "63ef9d2e6be295552062ac55bdd693bea2bb7f6e6221edc9d308d843d293650b", symbol: "SOLR", coinGeckoId: "solrazr", decimals: 6, price: 0.01862582}, // Addr: 7j7H7sgsnNDeCngAPjpaCN4aaaru4HS7NAFYSEUyzJ3k, Notional: 0.01862582 + {chain: 1, addr: "6752055c20b3e9d8746656ddf73855507f87ab6d87523e4c76a7fa36096a99eb", symbol: "SAMO", coinGeckoId: "samoyedcoin", decimals: 9, price: 0.00697695}, // Addr: 7xKXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgAsU, Notional: 2.8191753443123657 + {chain: 1, addr: "676179b0b67070a1d3e299cac3bddc85e6b6b60600a99ddceae0f96b521cae33", symbol: "DOGEVERSE", coinGeckoId: "dogeverse", decimals: 8, price: 0.00001076}, // Addr: 7xZCdhj7rGhnKndRpU3NHgZhbFMkPLP2ErDr1AS8Chsx, Notional: 82.44884432 + {chain: 1, addr: "689ac099ef657e5d3b7efaf1e36ab8b897e2746232d8a9261b3e49b35c1dead4", symbol: "xUSD", coinGeckoId: "synthetic-usd", decimals: 6, price: 0.59214}, // Addr: 83LGLCm7QKpYZbX8q4W2kYWbtt8NJBwbVwEepzkVnJ9y, Notional: 5.90339479902 + {chain: 1, addr: "6927fdc01ea906f96d7137874cdd7adad00ca35764619310e54196c781d84d5b", symbol: "W", coinGeckoId: "wormhole", decimals: 6, price: 0.284654}, // Addr: 85VBFQZC9TZkfaptBWjvUw7YbZjy52A6mjtPGjstQAmQ, Notional: 33068.95536593147 + {chain: 1, addr: "69302bef50efd86a9bc1c2ac763ff56633e9fda1709eb0b858088e9cfbdcfe0f", symbol: "Rizzmas", coinGeckoId: "rizzmas", decimals: 6, price: 0.0000032}, // Addr: 85cQsFgbi8mBZxiPppbpPXuV7j1hA8tBwhjF4gKW6mHg, Notional: 1.750656 + {chain: 1, addr: "6afc09bb2ca898b2a734540d93a61ea2dd46ab6bd318a3e3283c8fbe86b93f3e", symbol: "LEO", coinGeckoId: "leo-2", decimals: 6, price: 0.00270122}, // Addr: 8Cd7wXoPb5Yt9cUGtmHNqAEmpMDrhfcVqnGbLC48b8Qm, Notional: 6359.23941931757 + {chain: 1, addr: "6b04a01bfd79e1eddf99d77598a5da54ee3cc8189dedfc1408908e29e1e94058", symbol: "POWSCHE", coinGeckoId: "powsche", decimals: 9, price: 0.04828246}, // Addr: 8CkiSHHJDHJV4LUoiRMLUhqG58cUkbyJRtcP4Z3mCXNf, Notional: 18190.65560522857 + {chain: 1, addr: "6b054395432c64d8250648371121f271fc3b8e36621384b9e91956bf02307c13", symbol: "DOKI", coinGeckoId: "doki", decimals: 6, price: 0.00020869}, // Addr: 8CmHC7Y2715VFaMkMZMwWDqRYQwPLAsM57Xiu3Ho4TjG, Notional: 7.95007390137126 + {chain: 1, addr: "6cccc33e6627899bd00d679cca0b56d788a1861b8de1ea3691e870710b92447c", symbol: "LOCKIN", coinGeckoId: "lock-in", decimals: 9, price: 0.0319384}, // Addr: 8Ki8DpuWNxu9VsS3kQbarsCWMcFGWkzzA8pUPto9zBd5, Notional: 29.527004029726424 + {chain: 1, addr: "6dbb85629db6a38eeb2fec793974b4c7e9c5fdc9e70165303b4f73106e5e62ba", symbol: "", coinGeckoId: "rope-token", decimals: 9, price: 0.01116572}, // Addr: 8PMHT4swUMtBzgHnh5U564N5sjPSiUz2cjEQzFnnP1Fo, Notional: 0.01116572 + {chain: 1, addr: "73512a31b0ae74aae6fbce469044131a230a122b1ea6f4af3a4e93c9158b538e", symbol: "JOWNES", coinGeckoId: "alux-jownes", decimals: 6, price: 0.00026182}, // Addr: 8m9fjYycXAFva1kScttQgsESVZT7yELhjZASqfHBuMa5, Notional: 23.21125074512556 + {chain: 1, addr: "7589fb28d63e11a5f134a97a6bc85399e6cbe2fddb268d496f91204d5271ff05", symbol: "GRAPE", coinGeckoId: "grape-2", decimals: 6, price: 0.0004727}, // Addr: 8upjSpvjcdpuzhfR1zriwg5NXkwDruejqNE9WNbPRtyA, Notional: 0.01096664 + {chain: 1, addr: "75fa185aaff1c781b07269a4dfd7849add90a6db207bf61cff506c9b3d525376", symbol: "GME", coinGeckoId: "gme", decimals: 9, price: 0.00365618}, // Addr: 8wXtPeU6557ETkp9WHFY1n1EcU6NxDvbAggHGsMYiHsB, Notional: 7379.234550893757 + {chain: 1, addr: "7618e3a4b6365218d0473a17c3386761b449f05d4e5dc213bd7966edde409f24", symbol: "SAGIT", coinGeckoId: "sagittarius", decimals: 6, price: 0.0025247}, // Addr: 8x17zMmVjJxqswjX4hNpxVPc7Tr5UabVJF3kv8TKq8Y3, Notional: 6350.477547421833 + {chain: 1, addr: "766d8eac4c0ae9f5d006f7a74ca87eaa78b50411e9385154b12fcc17c21b41d3", symbol: "KITTY", coinGeckoId: "kitty-ai", decimals: 6, price: 0.00031595}, // Addr: 8yJ15ee2AUQmwbWPxXLTTeBTzyMGn4MtSRKMqVHw1J1G, Notional: 9.4785 + {chain: 1, addr: "7747dce1ae5735f0fe877af40fc4b972847edabdb0abb1e04a432c4025606496", symbol: "MONKEY", coinGeckoId: "monkey", decimals: 1, price: 6.0784e-10}, // Addr: 92d5AncUVELq79xqLWNQ5Zoxz7fn9XHwijYswYWFrKtR, Notional: 4.002657617932992 + {chain: 1, addr: "777c026899a52a4c61329b0a098e74fbcd720d34665a41782bca2e2713410082", symbol: "ZERO", coinGeckoId: "analysoor", decimals: 9, price: 0.130651}, // Addr: 93RC484oMK5T9H89rzT5qiAXKHGP9jscXfFfrihNbe57, Notional: 0.130651 + {chain: 1, addr: "78404f497a9523d5d2530469f1d76f4ac5cfafad2423341f61aa08021efc459c", symbol: "$POPO", coinGeckoId: "popo-pepe-s-dog", decimals: 9, price: 0.00003108}, // Addr: 96QoNkZLTKH7Gecf6dKMRXBQXW1wqh378uF9pnTejgAw, Notional: 3.399480606232544 {chain: 1, addr: "7dd04d62e0c5aac91b412ea0cf91f647234e2797378e4b983cdecb7d3ef6fd46", symbol: "", coinGeckoId: "gigadao", decimals: 4, price: 0.00040465}, // Addr: 9U8Bn6zAf6Wyp1YHdXtLyfbN7yMvdvW1qQY475iZ5ftZ, Notional: 0.202325 - {chain: 1, addr: "8217c0f1b6d3300f53e7ea24352e93a307829c4ba2a43533c1b56d11468b0033", symbol: "ZORKSEES", coinGeckoId: "zorksees", decimals: 8, price: 354244}, // Addr: 9kq1VuGCCKeTgtRmzUTjLVi6LpmBD38im2hPRaqusPkE, Notional: 341389.49483539996 - {chain: 1, addr: "82444ff8283660793c0370a7dd9fb35cb1f7338d57eb088765d0dad090541e72", symbol: "", coinGeckoId: "mimatic", decimals: 9, price: 0.993831}, // Addr: 9mWRABuz2x6koTPCWiCPM49WUbcrNqGTHBV9T9k7y1o7, Notional: 20.72219433254286 - {chain: 1, addr: "8268e9a9a1444c2ba5c77a51936856b072e43fefcff5e4b01e99623c8ebb7749", symbol: "BTC", coinGeckoId: "wrapped-bitcoin-sollet", decimals: 6, price: 1858.43}, // Addr: 9n4nbM75f5Ui33ZbPYXn59EwSgE8CGsHtAeTH5YFeJ9E, Notional: 3646.11700362 - {chain: 1, addr: "8274472938310e90c774c25ade5e6fcaa7238aef9e3e67764d45b920d0c3e075", symbol: "WOOF", coinGeckoId: "woof-token", decimals: 6, price: 0.00008895}, // Addr: 9nEqaUcb16sQ3Tn1psbkWqyhPdLmfHWjKGymREjsAgTE, Notional: 0.9137511788308499 - {chain: 1, addr: "82993f9b768020400dc11af927de6d015f4f4abe63d73272b7e57ae17c7c5c6e", symbol: "KING", coinGeckoId: "king-2", decimals: 9, price: 0.00002282}, // Addr: 9noXzpXnkyEcKF3AeXqUHTdR59V5uvrRBUZ9bwfQwxeq, Notional: 6426.780733993627 - {chain: 1, addr: "842f35b8d1f37e6cc0a7eb8d12bf9079f7abf194cdcd466c22f5f1e8baa4dea8", symbol: "", coinGeckoId: "arb-protocol", decimals: 6, price: 0.0002046}, // Addr: 9tzZzEHsKnwFL1A3DyFJwj36KnZj3gZ7g4srWp9YTEoh, Notional: 1.0240230000000001 - {chain: 1, addr: "85cdebc205dddf95b88200aba0ac9bcbb78096324e276fce85d63c69211f0845", symbol: "USDY", coinGeckoId: "ondo-us-dollar-yield", decimals: 6, price: 1.063}, // Addr: A1KLoBrKBde8Ty9qtNQUtq3C2ortoC3u7twggz7sEto6, Notional: 0.10342989999999999 - {chain: 1, addr: "8666930409fea01a38402e938d3116943dc955b0abc3406728922f21131b6f01", symbol: "PENG", coinGeckoId: "peng", decimals: 6, price: 0.150299}, // Addr: A3eME5CetyZPBoWbRUwY3tSe25S6tb18ba9ZPbWk9eFJ, Notional: 23.858724629960996 - {chain: 1, addr: "86d536568df6b574b219c07565198d7fab61cb0458cdfbadf0f004759f2e5038", symbol: "GMEOW", coinGeckoId: "gmeow-cat", decimals: 6, price: 0.00016373}, // Addr: A5LCTQ1vJECCQWSXJYs3rfCoexctbUgTCAEKDuNye8bZ, Notional: 89.80465128124091 + {chain: 1, addr: "8217c0f1b6d3300f53e7ea24352e93a307829c4ba2a43533c1b56d11468b0033", symbol: "ZORKSEES", coinGeckoId: "zorksees", decimals: 8, price: 354244}, // Addr: 9kq1VuGCCKeTgtRmzUTjLVi6LpmBD38im2hPRaqusPkE, Notional: 341447.49520552 + {chain: 1, addr: "82444ff8283660793c0370a7dd9fb35cb1f7338d57eb088765d0dad090541e72", symbol: "", coinGeckoId: "mimatic", decimals: 9, price: 0.994558}, // Addr: 9mWRABuz2x6koTPCWiCPM49WUbcrNqGTHBV9T9k7y1o7, Notional: 20.73735288090748 + {chain: 1, addr: "8268e9a9a1444c2ba5c77a51936856b072e43fefcff5e4b01e99623c8ebb7749", symbol: "BTC", coinGeckoId: "wrapped-bitcoin-sollet", decimals: 6, price: 1656.85}, // Addr: 9n4nbM75f5Ui33ZbPYXn59EwSgE8CGsHtAeTH5YFeJ9E, Notional: 3250.6303479 + {chain: 1, addr: "826d35ab8f5b30c7d511f8f2ba9d8765228e94c8b810afc82c9a3a29a8146f89", symbol: "FLOCKA", coinGeckoId: "waka-flocka", decimals: 6, price: 0.0001998}, // Addr: 9n8b1EXLCA8Z22mf7pjLKVNzuQgGbyPfLrmFQvEcHeSU, Notional: 1.998 + {chain: 1, addr: "8274472938310e90c774c25ade5e6fcaa7238aef9e3e67764d45b920d0c3e075", symbol: "WOOF", coinGeckoId: "woof-token", decimals: 6, price: 0.0000708}, // Addr: 9nEqaUcb16sQ3Tn1psbkWqyhPdLmfHWjKGymREjsAgTE, Notional: 0.7273027932684 + {chain: 1, addr: "82993f9b768020400dc11af927de6d015f4f4abe63d73272b7e57ae17c7c5c6e", symbol: "KING", coinGeckoId: "king-2", decimals: 9, price: 0.00001918}, // Addr: 9noXzpXnkyEcKF3AeXqUHTdR59V5uvrRBUZ9bwfQwxeq, Notional: 4975.323580600063 + {chain: 1, addr: "8300ec316d7d1c7a81a6907c633655bcf37368889c2bed5f47901d0f56e01c8b", symbol: "KEYCAT", coinGeckoId: "keyboard-cat", decimals: 9, price: 0.00046977}, // Addr: 9pPE1q9EW1bMQWbHmffrzUCfRr7S82UoxNUFfA6mAZC6, Notional: 0.571280145254404 + {chain: 1, addr: "842f35b8d1f37e6cc0a7eb8d12bf9079f7abf194cdcd466c22f5f1e8baa4dea8", symbol: "", coinGeckoId: "arb-protocol", decimals: 6, price: 0.00009927}, // Addr: 9tzZzEHsKnwFL1A3DyFJwj36KnZj3gZ7g4srWp9YTEoh, Notional: 0.49684635 + {chain: 1, addr: "85cdebc205dddf95b88200aba0ac9bcbb78096324e276fce85d63c69211f0845", symbol: "USDY", coinGeckoId: "ondo-us-dollar-yield", decimals: 6, price: 1.069}, // Addr: A1KLoBrKBde8Ty9qtNQUtq3C2ortoC3u7twggz7sEto6, Notional: 0.10401369999999999 + {chain: 1, addr: "8666930409fea01a38402e938d3116943dc955b0abc3406728922f21131b6f01", symbol: "PENG", coinGeckoId: "peng", decimals: 6, price: 0.110595}, // Addr: A3eME5CetyZPBoWbRUwY3tSe25S6tb18ba9ZPbWk9eFJ, Notional: 17.556042624705 + {chain: 1, addr: "86d536568df6b574b219c07565198d7fab61cb0458cdfbadf0f004759f2e5038", symbol: "GMEOW", coinGeckoId: "gmeow-cat", decimals: 6, price: 0.00005906}, // Addr: A5LCTQ1vJECCQWSXJYs3rfCoexctbUgTCAEKDuNye8bZ, Notional: 32.39395776381902 {chain: 1, addr: "86d786039c432f0d4d65f3d29b9fe4ba5fd0f4057f259bcdc314c115559274fc", symbol: "", coinGeckoId: "vynk-chain", decimals: 4, price: 0.000054}, // Addr: A5NF1e6RnYkVwtg3V3z1qeUz4PZfHCXmQ9RotuJWgi6F, Notional: 0.036396 - {chain: 1, addr: "87c9ce6b6344187c4b75fa01dd4334d8bb826a9214fefe9d39cce5fad29b6faa", symbol: "", coinGeckoId: "bilira", decimals: 6, price: 0.02884969}, // Addr: A94X2fRy3wydNShU4dRaDyap2UuoeWJGWyATtyp61WZf, Notional: 6.0584349 - {chain: 1, addr: "883977f594221f16fd8037db6cd49393cb7ccb597ef5513fee423975372ff5b3", symbol: "", coinGeckoId: "racefi", decimals: 6, price: 0.00150934}, // Addr: AAmGoPDFLG6bE82BgZWjVi8k95tj9Tf3vUN7WvtUm2BU, Notional: 371.60154409966 - {chain: 1, addr: "895e01287acee57df889b96b43c641ad49a9b304f8a5619eb18098db01c6e583", symbol: "COLLE", coinGeckoId: "colle-ai", decimals: 6, price: 0.00183407}, // Addr: AFDzaLz3cQZNWjnWbyq2q81TLVTPbHTbfkj8qKqTk74e, Notional: 18.840270776327138 - {chain: 1, addr: "897658557d211722ba678ad99276eb14d9567f0a792e3ba70c894785c742bfae", symbol: "", coinGeckoId: "green-satoshi-token", decimals: 9, price: 0.01935781}, // Addr: AFbX8oGjGpmVFywbVouvhQSRmiW2aR1mohfahi4Y2AdB, Notional: 63.16982376238905 - {chain: 1, addr: "89a0fd32e8624b657a53062808b8980d227274c3f76d3ddaa49985ddf034004c", symbol: "FTT", coinGeckoId: "ftx-token", decimals: 6, price: 2.43}, // Addr: AGFEad2et2ZJif9jaGpdMixQqvW5i81aBdvKe7PHNfz3, Notional: 45.49444056 + {chain: 1, addr: "87c9ce6b6344187c4b75fa01dd4334d8bb826a9214fefe9d39cce5fad29b6faa", symbol: "", coinGeckoId: "bilira", decimals: 6, price: 0.0279144}, // Addr: A94X2fRy3wydNShU4dRaDyap2UuoeWJGWyATtyp61WZf, Notional: 5.862024 + {chain: 1, addr: "883977f594221f16fd8037db6cd49393cb7ccb597ef5513fee423975372ff5b3", symbol: "", coinGeckoId: "racefi", decimals: 6, price: 0.00106189}, // Addr: AAmGoPDFLG6bE82BgZWjVi8k95tj9Tf3vUN7WvtUm2BU, Notional: 261.43875048961 + {chain: 1, addr: "895e01287acee57df889b96b43c641ad49a9b304f8a5619eb18098db01c6e583", symbol: "COLLE", coinGeckoId: "colle-ai", decimals: 6, price: 0.00140801}, // Addr: AFDzaLz3cQZNWjnWbyq2q81TLVTPbHTbfkj8qKqTk74e, Notional: 27.13595895575643 + {chain: 1, addr: "897658557d211722ba678ad99276eb14d9567f0a792e3ba70c894785c742bfae", symbol: "", coinGeckoId: "green-satoshi-token", decimals: 9, price: 0.01603755}, // Addr: AFbX8oGjGpmVFywbVouvhQSRmiW2aR1mohfahi4Y2AdB, Notional: 52.33490808518643 + {chain: 1, addr: "89a0fd32e8624b657a53062808b8980d227274c3f76d3ddaa49985ddf034004c", symbol: "FTT", coinGeckoId: "ftx-token", decimals: 6, price: 3.64}, // Addr: AGFEad2et2ZJif9jaGpdMixQqvW5i81aBdvKe7PHNfz3, Notional: 68.14805088 {chain: 1, addr: "89efe489cf710a97bb9346ccc2dd81a30d71b982ed3523f6bfefdd8ebd04187c", symbol: "AHT", coinGeckoId: "avenue-hamilton-token", decimals: 9, price: 0.03585085}, // Addr: AHT1yynTv45s3P3KrRfQCVMHckdHeMVA3fteEg34xt9y, Notional: 0.17925424999999998 - {chain: 1, addr: "8af8661ba22613733b7c8025128597497dea9952506b2e1b484dc840befe83f1", symbol: "AMU", coinGeckoId: "amulet-protocol", decimals: 9, price: 0.00569739}, // Addr: AMUwxPsqWSd1fbCGzWsrRKDcNoduuWMkdR38qPdit8G8, Notional: 153144.60816301836 - {chain: 1, addr: "8b7a5bd48982a26d6436cb99d7a2c7ea90e46d38625a0bdb74e1cc5886a7b703", symbol: "", coinGeckoId: "apricot", decimals: 6, price: 0.00019428}, // Addr: APTtJyaRX5yGTsJU522N4VYWg3vCvSb65eam5GrPT5Rt, Notional: 0.36990912 - {chain: 1, addr: "8c0e1e13db30b1678d1cf8888201ced5a3ffc5104bf903743bfb1f87a5e15589", symbol: "GEMINI", coinGeckoId: "gemini-2", decimals: 6, price: 0.00479468}, // Addr: ARiZfq6dK19uNqxWyRudhbM2MswLyYhVUHdndGkffdGc, Notional: 10932.273163629938 - {chain: 1, addr: "8c77f3661d6b4a8ef39dbc5340eead8c3cbe0b45099840e8263d8725b587b073", symbol: "ATLAS", coinGeckoId: "star-atlas", decimals: 8, price: 0.00331438}, // Addr: ATLASXmbPQxBUYbxPsV97usA3fPQYEqzQBUHgiFCUsXx, Notional: 175108.2924100174 - {chain: 1, addr: "8cbf9fdba8691b67e32eb57a784b1cae2744c6fc03ac61e450dd9331b9bdbb2e", symbol: "AURY", coinGeckoId: "aurory", decimals: 9, price: 0.22886}, // Addr: AURYydfxJib1ZkTir1Jn1J9ECYUtjb6rKQVmtYaixWPP, Notional: 1343.177272794587 + {chain: 1, addr: "8af8661ba22613733b7c8025128597497dea9952506b2e1b484dc840befe83f1", symbol: "AMU", coinGeckoId: "amulet-protocol", decimals: 9, price: 0.00486302}, // Addr: AMUwxPsqWSd1fbCGzWsrRKDcNoduuWMkdR38qPdit8G8, Notional: 130334.92056406295 + {chain: 1, addr: "8b7a5bd48982a26d6436cb99d7a2c7ea90e46d38625a0bdb74e1cc5886a7b703", symbol: "", coinGeckoId: "apricot", decimals: 6, price: 0.00021285}, // Addr: APTtJyaRX5yGTsJU522N4VYWg3vCvSb65eam5GrPT5Rt, Notional: 0.40526639999999997 + {chain: 1, addr: "8c0e1e13db30b1678d1cf8888201ced5a3ffc5104bf903743bfb1f87a5e15589", symbol: "GEMINI", coinGeckoId: "gemini-2", decimals: 6, price: 0.00570052}, // Addr: ARiZfq6dK19uNqxWyRudhbM2MswLyYhVUHdndGkffdGc, Notional: 11923.348656183789 + {chain: 1, addr: "8c77f3661d6b4a8ef39dbc5340eead8c3cbe0b45099840e8263d8725b587b073", symbol: "ATLAS", coinGeckoId: "star-atlas", decimals: 8, price: 0.00342095}, // Addr: ATLASXmbPQxBUYbxPsV97usA3fPQYEqzQBUHgiFCUsXx, Notional: 180776.32345539652 + {chain: 1, addr: "8cbf9fdba8691b67e32eb57a784b1cae2744c6fc03ac61e450dd9331b9bdbb2e", symbol: "AURY", coinGeckoId: "aurory", decimals: 9, price: 0.215592}, // Addr: AURYydfxJib1ZkTir1Jn1J9ECYUtjb6rKQVmtYaixWPP, Notional: 1256.010292878042 {chain: 1, addr: "8cc1469b46aa9e904a5106fa3e6dd3937ac55099a1fbb62047fc1c556d88d29b", symbol: "AUT", coinGeckoId: "avenue-university-token", decimals: 9, price: 0.00546985}, // Addr: AUT1gfMZw37wMMQqAxk89nfpjZpEEf2XSoBUd8V5ydnS, Notional: 0.06016835 - {chain: 1, addr: "8ea6bae83ada8cc0d7be5c2816a74e95d409603129bb2ee4fa22cc6f964a4d81", symbol: "Cheese", coinGeckoId: "cheese-2", decimals: 6, price: 0.00178774}, // Addr: AbrMJWfDVRZ2EWCQ1xSCpoVeVgZNpq1U2AoYG98oRXfn, Notional: 0.00047987410950000003 - {chain: 1, addr: "8f286c320f95f37efe6535d91dac27779494093b14e7b427a0a07b1c7f97ccc1", symbol: "WIT", coinGeckoId: "what-in-tarnation", decimals: 6, price: 0.00091992}, // Addr: Adq3wnAvtaXBNfy63xGV1YNkDiPKadDT469xF9uZPrqE, Notional: 6269.329368803512 - {chain: 1, addr: "8f8eda6d92c4afa64e25a02b8cc6e9f4026cf3007f48f279d842594d0328e121", symbol: "WGC", coinGeckoId: "wild-goat-coin", decimals: 6, price: 3.33968e-7}, // Addr: AfPeB1BDUotBeNoLv82XRDCNQcdAA1mqis3YC5SMTe7a, Notional: 7335.587819015411 - {chain: 1, addr: "8fa66a1378bce9e01b9496615ed38c132c586fa36e29f6b38eace0bf7b3d4b69", symbol: "ca", coinGeckoId: "contract-address-meme", decimals: 9, price: 0.00008223}, // Addr: AfkUkcoJ5Yt7eU9BwnF1RjRqt4fQG5zYV1eS1ytDk7FE, Notional: 3381.4909830052093 - {chain: 1, addr: "90eb19122682b9b340f9afd6717bcc7770812215c2286d3d3051dff49288b17e", symbol: "BOT", coinGeckoId: "starbots", decimals: 8, price: 0.0003369}, // Addr: AkhdZGVbJXPuQZ53u2LrimCjkRP6ZyxG1SoM85T98eE1, Notional: 1628.315480866641 - {chain: 1, addr: "921414f6337fb743709e6fcbcc439ecc35fe8e23bc33941b1d62862b809e8d24", symbol: "YAKU", coinGeckoId: "yaku", decimals: 9, price: 0.00970613}, // Addr: AqEHVh8J2nXH9saV2ciZyYwPpqWFRfD2ffcq5Z8xxqm5, Notional: 0.00970613 - {chain: 1, addr: "9266050ea34cd64a96e9e7be1e210ed22b2e3f5fde61861af7527c681ef2f3d3", symbol: "renDOGE", coinGeckoId: "rendoge", decimals: 8, price: 0.01020529}, // Addr: ArUkYE2XDKzqy77PRRGjo4wREWwqk6RXTfM9NeqzPvjU, Notional: 32.83803107634 + {chain: 1, addr: "8ea6bae83ada8cc0d7be5c2816a74e95d409603129bb2ee4fa22cc6f964a4d81", symbol: "Cheese", coinGeckoId: "cheese-2", decimals: 6, price: 0.00100062}, // Addr: AbrMJWfDVRZ2EWCQ1xSCpoVeVgZNpq1U2AoYG98oRXfn, Notional: 0.00026859142350000003 + {chain: 1, addr: "8f286c320f95f37efe6535d91dac27779494093b14e7b427a0a07b1c7f97ccc1", symbol: "WIT", coinGeckoId: "what-in-tarnation", decimals: 6, price: 0.00058917}, // Addr: Adq3wnAvtaXBNfy63xGV1YNkDiPKadDT469xF9uZPrqE, Notional: 5356.781396390987 + {chain: 1, addr: "8f8eda6d92c4afa64e25a02b8cc6e9f4026cf3007f48f279d842594d0328e121", symbol: "WGC", coinGeckoId: "wild-goat-coin", decimals: 6, price: 4.12203e-7}, // Addr: AfPeB1BDUotBeNoLv82XRDCNQcdAA1mqis3YC5SMTe7a, Notional: 9074.483538731105 + {chain: 1, addr: "8fa66a1378bce9e01b9496615ed38c132c586fa36e29f6b38eace0bf7b3d4b69", symbol: "ca", coinGeckoId: "contract-address-meme", decimals: 9, price: 0.00004147}, // Addr: AfkUkcoJ5Yt7eU9BwnF1RjRqt4fQG5zYV1eS1ytDk7FE, Notional: 1705.3439263678222 + {chain: 1, addr: "90eb19122682b9b340f9afd6717bcc7770812215c2286d3d3051dff49288b17e", symbol: "BOT", coinGeckoId: "starbots", decimals: 8, price: 0.00031316}, // Addr: AkhdZGVbJXPuQZ53u2LrimCjkRP6ZyxG1SoM85T98eE1, Notional: 1513.5745799590302 + {chain: 1, addr: "921414f6337fb743709e6fcbcc439ecc35fe8e23bc33941b1d62862b809e8d24", symbol: "YAKU", coinGeckoId: "yaku", decimals: 9, price: 0.00904675}, // Addr: AqEHVh8J2nXH9saV2ciZyYwPpqWFRfD2ffcq5Z8xxqm5, Notional: 0.00904675 + {chain: 1, addr: "9266050ea34cd64a96e9e7be1e210ed22b2e3f5fde61861af7527c681ef2f3d3", symbol: "renDOGE", coinGeckoId: "rendoge", decimals: 8, price: 0.00870511}, // Addr: ArUkYE2XDKzqy77PRRGjo4wREWwqk6RXTfM9NeqzPvjU, Notional: 28.01083288206 {chain: 1, addr: "92d10feca33abd20cdb6c082b7066be3a8664e9098e5758226e82e28a0e0cc0a", symbol: "", coinGeckoId: "battle-of-guardians-share", decimals: 9, price: 0.0011079}, // Addr: At7RLMbA6ZUjj7riyvFq2j5NHQ19aJabCju2VxLDAqso, Notional: 12.92246760384 - {chain: 1, addr: "9353906bba080336a76db51391c3737194d3a31183665f4b7021e908739bc0f2", symbol: "COST", coinGeckoId: "costco-hot-dog", decimals: 9, price: 0.00388238}, // Addr: Av6qVigkb7USQyPXJkUvAEm4f599WTRvd75PUWBA9eNm, Notional: 21700.2292767928 - {chain: 1, addr: "969c68e974ffbb74feed1af1672b9f67adb65fb382ff2ee105070fd8d60d9fe5", symbol: "POS", coinGeckoId: "pengyos", decimals: 6, price: 0.00009495}, // Addr: B8vV6An7xFF3bARB1cmU7TMfKNjjes2WvY7jWqiRc6K6, Notional: 5.697e-10 - {chain: 1, addr: "97af730592f7e84eaf461cf72db62d036e914c7a1b1f2cd2ac35c3301efb434f", symbol: "SNARC", coinGeckoId: "first-ai-1951", decimals: 6, price: 0.00002426}, // Addr: BD7jNnt6uYDp9rVRBTjJhkweGxYQppRe8CXLnAJspump, Notional: 89.10209339551174 - {chain: 1, addr: "9990517de4aab724b1d8e7fead02d3f25a7ad6912ba339c6b7b637d2f53d7d10", symbol: "", coinGeckoId: "blocto-token", decimals: 8, price: 0.00544248}, // Addr: BLT1noyNr3GttckEVrtcfC6oyK6yV1DpPgSyXbncMwef, Notional: 0.05714604 - {chain: 1, addr: "99975862e4e373b0063604e03ebced38da7060839238fb7001a925fd85756c93", symbol: "BLZE", coinGeckoId: "solblaze", decimals: 9, price: 0.00047757}, // Addr: BLZEEuZUBVqFhj8adcCFPJvPVCiCyVmh3hkJMrU8KuJA, Notional: 0.0024761628891195 - {chain: 1, addr: "9a7bc3a4fa3d288a156a2a3171fd953536f10e7c92cefad8b919c709aefb2b0c", symbol: "GROK", coinGeckoId: "grok-6", decimals: 9, price: 0.155997}, // Addr: BQ3F72yt9FVRgYrqCVCG3YohyBesDZ9bTuhGdmQ7GNEF, Notional: 0.7799849999999999 - {chain: 1, addr: "9cdd9b466af324c58b653f6eac5e78f748e55778caed00a90d61e70c061587f8", symbol: "IO", coinGeckoId: "io", decimals: 8, price: 3.23}, // Addr: BZLbGTNCSFfoth2GYDtwr7e4imWzpR5jqcUuGEwr646K, Notional: 145.0398225509 - {chain: 1, addr: "9ce7be61bf4938b98cd984cbfabd66b6b4ee2fd4d02529ab27f76bcfcc88798f", symbol: "JANI", coinGeckoId: "jani", decimals: 6, price: 0.00138576}, // Addr: BZVZFqfUaV2uEsBU9QCcVgsLJVMy9UCcSVbryzAFpump, Notional: 20786.4 - {chain: 1, addr: "9ed00a9e2b184c6c0b6d9629c2648efe56c512456e354538bb4efad332ea5f30", symbol: "", coinGeckoId: "deapcoin", decimals: 6, price: 0.00149356}, // Addr: BgwQjVNMWvt2d8CN51CsbniwRWyZ9H9HfHkEsvikeVuZ, Notional: 4.4806799999999996 - {chain: 1, addr: "a084edb439cccf78ff5db4936074779133cc49d8058731fb9ad6d982f57f899e", symbol: "BOBO", coinGeckoId: "bobo-the-bear", decimals: 6, price: 1.22807e-7}, // Addr: Bobo54AXWLGQWqCK6EZdrBQz4bKJXeBE9ExD1HJGbXed, Notional: 1.7298767359791376 - {chain: 1, addr: "a2b04fe6f429ea28555be7b6dbba72479b6694ea96e93082996e9be877bc920a", symbol: "TOX", coinGeckoId: "trollbox", decimals: 9, price: 0.00010213}, // Addr: Bx4ykEMurwPQBAFNvthGj73fMBVTvHa8e9cbAyaK4ZSh, Notional: 0.0020426 - {chain: 1, addr: "a43ee344a6ae6a837ced5766eb6183dad04fbe9b15e49e1dcd89fe0937fe930f", symbol: "AQUARIUS", coinGeckoId: "aquarius-2", decimals: 6, price: 0.00274435}, // Addr: C49Ut3om3QFTDrMZ5Cr8VcTKPpHDcQ2Fv8mmuJHHigDt, Notional: 7328.863085102767 - {chain: 1, addr: "a5854b583d61bd674064522d1d3017a389990e96a9c244b9c57f0dac1cde4ea8", symbol: "C98", coinGeckoId: "coin98", decimals: 6, price: 0.205573}, // Addr: C98A4nkJXhpVZNAZdHUA95RpTF3T4whtQubL3YobiUX9, Notional: 107.930920537951 - {chain: 1, addr: "a790b593d8c348fba977d377f67f86214cb50662ae0e1410776d5b92611aec13", symbol: "SOLX", coinGeckoId: "soldex", decimals: 9, price: 0.00007277}, // Addr: CH74tuRLTYcxG7qNJCsV9rghfLXJCQJbsu7i52a8F1Gn, Notional: 0.0018963731741699998 - {chain: 1, addr: "a832b1347f65932aa5a8b8e3b6f7854a2972157d0375097d599eabac9685a95c", symbol: "", coinGeckoId: "gari-network", decimals: 9, price: 0.01351793}, // Addr: CKaKtYvz6dKPyMvYq9Rh3UBrnNqYZAyd7iF4hJtjUvks, Notional: 266095.04398391425 - {chain: 1, addr: "a9b7b4c191b9fcd8a101e517de4a2bc44ae7df4ff6595f62cb4bf9c5c3b01fd2", symbol: "CRWNY", coinGeckoId: "crowny-token", decimals: 6, price: 0.00183113}, // Addr: CRWNYkqdgvhGGae9CKfNka58j6QQkaD5bLhKXvUYqnc1, Notional: 3.30885192648017 - {chain: 1, addr: "aa77c1f5d0d2c07ce7075e31d348ca1c0965bb287be13984dec1c5615bf22665", symbol: "CUSD", coinGeckoId: "coin98-dollar", decimals: 6, price: 1.12}, // Addr: CUSDvqAQLbt7fRofcmV2EXfPA2t36kzj7FjzdmqDiNQL, Notional: 2.3793918400000003 - {chain: 1, addr: "aeeafcf3ec1126c4abb764352b5b2959152bf9c3aa2237802092efc84f8e04ca", symbol: "CANCER", coinGeckoId: "cancer", decimals: 6, price: 0.00278731}, // Addr: CmomKM8iPKRSMN7y1jqyW1QKj5bGoZmbvNZXWBJSUdnZ, Notional: 6689.187756818851 - {chain: 1, addr: "b4f7fddc746c9c6b8872c4a21efe2817409c7c51a20c286e32162bbca75b8400", symbol: "DBR", coinGeckoId: "debridge", decimals: 6, price: 0.02589895}, // Addr: DBRiDgJAMsM95moTzJs7M9LnkGErpbv9v6CUR1DXnUu5, Notional: 0.02589895 - {chain: 1, addr: "b5ce441b09fe68fbcace88868d120ae3dbe8969465c859e1abaeb390d966d890", symbol: "Odie", coinGeckoId: "odie-on-sol", decimals: 6, price: 0.00004258}, // Addr: DEhDXhtUFuz6Uodhde3rznGbVbdiECahp1kTHnFpsna3, Notional: 0.08941800000000001 - {chain: 1, addr: "b5f7e08966fa2f997abc90d7a7cde1bc733f567b9eafc3007e80a3174726b6f6", symbol: "", coinGeckoId: "defi-land", decimals: 9, price: 0.00054534}, // Addr: DFL1zNkaGPWm1BqAVqRjCZvHmwTFrEaJtbzJWgseoNJh, Notional: 11.579834453644953 - {chain: 1, addr: "b7db4e83eb727f1187bd7a50303f5b4e4e943503da8571ad6564a51131504792", symbol: "", coinGeckoId: "wrapped-usdt-allbridge-from-polygon", decimals: 6, price: 0.999328}, // Addr: DNhZkUaxHXYvpxZ7LNnHtss8sQgdAfd1ZYS1fB7LKWUZ, Notional: 42.166398125983996 - {chain: 1, addr: "b953b5f8dd5457a2a0f0d41903409785b9d84d4045614faa4f505ee132dcd769", symbol: "DUST", coinGeckoId: "dust-protocol", decimals: 9, price: 0.143023}, // Addr: DUSTawucrTsGU8hcqRdHDCbuYhCPADMLM2VcCb8VnFnQ, Notional: 1357920.8403847923 - {chain: 1, addr: "bbec677bca5169fbcaa1dccd44ef4badd3fe4d53bf3c9610379afe527256660a", symbol: "SOLNIC", coinGeckoId: "solnic", decimals: 6, price: 0.00518942}, // Addr: DeaKMzAeZja3Mh5okZE6WUvygLP3Lfuvm6Rg78HqXTz9, Notional: 25965.27331164224 - {chain: 1, addr: "bc07c56e60ad3d3f177382eac6548fba1fd32cfd90ca02b3e7cfa185fdce7398", symbol: "Bonk", coinGeckoId: "bonk", decimals: 5, price: 0.00004194}, // Addr: DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263, Notional: 24888538.85225835 - {chain: 1, addr: "bfc5f3a72f20be422f69837df545b8a5c992a9cb3e4687f61030f55ae9e3b235", symbol: "CRP", coinGeckoId: "cropperfinance", decimals: 9, price: 0.00157506}, // Addr: DubwWZNWiNGMMeeQHPnMATNj77YZPZSAz2WVR5WjLJqz, Notional: 1.2442974e-9 - {chain: 1, addr: "c261d86cf5cf877128ba1f5652e5f3dda599270c1556a15bc0a9aacf8063e563", symbol: "RIN", coinGeckoId: "aldrin", decimals: 9, price: 0.01349437}, // Addr: E5ndSkaB17Dm7CsD22dvcjfrYSDLCxFcMd6z8ddCk5wp, Notional: 0.0114702145 - {chain: 1, addr: "c2667f39a3a7b6febb2f995eb4d1b739f45fe2edd645403c3e52e677e6bd6852", symbol: "WOO", coinGeckoId: "woo-network", decimals: 6, price: 0.294151}, // Addr: E5rk3nmgLUuKUiS94gg4bpWwWwyjCMtddsAXkTFLtHEy, Notional: 587.47225003467 - {chain: 1, addr: "c28ee4128851e187510f75f9d61703da621ecbbb4b5b6e0d4b1fc21942f309a0", symbol: "DGLN", coinGeckoId: "dogelana", decimals: 9, price: 0.00001374}, // Addr: E6UU5M1z4CvSAAF99d9wRoXsasWMEXsvHrz3JQRXtm2X, Notional: 1.9637318014806002 - {chain: 1, addr: "c3bc53a848c67ab3799f20a745a51e51c991946690c7c8a4b9a480aa29b07b94", symbol: "RPILL", coinGeckoId: "red-pill-2", decimals: 7, price: 9.35549e-7}, // Addr: EB54Nt1ydAgMR3edpaXEwb16R8TfF1enJ7zaYSefo7wH, Notional: 110631.76691091523 - {chain: 1, addr: "c44051a911b54c7ecffc7ee0b0a40af48b328ae755a99533c8402cb26df43807", symbol: "MOODENG", coinGeckoId: "moo-deng", decimals: 6, price: 0.301709}, // Addr: ED5nyyWEzpPPiWimP8vYm7sD7TD3LAt3Q3gRTWHzPJBY, Notional: 92664.3948503325 + {chain: 1, addr: "9353906bba080336a76db51391c3737194d3a31183665f4b7021e908739bc0f2", symbol: "COST", coinGeckoId: "costco-hot-dog", decimals: 9, price: 0.00137439}, // Addr: Av6qVigkb7USQyPXJkUvAEm4f599WTRvd75PUWBA9eNm, Notional: 9941.60985141907 + {chain: 1, addr: "969c68e974ffbb74feed1af1672b9f67adb65fb382ff2ee105070fd8d60d9fe5", symbol: "POS", coinGeckoId: "pengyos", decimals: 6, price: 0.00004403}, // Addr: B8vV6An7xFF3bARB1cmU7TMfKNjjes2WvY7jWqiRc6K6, Notional: 2.6418e-10 + {chain: 1, addr: "97af730592f7e84eaf461cf72db62d036e914c7a1b1f2cd2ac35c3301efb434f", symbol: "SNARC", coinGeckoId: "first-ai-1951", decimals: 6, price: 0.00001618}, // Addr: BD7jNnt6uYDp9rVRBTjJhkweGxYQppRe8CXLnAJspump, Notional: 75.61631573743422 + {chain: 1, addr: "9990517de4aab724b1d8e7fead02d3f25a7ad6912ba339c6b7b637d2f53d7d10", symbol: "", coinGeckoId: "blocto-token", decimals: 8, price: 0.00467942}, // Addr: BLT1noyNr3GttckEVrtcfC6oyK6yV1DpPgSyXbncMwef, Notional: 0.04913391 + {chain: 1, addr: "99975862e4e373b0063604e03ebced38da7060839238fb7001a925fd85756c93", symbol: "BLZE", coinGeckoId: "solblaze", decimals: 9, price: 0.00054372}, // Addr: BLZEEuZUBVqFhj8adcCFPJvPVCiCyVmh3hkJMrU8KuJA, Notional: 0.002819145436422 + {chain: 1, addr: "9a7bc3a4fa3d288a156a2a3171fd953536f10e7c92cefad8b919c709aefb2b0c", symbol: "GROK", coinGeckoId: "grok-6", decimals: 9, price: 0.106289}, // Addr: BQ3F72yt9FVRgYrqCVCG3YohyBesDZ9bTuhGdmQ7GNEF, Notional: 0.531445 + {chain: 1, addr: "9cdd9b466af324c58b653f6eac5e78f748e55778caed00a90d61e70c061587f8", symbol: "IO", coinGeckoId: "io", decimals: 8, price: 2.88}, // Addr: BZLbGTNCSFfoth2GYDtwr7e4imWzpR5jqcUuGEwr646K, Notional: 129.3234331104 + {chain: 1, addr: "9ce7be61bf4938b98cd984cbfabd66b6b4ee2fd4d02529ab27f76bcfcc88798f", symbol: "JANI", coinGeckoId: "jani", decimals: 6, price: 0.00107341}, // Addr: BZVZFqfUaV2uEsBU9QCcVgsLJVMy9UCcSVbryzAFpump, Notional: 16101.149999999998 + {chain: 1, addr: "9ed00a9e2b184c6c0b6d9629c2648efe56c512456e354538bb4efad332ea5f30", symbol: "", coinGeckoId: "deapcoin", decimals: 6, price: 0.0017643}, // Addr: BgwQjVNMWvt2d8CN51CsbniwRWyZ9H9HfHkEsvikeVuZ, Notional: 5.2928999999999995 + {chain: 1, addr: "a084edb439cccf78ff5db4936074779133cc49d8058731fb9ad6d982f57f899e", symbol: "BOBO", coinGeckoId: "bobo-the-bear", decimals: 6, price: 5.9525e-8}, // Addr: Bobo54AXWLGQWqCK6EZdrBQz4bKJXeBE9ExD1HJGbXed, Notional: 0.8384775518427954 + {chain: 1, addr: "a2b04fe6f429ea28555be7b6dbba72479b6694ea96e93082996e9be877bc920a", symbol: "TOX", coinGeckoId: "trollbox", decimals: 9, price: 0.00006207}, // Addr: Bx4ykEMurwPQBAFNvthGj73fMBVTvHa8e9cbAyaK4ZSh, Notional: 0.0012414 + {chain: 1, addr: "a43ee344a6ae6a837ced5766eb6183dad04fbe9b15e49e1dcd89fe0937fe930f", symbol: "AQUARIUS", coinGeckoId: "aquarius-2", decimals: 6, price: 0.00256817}, // Addr: C49Ut3om3QFTDrMZ5Cr8VcTKPpHDcQ2Fv8mmuJHHigDt, Notional: 7439.286673330408 + {chain: 1, addr: "a5854b583d61bd674064522d1d3017a389990e96a9c244b9c57f0dac1cde4ea8", symbol: "C98", coinGeckoId: "coin98", decimals: 6, price: 0.166627}, // Addr: C98A4nkJXhpVZNAZdHUA95RpTF3T4whtQubL3YobiUX9, Notional: 87.48330518344899 + {chain: 1, addr: "a790b593d8c348fba977d377f67f86214cb50662ae0e1410776d5b92611aec13", symbol: "SOLX", coinGeckoId: "soldex", decimals: 9, price: 0.00019251}, // Addr: CH74tuRLTYcxG7qNJCsV9rghfLXJCQJbsu7i52a8F1Gn, Notional: 0.00501677614071 + {chain: 1, addr: "a832b1347f65932aa5a8b8e3b6f7854a2972157d0375097d599eabac9685a95c", symbol: "", coinGeckoId: "gari-network", decimals: 9, price: 0.01225239}, // Addr: CKaKtYvz6dKPyMvYq9Rh3UBrnNqYZAyd7iF4hJtjUvks, Notional: 240635.05699819705 + {chain: 1, addr: "a9b7b4c191b9fcd8a101e517de4a2bc44ae7df4ff6595f62cb4bf9c5c3b01fd2", symbol: "CRWNY", coinGeckoId: "crowny-token", decimals: 6, price: 0.00214466}, // Addr: CRWNYkqdgvhGGae9CKfNka58j6QQkaD5bLhKXvUYqnc1, Notional: 3.8754006393019402 + {chain: 1, addr: "aa77c1f5d0d2c07ce7075e31d348ca1c0965bb287be13984dec1c5615bf22665", symbol: "CUSD", coinGeckoId: "coin98-dollar", decimals: 6, price: 1.099}, // Addr: CUSDvqAQLbt7fRofcmV2EXfPA2t36kzj7FjzdmqDiNQL, Notional: 2.334778243 + {chain: 1, addr: "aeeafcf3ec1126c4abb764352b5b2959152bf9c3aa2237802092efc84f8e04ca", symbol: "CANCER", coinGeckoId: "cancer", decimals: 6, price: 0.00260639}, // Addr: CmomKM8iPKRSMN7y1jqyW1QKj5bGoZmbvNZXWBJSUdnZ, Notional: 6294.324381935708 + {chain: 1, addr: "b41652c46fff703ca2d2d9660dc6e9c2f9eb59cbd77ba07d1edf3548c30e4fac", symbol: "CAIR", coinGeckoId: "crypto-ai-robo", decimals: 6, price: 0.00018351}, // Addr: D7z8T6FadmqDYGHy3LsMN3bzfrABmvVUnAFUrKfuWZ8F, Notional: 0.05780565 + {chain: 1, addr: "b4f7fddc746c9c6b8872c4a21efe2817409c7c51a20c286e32162bbca75b8400", symbol: "DBR", coinGeckoId: "debridge", decimals: 6, price: 0.03684308}, // Addr: DBRiDgJAMsM95moTzJs7M9LnkGErpbv9v6CUR1DXnUu5, Notional: 0.03684308 + {chain: 1, addr: "b5cbeacdc2c4b9172fc2055facc3b365eacb144ec670fcd02689fc9c29a252be", symbol: "KWEEN", coinGeckoId: "kween", decimals: 6, price: 0.01711516}, // Addr: DEf93bSt8dx58gDFCcz4CwbjYZzjwaRBYAciJYLfdCA9, Notional: 64755.46793966082 + {chain: 1, addr: "b5ce441b09fe68fbcace88868d120ae3dbe8969465c859e1abaeb390d966d890", symbol: "Odie", coinGeckoId: "odie-on-sol", decimals: 6, price: 0.00003857}, // Addr: DEhDXhtUFuz6Uodhde3rznGbVbdiECahp1kTHnFpsna3, Notional: 0.080997 + {chain: 1, addr: "b5f7e08966fa2f997abc90d7a7cde1bc733f567b9eafc3007e80a3174726b6f6", symbol: "", coinGeckoId: "defi-land", decimals: 9, price: 0.00048809}, // Addr: DFL1zNkaGPWm1BqAVqRjCZvHmwTFrEaJtbzJWgseoNJh, Notional: 10.364179041477913 + {chain: 1, addr: "b7db4e83eb727f1187bd7a50303f5b4e4e943503da8571ad6564a51131504792", symbol: "", coinGeckoId: "wrapped-usdt-allbridge-from-polygon", decimals: 6, price: 1}, // Addr: DNhZkUaxHXYvpxZ7LNnHtss8sQgdAfd1ZYS1fB7LKWUZ, Notional: 42.194753 + {chain: 1, addr: "b814cbaa6004e889059e49841809b54c120f6d17c37cfaace4d28d394d56f67c", symbol: "SKBDI", coinGeckoId: "skibidi-toilet-2", decimals: 9, price: 0.16861}, // Addr: DPaQfq5sFnoqw2Sh9WMmmASFL9LNu6RdtDqwE1tab2tB, Notional: 0.16861 + {chain: 1, addr: "b953b5f8dd5457a2a0f0d41903409785b9d84d4045614faa4f505ee132dcd769", symbol: "DUST", coinGeckoId: "dust-protocol", decimals: 9, price: 0.126845}, // Addr: DUSTawucrTsGU8hcqRdHDCbuYhCPADMLM2VcCb8VnFnQ, Notional: 1192755.073239987 + {chain: 1, addr: "bbec677bca5169fbcaa1dccd44ef4badd3fe4d53bf3c9610379afe527256660a", symbol: "SOLNIC", coinGeckoId: "solnic", decimals: 6, price: 0.00879342}, // Addr: DeaKMzAeZja3Mh5okZE6WUvygLP3Lfuvm6Rg78HqXTz9, Notional: 33902.13468960065 + {chain: 1, addr: "bc07c56e60ad3d3f177382eac6548fba1fd32cfd90ca02b3e7cfa185fdce7398", symbol: "Bonk", coinGeckoId: "bonk", decimals: 5, price: 0.00003062}, // Addr: DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263, Notional: 18509214.92426475 + {chain: 1, addr: "bfc5f3a72f20be422f69837df545b8a5c992a9cb3e4687f61030f55ae9e3b235", symbol: "CRP", coinGeckoId: "cropperfinance", decimals: 9, price: 0.00144457}, // Addr: DubwWZNWiNGMMeeQHPnMATNj77YZPZSAz2WVR5WjLJqz, Notional: 1.1412103e-9 + {chain: 1, addr: "c206c5c565936e75a63aca8d62d7f2c27c21572474d7dd13e38424b0377f17af", symbol: "ADA", coinGeckoId: "ada-the-dog", decimals: 9, price: 0.00097295}, // Addr: E4Q5pLaEiejwEQHcM9GeYSQfMyGy8DJ4bPWgeYthn24v, Notional: 0.0029188499999999997 + {chain: 1, addr: "c261d86cf5cf877128ba1f5652e5f3dda599270c1556a15bc0a9aacf8063e563", symbol: "RIN", coinGeckoId: "aldrin", decimals: 9, price: 0.01544558}, // Addr: E5ndSkaB17Dm7CsD22dvcjfrYSDLCxFcMd6z8ddCk5wp, Notional: 0.013128743 + {chain: 1, addr: "c2667f39a3a7b6febb2f995eb4d1b739f45fe2edd645403c3e52e677e6bd6852", symbol: "WOO", coinGeckoId: "woo-network", decimals: 6, price: 0.207659}, // Addr: E5rk3nmgLUuKUiS94gg4bpWwWwyjCMtddsAXkTFLtHEy, Notional: 414.73222926303004 + {chain: 1, addr: "c28ee4128851e187510f75f9d61703da621ecbbb4b5b6e0d4b1fc21942f309a0", symbol: "DGLN", coinGeckoId: "dogelana", decimals: 9, price: 0.00000937}, // Addr: E6UU5M1z4CvSAAF99d9wRoXsasWMEXsvHrz3JQRXtm2X, Notional: 1.3391679024653 + {chain: 1, addr: "c3bc53a848c67ab3799f20a745a51e51c991946690c7c8a4b9a480aa29b07b94", symbol: "RPILL", coinGeckoId: "red-pill-2", decimals: 7, price: 0.00000137}, // Addr: EB54Nt1ydAgMR3edpaXEwb16R8TfF1enJ7zaYSefo7wH, Notional: 162007.03615519218 + {chain: 1, addr: "c44051a911b54c7ecffc7ee0b0a40af48b328ae755a99533c8402cb26df43807", symbol: "MOODENG", coinGeckoId: "moo-deng", decimals: 6, price: 0.266233}, // Addr: ED5nyyWEzpPPiWimP8vYm7sD7TD3LAt3Q3gRTWHzPJBY, Notional: 45275.61167488783 {chain: 1, addr: "c52e93ce650a3e02a70273e400132ed89b3bd67f2b839d4848593282bdec3ea0", symbol: "", coinGeckoId: "bitmon", decimals: 9, price: 0.00004538}, // Addr: EGiWZhNk3vUNJr35MbL2tY5YD6D81VVZghR2LgEFyXZh, Notional: 0.0743617047034104 - {chain: 1, addr: "c59cade70266477a5028970d5d9680bb9f1602dd393d05e3cfa8775ea818e6f8", symbol: "", coinGeckoId: "bozo-hybrid", decimals: 9, price: 0.010061}, // Addr: EJPtJEDogxzDbvM8qvAsqYbLmPj5n1vQeqoAzj9Yfv3q, Notional: 0.00027854472099 - {chain: 1, addr: "c5f9fb32f49111ab20c33f2598fc836c113e291881ac21ee29169394011244e4", symbol: "$WIF", coinGeckoId: "dogwifcoin", decimals: 6, price: 3.01}, // Addr: EKpQGSJtjMFqKZ9KQanSqYXRcF8fBopzLHYxdM65zcjm, Notional: 696954.43479753 - {chain: 1, addr: "c6fa7af3bedbad3a3d65f36aabc97431b1bbe4c2d2f6e0e47ca60203452f5d61", symbol: "USDC", coinGeckoId: "usd-coin", decimals: 6, price: 1}, // Addr: EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v, Notional: 4901334.033869 - {chain: 1, addr: "c7dc3552acd085ffa989b81b21e5e0bcbccbb1ec87835f0db12fabbad666ddf6", symbol: "MEDIA", coinGeckoId: "media-network", decimals: 6, price: 15.82}, // Addr: ETAtLmCmsoiEEKfNrHKJ2kYy3MoABhU6NQvpSfij5tDs, Notional: 32.3436736 - {chain: 1, addr: "c9a11f01cc857e5febddff9fd9e04cc82f44ec58ec6f19e23f5e7cca07ffb041", symbol: "PAI", coinGeckoId: "parrot-usd", decimals: 6, price: 0.981468}, // Addr: Ea5SjE2Y6yvCeW5dYTn7PYMuW5ikXkvbGdcmSnXeaLjS, Notional: 39.25872 - {chain: 1, addr: "ca4d39964c9cb5f9790d0a12969f60fd9724936284ea4a12daded42ddfa69c5d", symbol: "FIDA", coinGeckoId: "bonfida", decimals: 6, price: 0.322436}, // Addr: EchesyfXePKdLtoiZSL8pBe8Myagyy8ZRqsACNCFGnvp, Notional: 10.632755295008002 - {chain: 1, addr: "cc1bcd1d67c75bc278395ed463e45967941dd0ee02cc7327100d02c8730d1637", symbol: "TAURUS", coinGeckoId: "taurus-2", decimals: 6, price: 0.00307196}, // Addr: EjkkxYpfSwS6TAtKKuiJuNMMngYvumc1t1v9ZX1WJKMp, Notional: 7364.086944719821 - {chain: 1, addr: "ce010e60afedb22717bd63192f54145a3f965a33bb82d2c7029eb2ce1e208264", symbol: "USDT", coinGeckoId: "tether", decimals: 6, price: 1}, // Addr: Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB, Notional: 386940.189327 - {chain: 1, addr: "ced51ea8ae7d7670ce24e31fa7cc1f731ee3e02b91c017a37af71968cb17a290", symbol: "CHADCAT", coinGeckoId: "chad-cat", decimals: 9, price: 0.00022358}, // Addr: EvPUFsBikS1B3GpbmVvUWAc4DXaBXD4zLDER9SVSEF27, Notional: 0.139915180244511 - {chain: 1, addr: "cf3be585daf0d7aa080054c5ff622f468dbb2f49d086c5ca3230b60529e06103", symbol: "", coinGeckoId: "wrapped-cusd-allbridge-from-celo", decimals: 9, price: 1}, // Addr: EwxNF8g9UfmsJVcZFTpL9Hx5MCkoQFoJi6XNWzKf1j8e, Notional: 1.7 - {chain: 1, addr: "cfc61bb2ec4f1577d9b77f7d25db59555fa791bcea427ce294a390e3e127f82e", symbol: "VIRGO", coinGeckoId: "virgo-2", decimals: 6, price: 0.0036903}, // Addr: Ez4bst5qu5uqX3AntYWUdafw9XvtFeJ3gugytKKbSJso, Notional: 8149.964243608348 - {chain: 1, addr: "d670e7f1810e56d73423f0e3ccb3c5e6218211acda522599c494f893113305ab", symbol: "SMOG", coinGeckoId: "smog", decimals: 6, price: 0.02185386}, // Addr: FS66v5XYtJAFo14LiPz5HT93EUMAHmYipCfQhLpU4ss8, Notional: 925104.4392519547 - {chain: 1, addr: "d6c679aa7652867ebb3221cd90f5cf1d7f1b20e3bfd713c95de54bbdd6df2172", symbol: "wBIRD", coinGeckoId: "bird-money", decimals: 9, price: 2.04}, // Addr: FTPnEQ3NfRRZ9tvmpDW6JFrvweBE5sanxnXSpJL1dvbB, Notional: 0.40800000000000003 + {chain: 1, addr: "c59cade70266477a5028970d5d9680bb9f1602dd393d05e3cfa8775ea818e6f8", symbol: "", coinGeckoId: "bozo-hybrid", decimals: 9, price: 0.00822188}, // Addr: EJPtJEDogxzDbvM8qvAsqYbLmPj5n1vQeqoAzj9Yfv3q, Notional: 0.00022762759870920002 + {chain: 1, addr: "c5f9fb32f49111ab20c33f2598fc836c113e291881ac21ee29169394011244e4", symbol: "$WIF", coinGeckoId: "dogwifcoin", decimals: 6, price: 1.85}, // Addr: EKpQGSJtjMFqKZ9KQanSqYXRcF8fBopzLHYxdM65zcjm, Notional: 88974.87575845 + {chain: 1, addr: "c6fa7af3bedbad3a3d65f36aabc97431b1bbe4c2d2f6e0e47ca60203452f5d61", symbol: "USDC", coinGeckoId: "usd-coin", decimals: 6, price: 0.999339}, // Addr: EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v, Notional: 4733866.906423924 + {chain: 1, addr: "c7dc3552acd085ffa989b81b21e5e0bcbccbb1ec87835f0db12fabbad666ddf6", symbol: "MEDIA", coinGeckoId: "media-network", decimals: 6, price: 14.89}, // Addr: ETAtLmCmsoiEEKfNrHKJ2kYy3MoABhU6NQvpSfij5tDs, Notional: 30.442307200000002 + {chain: 1, addr: "c9a11f01cc857e5febddff9fd9e04cc82f44ec58ec6f19e23f5e7cca07ffb041", symbol: "PAI", coinGeckoId: "parrot-usd", decimals: 6, price: 0.958151}, // Addr: Ea5SjE2Y6yvCeW5dYTn7PYMuW5ikXkvbGdcmSnXeaLjS, Notional: 38.32604 + {chain: 1, addr: "ca4d39964c9cb5f9790d0a12969f60fd9724936284ea4a12daded42ddfa69c5d", symbol: "FIDA", coinGeckoId: "bonfida", decimals: 6, price: 0.241845}, // Addr: EchesyfXePKdLtoiZSL8pBe8Myagyy8ZRqsACNCFGnvp, Notional: 7.975160045160001 + {chain: 1, addr: "cc1bcd1d67c75bc278395ed463e45967941dd0ee02cc7327100d02c8730d1637", symbol: "TAURUS", coinGeckoId: "taurus-2", decimals: 6, price: 0.00348625}, // Addr: EjkkxYpfSwS6TAtKKuiJuNMMngYvumc1t1v9ZX1WJKMp, Notional: 7933.445927739062 + {chain: 1, addr: "ce010e60afedb22717bd63192f54145a3f965a33bb82d2c7029eb2ce1e208264", symbol: "USDT", coinGeckoId: "tether", decimals: 6, price: 0.99789}, // Addr: Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB, Notional: 390458.5323116944 + {chain: 1, addr: "ceaf14fcf7cb2ed5003289247656f3427aa86c1cee4185effcc253e7a8fe403a", symbol: "LAIKA", coinGeckoId: "the-soldog", decimals: 6, price: 0.00001561}, // Addr: Euoq6CyQFCjCVSLR9wFaUPDW19Y6ZHwEcJoZsEi643i1, Notional: 0.004839100000000001 + {chain: 1, addr: "ced51ea8ae7d7670ce24e31fa7cc1f731ee3e02b91c017a37af71968cb17a290", symbol: "CHADCAT", coinGeckoId: "chad-cat", decimals: 9, price: 0.00008347}, // Addr: EvPUFsBikS1B3GpbmVvUWAc4DXaBXD4zLDER9SVSEF27, Notional: 0.0522350840639115 + {chain: 1, addr: "cf3be585daf0d7aa080054c5ff622f468dbb2f49d086c5ca3230b60529e06103", symbol: "", coinGeckoId: "wrapped-cusd-allbridge-from-celo", decimals: 9, price: 0.999223}, // Addr: EwxNF8g9UfmsJVcZFTpL9Hx5MCkoQFoJi6XNWzKf1j8e, Notional: 1.6986790999999999 + {chain: 1, addr: "cfc61bb2ec4f1577d9b77f7d25db59555fa791bcea427ce294a390e3e127f82e", symbol: "VIRGO", coinGeckoId: "virgo-2", decimals: 6, price: 0.00258387}, // Addr: Ez4bst5qu5uqX3AntYWUdafw9XvtFeJ3gugytKKbSJso, Notional: 6461.147952855022 + {chain: 1, addr: "d670e7f1810e56d73423f0e3ccb3c5e6218211acda522599c494f893113305ab", symbol: "SMOG", coinGeckoId: "smog", decimals: 6, price: 0.01655615}, // Addr: FS66v5XYtJAFo14LiPz5HT93EUMAHmYipCfQhLpU4ss8, Notional: 704352.2414005545 + {chain: 1, addr: "d6c679aa7652867ebb3221cd90f5cf1d7f1b20e3bfd713c95de54bbdd6df2172", symbol: "wBIRD", coinGeckoId: "bird-money", decimals: 9, price: 0.856385}, // Addr: FTPnEQ3NfRRZ9tvmpDW6JFrvweBE5sanxnXSpJL1dvbB, Notional: 0.171277 {chain: 1, addr: "d6de2876953718f8ae61f7a6da3b0869cc770dbe30d86458f46467d8ed1bf499", symbol: "", coinGeckoId: "synex-coin", decimals: 9, price: 0.00037006}, // Addr: FTkj421DxbS1wajE74J34BJ5a1o9ccA97PkK6mYq9hNQ, Notional: 0.018503000000000002 - {chain: 1, addr: "d813ffacd702778f0e56a4224bc22b7c2644dfa713fe929fec09c5fae093a802", symbol: "MC", coinGeckoId: "tap-fantasy-mc", decimals: 9, price: 0.108047}, // Addr: FYUkUybywqUUyrUwiAezbvhTp2DUgx1eg8tQNiKkXqJ9, Notional: 0.0091064928869 + {chain: 1, addr: "d813ffacd702778f0e56a4224bc22b7c2644dfa713fe929fec09c5fae093a802", symbol: "MC", coinGeckoId: "tap-fantasy-mc", decimals: 9, price: 0.131966}, // Addr: FYUkUybywqUUyrUwiAezbvhTp2DUgx1eg8tQNiKkXqJ9, Notional: 0.0111224507882 {chain: 1, addr: "d9299d4dd5f2e8021a5f9d220ee6499ed7ce916b4455042a172fd08cee33065e", symbol: "TGT", coinGeckoId: "twirl-governance-token", decimals: 6, price: 0.00206801}, // Addr: FciGvHj9FjgSGgCBF1b9HY814FM9D28NijDd5SJrKvPo, Notional: 0.010546851 {chain: 1, addr: "d9f5f028b2262005f14736d01e0115d02ecbf82513a58b8c0525c5537a186f41", symbol: "BOO", coinGeckoId: "boo", decimals: 6, price: 2.25488e-10}, // Addr: FfpyoV365c7iR8QQg5NHGCXQfahbqzY67B3wpzXkiLXr, Notional: 0.0009470496 - {chain: 1, addr: "db532dd1df8e6c87ca70695ddf92f8d86e621d0d86de69c3058de9b29ee22647", symbol: "", coinGeckoId: "monkeyball", decimals: 6, price: 0.02384234}, // Addr: Fm9rHUTF5v3hwMLbStjZXqNBBoZyGriQaFM6sTFz3K8A, Notional: 3.34392504525764 - {chain: 1, addr: "db9f5cc7f4249010132350e743d99e2a30f0a264b8b345cf23622f0e4eca9d14", symbol: "SYP", coinGeckoId: "sypool", decimals: 9, price: 0.00048438}, // Addr: FnKE9n6aGjQoNWRBZXy4RW6LZVao7qwBonUbiD7edUmZ, Notional: 2081.6963576787416 - {chain: 1, addr: "dbe7c49c3d365abe845bb853bf8a6e8a42743847fd0611ffba1a410b3f22639e", symbol: "FORGE", coinGeckoId: "blocksmith-labs-forge", decimals: 9, price: 0.01651007}, // Addr: FoRGERiW7odcCBGU1bztZi16osPBHjxharvDathL5eds, Notional: 0.021351449081156503 - {chain: 1, addr: "dbef5aa1e0f0042edd619a2f68fd3e4df833325dd2037fcc6bb3b6ed0cb7508e", symbol: "", coinGeckoId: "famous-fox-federation", decimals: 0, price: 0.00272131}, // Addr: FoXyMu5xwXre7zEoSvzViRk3nGawHUp9kUh97y2NDhcq, Notional: 12.90989464 - {chain: 1, addr: "dd40a2f6f423e4c3990a83eac3d9d9c1fe625b36cbc5e4a6d553544552a867ee", symbol: "BRZ", coinGeckoId: "brz", decimals: 4, price: 0.159991}, // Addr: FtgGSFADXBtroxq8VCausXRr2of47QBf5AS1NtZCu4GD, Notional: 4127.133067705699 - {chain: 1, addr: "e24bdeaeffa04f43b8771a420b80061cf093260db29ac9c8ead65058a97f7857", symbol: "", coinGeckoId: "genopets", decimals: 9, price: 0.117324}, // Addr: GENEtH5amGSi8kHAtQoezp1XEXwZJ8vcuePYnXdKrMYz, Notional: 1.55868074059536 - {chain: 1, addr: "e2975e097997188b8c83cf5b64f28ff42b1ae579b1b6747857bf722150de7fb0", symbol: "GOFX", coinGeckoId: "goosefx", decimals: 9, price: 0.00380373}, // Addr: GFX1ZjR2P15tmrSwow6FjyDYcEkoFb4p4gJCpLBjaxHD, Notional: 0.00760746 - {chain: 1, addr: "e334cd4a3826672ea4c5394a042929c94638ecee0deeae37fbd41e396d06fc77", symbol: "SOLAPE", coinGeckoId: "solape-token", decimals: 9, price: 0.00077909}, // Addr: GHvFFSZ9BctWsEc5nujR1MTmmJWY7tgQz2AXE6WVFtGN, Notional: 0.00077909 - {chain: 1, addr: "e350770814014371e2277d39b550570dd02e77db5f266e58f68f023c277f14af", symbol: "ily", coinGeckoId: "iiii-lovvv-youuuu", decimals: 6, price: 0.00552654}, // Addr: GJLiErro8cbWeDngDMWJug9dkwwckYZg4Lvb79F3pump, Notional: 246.93718431209328 + {chain: 1, addr: "db532dd1df8e6c87ca70695ddf92f8d86e621d0d86de69c3058de9b29ee22647", symbol: "", coinGeckoId: "monkeyball", decimals: 6, price: 0.01713571}, // Addr: Fm9rHUTF5v3hwMLbStjZXqNBBoZyGriQaFM6sTFz3K8A, Notional: 2.4033098193076596 + {chain: 1, addr: "db9f5cc7f4249010132350e743d99e2a30f0a264b8b345cf23622f0e4eca9d14", symbol: "SYP", coinGeckoId: "sypool", decimals: 9, price: 0.00031888}, // Addr: FnKE9n6aGjQoNWRBZXy4RW6LZVao7qwBonUbiD7edUmZ, Notional: 1831.9574754802063 + {chain: 1, addr: "dbe7c49c3d365abe845bb853bf8a6e8a42743847fd0611ffba1a410b3f22639e", symbol: "FORGE", coinGeckoId: "blocksmith-labs-forge", decimals: 9, price: 0.012355}, // Addr: FoRGERiW7odcCBGU1bztZi16osPBHjxharvDathL5eds, Notional: 0.01597795487225 + {chain: 1, addr: "dbef5aa1e0f0042edd619a2f68fd3e4df833325dd2037fcc6bb3b6ed0cb7508e", symbol: "", coinGeckoId: "famous-fox-federation", decimals: 0, price: 0.00298224}, // Addr: FoXyMu5xwXre7zEoSvzViRk3nGawHUp9kUh97y2NDhcq, Notional: 14.14774656 + {chain: 1, addr: "dd40a2f6f423e4c3990a83eac3d9d9c1fe625b36cbc5e4a6d553544552a867ee", symbol: "BRZ", coinGeckoId: "brz", decimals: 4, price: 0.16085}, // Addr: FtgGSFADXBtroxq8VCausXRr2of47QBf5AS1NtZCu4GD, Notional: 4149.291859795 + {chain: 1, addr: "e24bdeaeffa04f43b8771a420b80061cf093260db29ac9c8ead65058a97f7857", symbol: "", coinGeckoId: "genopets", decimals: 9, price: 0.124587}, // Addr: GENEtH5amGSi8kHAtQoezp1XEXwZJ8vcuePYnXdKrMYz, Notional: 1.65517163946468 + {chain: 1, addr: "e2975e097997188b8c83cf5b64f28ff42b1ae579b1b6747857bf722150de7fb0", symbol: "GOFX", coinGeckoId: "goosefx", decimals: 9, price: 0.00421538}, // Addr: GFX1ZjR2P15tmrSwow6FjyDYcEkoFb4p4gJCpLBjaxHD, Notional: 0.00843076 + {chain: 1, addr: "e334cd4a3826672ea4c5394a042929c94638ecee0deeae37fbd41e396d06fc77", symbol: "SOLAPE", coinGeckoId: "solape-token", decimals: 9, price: 0.00055333}, // Addr: GHvFFSZ9BctWsEc5nujR1MTmmJWY7tgQz2AXE6WVFtGN, Notional: 0.00055333 + {chain: 1, addr: "e350770814014371e2277d39b550570dd02e77db5f266e58f68f023c277f14af", symbol: "ily", coinGeckoId: "iiii-lovvv-youuuu", decimals: 6, price: 0.00293926}, // Addr: GJLiErro8cbWeDngDMWJug9dkwwckYZg4Lvb79F3pump, Notional: 131.33218765469232 {chain: 1, addr: "e66b5c6e86ec048a73a370e0588e1dcbaa16f532b8e5790eb830386b3ae947fc", symbol: "", coinGeckoId: "galaxy-war", decimals: 6, price: 0.00011302}, // Addr: GWTipxSJVPmmW2wCjBdkbnEJbCRCyrhL2x9zuHRPPTj1, Notional: 1.16168541313736 {chain: 1, addr: "e67a4e87ce4d1df99623ee52b47b2675bfa1dc3c875eac60533c6e7cc6daee27", symbol: "", coinGeckoId: "1safu", decimals: 0, price: 5.329e-9}, // Addr: GWgwUUrgai3BFeEJZp7bdsBSYiuDqNmHf9uRusWsf3Yi, Notional: 0.000647766595 - {chain: 1, addr: "e8aea53120492d4b007a41f4fea777ac914c36dc21f944614e9a96ebe0a18367", symbol: "SOLPAD", coinGeckoId: "solpad-finance", decimals: 9, price: 0.00004957}, // Addr: GfJ3Vq2eSTYf1hJP6kKLE9RT6u7jF9gNszJhZwo5VPZp, Notional: 0.0023110889853511004 - {chain: 1, addr: "e92f2b9eb212cdc7941a829712babcb7a6697f8b94710f05ba381666130d96d1", symbol: "ARIES", coinGeckoId: "aries", decimals: 6, price: 0.00293517}, // Addr: GhFiFrExPY3proVF96oth1gESWA5QPQzdtb8cy8b1YZv, Notional: 7264.874696057541 - {chain: 1, addr: "e9e5418ae527093d6a777adabea125d9681dd77643ac339e6ec487865c928672", symbol: "$PTRUMP", coinGeckoId: "pepe-trump", decimals: 6, price: 0.00098935}, // Addr: Gk2kRrwNMBU4Dn9JhC1Dks8G5X9nqi4ZE5jMvK6bdgEd, Notional: 21301.060333308946 - {chain: 1, addr: "eac40dce1cfccb5ca30a878aebb3025763a8d3f0c4f15c3e858b98899982b71f", symbol: "KSG", coinGeckoId: "king-sugar-glider", decimals: 6, price: 0.00005543}, // Addr: GoRnxWR5h4HMYAbCWhfPxsTF6N27jTRkBDFpAsvLpump, Notional: 9.139892777054031 - {chain: 1, addr: "ebc7380b4b2467a56f247d9d83635f45df774bd341fe028ef56b45607bfe256c", symbol: "DXL", coinGeckoId: "dexlab", decimals: 6, price: 0.00169779}, // Addr: GsNzxJfFn6zQdJGeYsupJWzUAm57Ba7335mfhWvFiE9Z, Notional: 0.0000075246052800000004 + {chain: 1, addr: "e8aea53120492d4b007a41f4fea777ac914c36dc21f944614e9a96ebe0a18367", symbol: "SOLPAD", coinGeckoId: "solpad-finance", decimals: 9, price: 0.000044}, // Addr: GfJ3Vq2eSTYf1hJP6kKLE9RT6u7jF9gNszJhZwo5VPZp, Notional: 0.00205140035012 + {chain: 1, addr: "e92f2b9eb212cdc7941a829712babcb7a6697f8b94710f05ba381666130d96d1", symbol: "ARIES", coinGeckoId: "aries", decimals: 6, price: 0.00258061}, // Addr: GhFiFrExPY3proVF96oth1gESWA5QPQzdtb8cy8b1YZv, Notional: 6611.275919426002 + {chain: 1, addr: "e9e5418ae527093d6a777adabea125d9681dd77643ac339e6ec487865c928672", symbol: "$PTRUMP", coinGeckoId: "pepe-trump", decimals: 6, price: 0.00091134}, // Addr: Gk2kRrwNMBU4Dn9JhC1Dks8G5X9nqi4ZE5jMvK6bdgEd, Notional: 25388.894298453157 + {chain: 1, addr: "eac40dce1cfccb5ca30a878aebb3025763a8d3f0c4f15c3e858b98899982b71f", symbol: "KSG", coinGeckoId: "king-sugar-glider", decimals: 6, price: 0.00003592}, // Addr: GoRnxWR5h4HMYAbCWhfPxsTF6N27jTRkBDFpAsvLpump, Notional: 5.922874770914321 + {chain: 1, addr: "ebc7380b4b2467a56f247d9d83635f45df774bd341fe028ef56b45607bfe256c", symbol: "DXL", coinGeckoId: "dexlab", decimals: 6, price: 0.00087509}, // Addr: GsNzxJfFn6zQdJGeYsupJWzUAm57Ba7335mfhWvFiE9Z, Notional: 0.00000387839888 {chain: 1, addr: "ebd47511adbd4c48202bc2d335138ce08fca42964e99e08126d8cdd78f974985", symbol: "gSAIL", coinGeckoId: "solanasail-governance-token", decimals: 9, price: 0.00589147}, // Addr: Gsai2KN28MTGcSZ1gKYFswUpFpS7EM9mvdR9c8f6iVXJ, Notional: 0.01767441 - {chain: 1, addr: "ecc960fbf1d75d4051dc9833005626b0556325ab2a1d2eaeba5e1241e479a699", symbol: "LLD", coinGeckoId: "liberland-lld", decimals: 8, price: 1.9}, // Addr: GwKKPsJdY5oWMJ8RReWLcvb82KzW6FKy2bKoYW7kHr16, Notional: 2.634424822 - {chain: 1, addr: "edcc10dafe9e4643d0397fb1ffa280b7a3c28090ebfe4816c3e0f39b9d7ca411", symbol: "SBONK", coinGeckoId: "shibonk-311f81df-a4ea-4f31-9e61-df0af8211bd7", decimals: 9, price: 1.44}, // Addr: H1G6sZ1WDoMmMCFqBKAbg9gkQPCo1sKQtaJWz9dHmqZr, Notional: 2.4478964784 - {chain: 1, addr: "f204ae4a202016d4de45496d2b0becaa650f1e9a58c02426f4190166488f4d9c", symbol: "", coinGeckoId: "pip", decimals: 9, price: 0.03276757}, // Addr: HHjoYwUp5aU6pnrvN4s2pwEErwXNZKhxKGYjRJMoBjLw, Notional: 11.075766335700001 + {chain: 1, addr: "ecc960fbf1d75d4051dc9833005626b0556325ab2a1d2eaeba5e1241e479a699", symbol: "LLD", coinGeckoId: "liberland-lld", decimals: 8, price: 1.68}, // Addr: GwKKPsJdY5oWMJ8RReWLcvb82KzW6FKy2bKoYW7kHr16, Notional: 2.3293861584 + {chain: 1, addr: "edcc10dafe9e4643d0397fb1ffa280b7a3c28090ebfe4816c3e0f39b9d7ca411", symbol: "SBONK", coinGeckoId: "shibonk-311f81df-a4ea-4f31-9e61-df0af8211bd7", decimals: 9, price: 1.4}, // Addr: H1G6sZ1WDoMmMCFqBKAbg9gkQPCo1sKQtaJWz9dHmqZr, Notional: 2.379899354 + {chain: 1, addr: "f204ae4a202016d4de45496d2b0becaa650f1e9a58c02426f4190166488f4d9c", symbol: "", coinGeckoId: "pip", decimals: 9, price: 0.04171439}, // Addr: HHjoYwUp5aU6pnrvN4s2pwEErwXNZKhxKGYjRJMoBjLw, Notional: 14.099880963899999 {chain: 1, addr: "f207dc9bd5545f9674a6b087ef55a585e8580a192f412de0890e91f735201049", symbol: "clAPT", coinGeckoId: "cloned-aptos", decimals: 8, price: 3.67}, // Addr: HHncifGW3yJyaW2fRRfBYAawnD9ogbsWM5PccFA4GHSx, Notional: 0.5642172488999999 - {chain: 1, addr: "f23cba7173364712aaa6114393f2c187b8d8b5194abaa872ada605fa8820b61f", symbol: "", coinGeckoId: "atlas-dex", decimals: 9, price: 0.00274264}, // Addr: HJbNXx2YMRxgfUJ6K4qeWtjatMK5KYQT1QnsCdDWywNv, Notional: 0.251232885749472 - {chain: 1, addr: "f51829ba389a574812109c6de6051e77c7a003ba666a26d13d30c51c51f7e94e", symbol: "", coinGeckoId: "visiongame", decimals: 9, price: 0.00280725}, // Addr: HVkFqcMHevVPb4XKrf4XowjEaVVsBoqJ2U1EG59Dfk5j, Notional: 97.59832365963224 - {chain: 1, addr: "f5edec8471c75624ebc4079a634326d96a689e6157d79abe8f5a6f94472853bc", symbol: "PYTH", coinGeckoId: "pyth-network", decimals: 6, price: 0.46658}, // Addr: HZ1JovNiVvGrGNiiYvEozEVgZ58xaU3RKwX8eACQBCt3, Notional: 1592299.2642765471 - {chain: 1, addr: "f79a6689e1ee9439000424c51198bfa4f0510ea523204ce8ec639c3fa8ebb916", symbol: "", coinGeckoId: "cryowar-token", decimals: 9, price: 0.00436386}, // Addr: HfYFjMKNZygfMC8LsQ8LtpPsPxEJoXJx4M6tqi75Hajo, Notional: 8.72772 - {chain: 1, addr: "f926de74d018c7be81c476f359aaacba61b762767977d2565c9eb57682011706", symbol: "PSOL", coinGeckoId: "parasol-finance", decimals: 7, price: 0.00497243}, // Addr: Hmatmu1ktLbobSvim94mfpZmjL5iiyoM1zidtXJRAdLZ, Notional: 0.00497243 - {chain: 1, addr: "faf2d6df73cb4778b625966d4fba883fd424a80497d5e31c934352ade1d1bdc9", symbol: "", coinGeckoId: "dead-knight", decimals: 9, price: 0.00001916}, // Addr: HtbhBYdcfXbbD2JiH6jtsTt2m2FXjn7h4k6iXfz98k5W, Notional: 0.00898125 - {chain: 1, addr: "fcd141e9832caf10ad917495ca0f271b5b293cd47027ea737007ed40eb39a0bd", symbol: "JitoSOL", coinGeckoId: "jito-staked-sol", decimals: 9, price: 257.81}, // Addr: J1toso1uCk3RLmjorhTtrVwY9HJ7X8V9yYac6Y7kGCPn, Notional: 660535.5664830321 - {chain: 1, addr: "fd86d81bd924f3cfc702ea40b8d30705f75c387a23d9a8e22ff1d6e52a8a3b54", symbol: "SCORPIO", coinGeckoId: "scorpio", decimals: 6, price: 0.00306706}, // Addr: J4fQTRN13MKpXhVE74t99msKJLbrjegjEgLBnzEv2YH1, Notional: 7073.263856300055 + {chain: 1, addr: "f23cba7173364712aaa6114393f2c187b8d8b5194abaa872ada605fa8820b61f", symbol: "", coinGeckoId: "atlas-dex", decimals: 9, price: 0.00244359}, // Addr: HJbNXx2YMRxgfUJ6K4qeWtjatMK5KYQT1QnsCdDWywNv, Notional: 0.223839135755532 + {chain: 1, addr: "f51829ba389a574812109c6de6051e77c7a003ba666a26d13d30c51c51f7e94e", symbol: "", coinGeckoId: "visiongame", decimals: 9, price: 0.00250917}, // Addr: HVkFqcMHevVPb4XKrf4XowjEaVVsBoqJ2U1EG59Dfk5j, Notional: 87.23511827483816 + {chain: 1, addr: "f5edec8471c75624ebc4079a634326d96a689e6157d79abe8f5a6f94472853bc", symbol: "PYTH", coinGeckoId: "pyth-network", decimals: 6, price: 0.351187}, // Addr: HZ1JovNiVvGrGNiiYvEozEVgZ58xaU3RKwX8eACQBCt3, Notional: 1208954.7282928037 + {chain: 1, addr: "f79a6689e1ee9439000424c51198bfa4f0510ea523204ce8ec639c3fa8ebb916", symbol: "", coinGeckoId: "cryowar-token", decimals: 9, price: 0.00346304}, // Addr: HfYFjMKNZygfMC8LsQ8LtpPsPxEJoXJx4M6tqi75Hajo, Notional: 6.926080000000001 + {chain: 1, addr: "f926de74d018c7be81c476f359aaacba61b762767977d2565c9eb57682011706", symbol: "PSOL", coinGeckoId: "parasol-finance", decimals: 7, price: 0.00493733}, // Addr: Hmatmu1ktLbobSvim94mfpZmjL5iiyoM1zidtXJRAdLZ, Notional: 0.00493733 + {chain: 1, addr: "faf2d6df73cb4778b625966d4fba883fd424a80497d5e31c934352ade1d1bdc9", symbol: "", coinGeckoId: "dead-knight", decimals: 9, price: 0.0000154}, // Addr: HtbhBYdcfXbbD2JiH6jtsTt2m2FXjn7h4k6iXfz98k5W, Notional: 0.00721875 + {chain: 1, addr: "fcd141e9832caf10ad917495ca0f271b5b293cd47027ea737007ed40eb39a0bd", symbol: "JitoSOL", coinGeckoId: "jito-staked-sol", decimals: 9, price: 222.33}, // Addr: J1toso1uCk3RLmjorhTtrVwY9HJ7X8V9yYac6Y7kGCPn, Notional: 126260.6514706989 + {chain: 1, addr: "fd86d81bd924f3cfc702ea40b8d30705f75c387a23d9a8e22ff1d6e52a8a3b54", symbol: "SCORPIO", coinGeckoId: "scorpio", decimals: 6, price: 0.00259934}, // Addr: J4fQTRN13MKpXhVE74t99msKJLbrjegjEgLBnzEv2YH1, Notional: 6414.802954127421 {chain: 1, addr: "fe41912ceb0b2cb23badaac80e3b41d42cbe0e0c999ccdec5cf0d70bc3e2ccd1", symbol: "", coinGeckoId: "mongoosecoin", decimals: 9, price: 3.4275e-8}, // Addr: J7WYVzFNynk9D28eBCccw2EYkygygiLDCVCabV7CupWL, Notional: 0.0000068550000000000004 - {chain: 2, addr: "0000000000000000000000000001a500a6b18995b03f44bb040a5ffc28e45cb0", symbol: "OLAS", coinGeckoId: "autonolas", decimals: 18, price: 2.2}, // Addr: 0x0001a500a6b18995b03f44bb040a5ffc28e45cb0, Notional: 1793941.22852406 - {chain: 2, addr: "000000000000000000000000009178997aff09a67d4caccfeb897fb79d036214", symbol: "1SOL", coinGeckoId: "1sol", decimals: 18, price: 0.01091323}, // Addr: 0x009178997aff09a67d4caccfeb897fb79d036214, Notional: 1018509.2551439271 - {chain: 2, addr: "00000000000000000000000000a8b738e453ffd858a7edf03bccfe20412f0eb0", symbol: "ALBT", coinGeckoId: "allianceblock", decimals: 18, price: 0.00011872}, // Addr: 0x00a8b738e453ffd858a7edf03bccfe20412f0eb0, Notional: 0.0173246051451648 - {chain: 2, addr: "00000000000000000000000000c5ca160a968f47e7272a0cfcda36428f386cb6", symbol: "USDEBT", coinGeckoId: "usdebt", decimals: 18, price: 1.0865e-8}, // Addr: 0x00c5ca160a968f47e7272a0cfcda36428f386cb6, Notional: 1956.7462708119374 - {chain: 2, addr: "00000000000000000000000000e679ba63b509182c349f5614f0a07cdd0ce0c5", symbol: "DAMEX", coinGeckoId: "damex-token", decimals: 18, price: 0.00195043}, // Addr: 0x00e679ba63b509182c349f5614f0a07cdd0ce0c5, Notional: 1.170258 - {chain: 2, addr: "000000000000000000000000030ba81f1c18d280636f32af80b9aad02cf0854e", symbol: "aWETH", coinGeckoId: "aave-weth", decimals: 18, price: 3590.67}, // Addr: 0x030ba81f1c18d280636f32af80b9aad02cf0854e, Notional: 1077.2478223368 - {chain: 2, addr: "0000000000000000000000000316eb71485b0ab14103307bf65a021042c6d380", symbol: "HBTC", coinGeckoId: "huobi-btc", decimals: 18, price: 4519.07}, // Addr: 0x0316eb71485b0ab14103307bf65a021042c6d380, Notional: 459.26585358799997 - {chain: 2, addr: "00000000000000000000000003ab458634910aad20ef5f1c8ee96f1d6ac54919", symbol: "RAI", coinGeckoId: "rai", decimals: 18, price: 3.03}, // Addr: 0x03ab458634910aad20ef5f1c8ee96f1d6ac54919, Notional: 9.09 - {chain: 2, addr: "00000000000000000000000003be5c903c727ee2c8c4e9bc0acc860cca4715e2", symbol: "CAPS", coinGeckoId: "coin-capsule", decimals: 18, price: 0.00440586}, // Addr: 0x03be5c903c727ee2c8c4e9bc0acc860cca4715e2, Notional: 803.6992634567964 - {chain: 2, addr: "000000000000000000000000046eee2cc3188071c02bfc1745a6b17c656e3f3d", symbol: "RLB", coinGeckoId: "rollbit-coin", decimals: 18, price: 0.109263}, // Addr: 0x046eee2cc3188071c02bfc1745a6b17c656e3f3d, Notional: 362.75316 - {chain: 2, addr: "00000000000000000000000004815313e9329e8905a77251a1781cfa7934259a", symbol: "HOOD", coinGeckoId: "wagmicatgirlkanye420etfmoon1000x", decimals: 18, price: 0.00002241}, // Addr: 0x04815313e9329e8905a77251a1781cfa7934259a, Notional: 70855.62000906192 - {chain: 2, addr: "00000000000000000000000004969cd041c0cafb6ac462bd65b536a5bdb3a670", symbol: "wOMI", coinGeckoId: "wrapped-ecomi", decimals: 18, price: 0.00071847}, // Addr: 0x04969cd041c0cafb6ac462bd65b536a5bdb3a670, Notional: 13.489055472501008 - {chain: 2, addr: "00000000000000000000000004c154b66cb340f3ae24111cc767e0184ed00cc6", symbol: "pxETH", coinGeckoId: "dinero-staked-eth", decimals: 18, price: 3584.71}, // Addr: 0x04c154b66cb340f3ae24111cc767e0184ed00cc6, Notional: 196394.9440063771 - {chain: 2, addr: "000000000000000000000000054d64b73d3d8a21af3d764efd76bcaa774f3bb2", symbol: "PPAY", coinGeckoId: "plasma-finance", decimals: 18, price: 0.00010068}, // Addr: 0x054d64b73d3d8a21af3d764efd76bcaa774f3bb2, Notional: 959.0107120989871 - {chain: 2, addr: "00000000000000000000000005d3606d5c81eb9b7b18530995ec9b29da05faba", symbol: "TOMOE", coinGeckoId: "tomoe", decimals: 18, price: 0.457214}, // Addr: 0x05d3606d5c81eb9b7b18530995ec9b29da05faba, Notional: 45721.4 - {chain: 2, addr: "00000000000000000000000006450dee7fd2fb8e39061434babcfc05599a6fb8", symbol: "XEN", coinGeckoId: "xen-crypto", decimals: 18, price: 1.12695e-7}, // Addr: 0x06450dee7fd2fb8e39061434babcfc05599a6fb8, Notional: 0.00112807695 - {chain: 2, addr: "00000000000000000000000006af07097c9eeb7fd685c692751d5c66db49c215", symbol: "CHAI", coinGeckoId: "chai", decimals: 18, price: 1.2}, // Addr: 0x06af07097c9eeb7fd685c692751d5c66db49c215, Notional: 9317916.255513707 - {chain: 2, addr: "00000000000000000000000006e0feb0d74106c7ada8497754074d222ec6bcdf", symbol: "BTB", coinGeckoId: "bitball", decimals: 18, price: 0.00004}, // Addr: 0x06e0feb0d74106c7ada8497754074d222ec6bcdf, Notional: 360.00000000000006 - {chain: 2, addr: "0000000000000000000000000763fdccf1ae541a5961815c0872a8c5bc6de4d7", symbol: "SUKU", coinGeckoId: "suku", decimals: 18, price: 0.088248}, // Addr: 0x0763fdccf1ae541a5961815c0872a8c5bc6de4d7, Notional: 2.0772548657505596 - {chain: 2, addr: "000000000000000000000000081131434f93063751813c619ecca9c4dc7862a3", symbol: "DAR", coinGeckoId: "mines-of-dalarnia", decimals: 6, price: 0.18792}, // Addr: 0x081131434f93063751813c619ecca9c4dc7862a3, Notional: 200.20978214712 - {chain: 2, addr: "00000000000000000000000008389495d7456e1951ddf7c3a1314a4bfb646d8b", symbol: "CRPT", coinGeckoId: "crypterium", decimals: 18, price: 0.01846974}, // Addr: 0x08389495d7456e1951ddf7c3a1314a4bfb646d8b, Notional: 0.62797116 - {chain: 2, addr: "00000000000000000000000008d967bb0134f2d07f7cfb6e246680c53927dd30", symbol: "MATH", coinGeckoId: "math", decimals: 18, price: 0.312206}, // Addr: 0x08d967bb0134f2d07f7cfb6e246680c53927dd30, Notional: 1549912.2467391903 - {chain: 2, addr: "000000000000000000000000090185f2135308bad17527004364ebcc2d37e5f6", symbol: "SPELL", coinGeckoId: "spell-token", decimals: 18, price: 0.00093684}, // Addr: 0x090185f2135308bad17527004364ebcc2d37e5f6, Notional: 0.00093684 - {chain: 2, addr: "00000000000000000000000009a3ecafa817268f77be1283176b946c4ff2e608", symbol: "MIR", coinGeckoId: "mirror-protocol", decimals: 18, price: 0.0324267}, // Addr: 0x09a3ecafa817268f77be1283176b946c4ff2e608, Notional: 283.81584762598715 - {chain: 2, addr: "0000000000000000000000000a638f07acc6969abf392bb009f216d22adea36d", symbol: "BKN", coinGeckoId: "brickken", decimals: 18, price: 0.492973}, // Addr: 0x0a638f07acc6969abf392bb009f216d22adea36d, Notional: 4211248.990532573 - {chain: 2, addr: "0000000000000000000000000ab87046fbb341d058f17cbc4c1133f25a20a52f", symbol: "gOHM", coinGeckoId: "governance-ohm", decimals: 18, price: 4856.15}, // Addr: 0x0ab87046fbb341d058f17cbc4c1133f25a20a52f, Notional: 812.1322795235 - {chain: 2, addr: "0000000000000000000000000b61c4f33bcdef83359ab97673cb5961c6435f4e", symbol: "EARN", coinGeckoId: "hold-2", decimals: 18, price: 0.00469054}, // Addr: 0x0b61c4f33bcdef83359ab97673cb5961c6435f4e, Notional: 27.411858936370194 - {chain: 2, addr: "0000000000000000000000000bc529c00c6401aef6d220be8c6ea1667f6ad93e", symbol: "YFI", coinGeckoId: "yearn-finance", decimals: 18, price: 7838.88}, // Addr: 0x0bc529c00c6401aef6d220be8c6ea1667f6ad93e, Notional: 259998.17877458883 - {chain: 2, addr: "0000000000000000000000000c572544a4ee47904d54aaa6a970af96b6f00e1b", symbol: "WAS", coinGeckoId: "wasder", decimals: 18, price: 0.00197845}, // Addr: 0x0c572544a4ee47904d54aaa6a970af96b6f00e1b, Notional: 1715.5835721860774 - {chain: 2, addr: "0000000000000000000000000d505c03d30e65f6e9b4ef88855a47a89e4b7676", symbol: "ZOOMER", coinGeckoId: "zoomer", decimals: 18, price: 0.00003564}, // Addr: 0x0d505c03d30e65f6e9b4ef88855a47a89e4b7676, Notional: 60882.804792036084 - {chain: 2, addr: "0000000000000000000000000d5639a1442730372e2a650a2900ba07937854f4", symbol: "CHUB", coinGeckoId: "callhub", decimals: 18, price: 0.01873251}, // Addr: 0x0d5639a1442730372e2a650a2900ba07937854f4, Notional: 112.39506 - {chain: 2, addr: "0000000000000000000000000d8775f648430679a709e98d2b0cb6250d2887ef", symbol: "BAT", coinGeckoId: "basic-attention-token", decimals: 18, price: 0.297146}, // Addr: 0x0d8775f648430679a709e98d2b0cb6250d2887ef, Notional: 285039.0473220813 - {chain: 2, addr: "0000000000000000000000000e186357c323c806c1efdad36d217f7a54b63d18", symbol: "CGT2.0", coinGeckoId: "curio-gas-token", decimals: 18, price: 0.01317038}, // Addr: 0x0e186357c323c806c1efdad36d217f7a54b63d18, Notional: 310143.4530957046 - {chain: 2, addr: "0000000000000000000000000f3adc247e91c3c50bc08721355a41037e89bc20", symbol: "ANC", coinGeckoId: "anchor-protocol", decimals: 18, price: 0.00880249}, // Addr: 0x0f3adc247e91c3c50bc08721355a41037e89bc20, Notional: 24.002683196739813 - {chain: 2, addr: "0000000000000000000000000f51bb10119727a7e5ea3538074fb341f56b09ad", symbol: "DAO", coinGeckoId: "dao-maker", decimals: 18, price: 0.423369}, // Addr: 0x0f51bb10119727a7e5ea3538074fb341f56b09ad, Notional: 3516.609549321746 - {chain: 2, addr: "0000000000000000000000000f5d2fb29fb7d3cfee444a200298f468908cc942", symbol: "MANA", coinGeckoId: "decentraland", decimals: 18, price: 0.605668}, // Addr: 0x0f5d2fb29fb7d3cfee444a200298f468908cc942, Notional: 50111.835648401575 - {chain: 2, addr: "000000000000000000000000102c776ddb30c754ded4fdcc77a19230a60d4e4f", symbol: "FLC", coinGeckoId: "flooring-lab-credit", decimals: 18, price: 0.00310757}, // Addr: 0x102c776ddb30c754ded4fdcc77a19230a60d4e4f, Notional: 64476.46863484898 - {chain: 2, addr: "0000000000000000000000001045f5ccb01daea4f8eab055f5fcbb7c0e7c89f0", symbol: "DFIAT", coinGeckoId: "defiato", decimals: 18, price: 0.00135615}, // Addr: 0x1045f5ccb01daea4f8eab055f5fcbb7c0e7c89f0, Notional: 2408.1588668872714 - {chain: 2, addr: "00000000000000000000000010633216e7e8281e33c86f02bf8e565a635d9770", symbol: "DVI", coinGeckoId: "dvision-network", decimals: 18, price: 0.01911329}, // Addr: 0x10633216e7e8281e33c86f02bf8e565a635d9770, Notional: 1.911329 - {chain: 2, addr: "000000000000000000000000111111111117dc0aa78b770fa6a738034120c302", symbol: "1INCH", coinGeckoId: "1inch", decimals: 18, price: 0.450082}, // Addr: 0x111111111117dc0aa78b770fa6a738034120c302, Notional: 202526.85757383818 - {chain: 2, addr: "00000000000000000000000012970e6868f88f6557b76120662c1b3e50a646bf", symbol: "LADYS", coinGeckoId: "milady-meme-coin", decimals: 18, price: 9.8641e-8}, // Addr: 0x12970e6868f88f6557b76120662c1b3e50a646bf, Notional: 10.376995682765886 - {chain: 2, addr: "00000000000000000000000012bb890508c125661e03b09ec06e404bc9289040", symbol: "RACA", coinGeckoId: "radio-caca", decimals: 18, price: 0.00024251}, // Addr: 0x12bb890508c125661e03b09ec06e404bc9289040, Notional: 10.028501827125389 - {chain: 2, addr: "000000000000000000000000138c2f1123cf3f82e4596d097c118eac6684940b", symbol: "ALPHA", coinGeckoId: "alphacoin", decimals: 18, price: 0.109808}, // Addr: 0x138c2f1123cf3f82e4596d097c118eac6684940b, Notional: 0.10870992 - {chain: 2, addr: "0000000000000000000000001494ca1f11d487c2bbe4543e90080aeba4ba3c2b", symbol: "DPI", coinGeckoId: "defipulse-index", decimals: 18, price: 129.84}, // Addr: 0x1494ca1f11d487c2bbe4543e90080aeba4ba3c2b, Notional: 3.9664094496 - {chain: 2, addr: "000000000000000000000000152649ea73beab28c5b49b26eb48f7ead6d4c898", symbol: "Cake", coinGeckoId: "pancakeswap-token", decimals: 18, price: 2.94}, // Addr: 0x152649ea73beab28c5b49b26eb48f7ead6d4c898, Notional: 5.9203301262000005 - {chain: 2, addr: "00000000000000000000000015d4c048f83bd7e37d49ea4c83a07267ec4203da", symbol: "GALA", coinGeckoId: "gala", decimals: 8, price: 0.04203893}, // Addr: 0x15d4c048f83bd7e37d49ea4c83a07267ec4203da, Notional: 25.89598088 - {chain: 2, addr: "000000000000000000000000170dec83c7753aaad20c01a0016b5a2e143990d4", symbol: "WIGGER", coinGeckoId: "wigger", decimals: 18, price: 0.0000808}, // Addr: 0x170dec83c7753aaad20c01a0016b5a2e143990d4, Notional: 1276.7417997475736 - {chain: 2, addr: "0000000000000000000000001796ae0b0fa4862485106a0de9b654efe301d0b2", symbol: "PMON", coinGeckoId: "polychain-monsters", decimals: 18, price: 0.155208}, // Addr: 0x1796ae0b0fa4862485106a0de9b654efe301d0b2, Notional: 6.130732074892561 - {chain: 2, addr: "00000000000000000000000018084fba666a33d37592fa2633fd49a74dd93a88", symbol: "tBTC", coinGeckoId: "tbtc", decimals: 18, price: 94760}, // Addr: 0x18084fba666a33d37592fa2633fd49a74dd93a88, Notional: 67627036.4947972 - {chain: 2, addr: "0000000000000000000000001864ce27e9f7517047933caae530674e8c70b8a7", symbol: "PIB", coinGeckoId: "pibble", decimals: 18, price: 0.00047899}, // Addr: 0x1864ce27e9f7517047933caae530674e8c70b8a7, Notional: 5.26889 - {chain: 2, addr: "00000000000000000000000018aaa7115705e8be94bffebde57af9bfc265b998", symbol: "AUDIO", coinGeckoId: "audius", decimals: 18, price: 0.180478}, // Addr: 0x18aaa7115705e8be94bffebde57af9bfc265b998, Notional: 6589469.391818729 - {chain: 2, addr: "00000000000000000000000019062190b1925b5b6689d7073fdfc8c2976ef8cb", symbol: "BZZ", coinGeckoId: "swarm-bzz", decimals: 16, price: 0.52985}, // Addr: 0x19062190b1925b5b6689d7073fdfc8c2976ef8cb, Notional: 5.2985e-9 - {chain: 2, addr: "0000000000000000000000001a11ea9d61588d756d9f1014c3cf0d226aedd279", symbol: "MILEI", coinGeckoId: "milei-token", decimals: 18, price: 0.03506191}, // Addr: 0x1a11ea9d61588d756d9f1014c3cf0d226aedd279, Notional: 1591.035121296339 - {chain: 2, addr: "0000000000000000000000001a3496c18d558bd9c6c8f609e1b129f67ab08163", symbol: "DEP", coinGeckoId: "deapcoin", decimals: 18, price: 0.00149356}, // Addr: 0x1a3496c18d558bd9c6c8f609e1b129f67ab08163, Notional: 0.00149356 - {chain: 2, addr: "0000000000000000000000001a6658f40e51b372e593b7d2144c1402d5cf33e8", symbol: "PUBLX", coinGeckoId: "publc", decimals: 18, price: 0.00064039}, // Addr: 0x1a6658f40e51b372e593b7d2144c1402d5cf33e8, Notional: 12348.321206865498 - {chain: 2, addr: "0000000000000000000000001a7e4e63778b4f12a199c062f3efdd288afcbce8", symbol: "agEUR", coinGeckoId: "ageur", decimals: 18, price: 1.046}, // Addr: 0x1a7e4e63778b4f12a199c062f3efdd288afcbce8, Notional: 20331.679150928383 - {chain: 2, addr: "0000000000000000000000001abaea1f7c830bd89acc67ec4af516284b1bc33c", symbol: "EUROC", coinGeckoId: "euro-coin", decimals: 6, price: 1.052}, // Addr: 0x1abaea1f7c830bd89acc67ec4af516284b1bc33c, Notional: 1.5912341600000002 - {chain: 2, addr: "0000000000000000000000001c4853ec0d55e420002c5efabc7ed8e0ba7a4121", symbol: "Okinami", coinGeckoId: "kanagawa-nami", decimals: 9, price: 0.00099678}, // Addr: 0x1c4853ec0d55e420002c5efabc7ed8e0ba7a4121, Notional: 12.09705744612302 - {chain: 2, addr: "0000000000000000000000001c48f86ae57291f7686349f12601910bd8d470bb", symbol: "USDK", coinGeckoId: "usdk", decimals: 18, price: 1.009}, // Addr: 0x1c48f86ae57291f7686349f12601910bd8d470bb, Notional: 2247.20061041113 + {chain: 2, addr: "0000000000000000000000000001a500a6b18995b03f44bb040a5ffc28e45cb0", symbol: "OLAS", coinGeckoId: "autonolas", decimals: 18, price: 1.53}, // Addr: 0x0001a500a6b18995b03f44bb040a5ffc28e45cb0, Notional: 1354548.9558927629 + {chain: 2, addr: "000000000000000000000000009178997aff09a67d4caccfeb897fb79d036214", symbol: "1SOL", coinGeckoId: "1sol", decimals: 18, price: 0.01627531}, // Addr: 0x009178997aff09a67d4caccfeb897fb79d036214, Notional: 1518941.1260769276 + {chain: 2, addr: "00000000000000000000000000a8b738e453ffd858a7edf03bccfe20412f0eb0", symbol: "ALBT", coinGeckoId: "allianceblock", decimals: 18, price: 0.00011037}, // Addr: 0x00a8b738e453ffd858a7edf03bccfe20412f0eb0, Notional: 0.0161061040252008 + {chain: 2, addr: "00000000000000000000000000c5ca160a968f47e7272a0cfcda36428f386cb6", symbol: "USDEBT", coinGeckoId: "usdebt", decimals: 18, price: 9.389e-9}, // Addr: 0x00c5ca160a968f47e7272a0cfcda36428f386cb6, Notional: 1690.9241359091836 + {chain: 2, addr: "00000000000000000000000000e679ba63b509182c349f5614f0a07cdd0ce0c5", symbol: "DAMEX", coinGeckoId: "damex-token", decimals: 18, price: 0.00089854}, // Addr: 0x00e679ba63b509182c349f5614f0a07cdd0ce0c5, Notional: 0.5391239999999999 + {chain: 2, addr: "000000000000000000000000030ba81f1c18d280636f32af80b9aad02cf0854e", symbol: "aWETH", coinGeckoId: "aave-weth", decimals: 18, price: 3327.38}, // Addr: 0x030ba81f1c18d280636f32af80b9aad02cf0854e, Notional: 998.2573890352 + {chain: 2, addr: "0000000000000000000000000316eb71485b0ab14103307bf65a021042c6d380", symbol: "HBTC", coinGeckoId: "huobi-btc", decimals: 18, price: 9952.5}, // Addr: 0x0316eb71485b0ab14103307bf65a021042c6d380, Notional: 1011.456651 + {chain: 2, addr: "00000000000000000000000003ab458634910aad20ef5f1c8ee96f1d6ac54919", symbol: "RAI", coinGeckoId: "rai", decimals: 18, price: 2.99}, // Addr: 0x03ab458634910aad20ef5f1c8ee96f1d6ac54919, Notional: 8.97 + {chain: 2, addr: "00000000000000000000000003be5c903c727ee2c8c4e9bc0acc860cca4715e2", symbol: "CAPS", coinGeckoId: "coin-capsule", decimals: 18, price: 0.00491619}, // Addr: 0x03be5c903c727ee2c8c4e9bc0acc860cca4715e2, Notional: 896.7916098136726 + {chain: 2, addr: "000000000000000000000000046eee2cc3188071c02bfc1745a6b17c656e3f3d", symbol: "RLB", coinGeckoId: "rollbit-coin", decimals: 18, price: 0.112137}, // Addr: 0x046eee2cc3188071c02bfc1745a6b17c656e3f3d, Notional: 372.29484 + {chain: 2, addr: "00000000000000000000000004815313e9329e8905a77251a1781cfa7934259a", symbol: "HOOD", coinGeckoId: "wagmicatgirlkanye420etfmoon1000x", decimals: 18, price: 0.00002502}, // Addr: 0x04815313e9329e8905a77251a1781cfa7934259a, Notional: 78908.02135254242 + {chain: 2, addr: "00000000000000000000000004969cd041c0cafb6ac462bd65b536a5bdb3a670", symbol: "wOMI", coinGeckoId: "wrapped-ecomi", decimals: 18, price: 0.00061798}, // Addr: 0x04969cd041c0cafb6ac462bd65b536a5bdb3a670, Notional: 11.602386322179314 + {chain: 2, addr: "00000000000000000000000004c154b66cb340f3ae24111cc767e0184ed00cc6", symbol: "pxETH", coinGeckoId: "dinero-staked-eth", decimals: 18, price: 3319.74}, // Addr: 0x04c154b66cb340f3ae24111cc767e0184ed00cc6, Notional: 196643.119609521 + {chain: 2, addr: "000000000000000000000000054d64b73d3d8a21af3d764efd76bcaa774f3bb2", symbol: "PPAY", coinGeckoId: "plasma-finance", decimals: 18, price: 0.00010374}, // Addr: 0x054d64b73d3d8a21af3d764efd76bcaa774f3bb2, Notional: 988.1582367217812 + {chain: 2, addr: "00000000000000000000000005d3606d5c81eb9b7b18530995ec9b29da05faba", symbol: "TOMOE", coinGeckoId: "tomoe", decimals: 18, price: 0.40751}, // Addr: 0x05d3606d5c81eb9b7b18530995ec9b29da05faba, Notional: 40751 + {chain: 2, addr: "00000000000000000000000006450dee7fd2fb8e39061434babcfc05599a6fb8", symbol: "XEN", coinGeckoId: "xen-crypto", decimals: 18, price: 1.68216e-7}, // Addr: 0x06450dee7fd2fb8e39061434babcfc05599a6fb8, Notional: 0.00168384216 + {chain: 2, addr: "00000000000000000000000006af07097c9eeb7fd685c692751d5c66db49c215", symbol: "CHAI", coinGeckoId: "chai", decimals: 18, price: 1.068}, // Addr: 0x06af07097c9eeb7fd685c692751d5c66db49c215, Notional: 8292945.4674072005 + {chain: 2, addr: "00000000000000000000000006e0feb0d74106c7ada8497754074d222ec6bcdf", symbol: "BTB", coinGeckoId: "bitball", decimals: 18, price: 0.0000935}, // Addr: 0x06e0feb0d74106c7ada8497754074d222ec6bcdf, Notional: 841.5 + {chain: 2, addr: "0000000000000000000000000763fdccf1ae541a5961815c0872a8c5bc6de4d7", symbol: "SUKU", coinGeckoId: "suku", decimals: 18, price: 0.066683}, // Addr: 0x0763fdccf1ae541a5961815c0872a8c5bc6de4d7, Notional: 1.56963994892626 + {chain: 2, addr: "000000000000000000000000081131434f93063751813c619ecca9c4dc7862a3", symbol: "DAR", coinGeckoId: "mines-of-dalarnia", decimals: 6, price: 0.165696}, // Addr: 0x081131434f93063751813c619ecca9c4dc7862a3, Notional: 176.532354526656 + {chain: 2, addr: "00000000000000000000000008389495d7456e1951ddf7c3a1314a4bfb646d8b", symbol: "CRPT", coinGeckoId: "crypterium", decimals: 18, price: 0.01551477}, // Addr: 0x08389495d7456e1951ddf7c3a1314a4bfb646d8b, Notional: 0.52750218 + {chain: 2, addr: "00000000000000000000000008d967bb0134f2d07f7cfb6e246680c53927dd30", symbol: "MATH", coinGeckoId: "math", decimals: 18, price: 0.261832}, // Addr: 0x08d967bb0134f2d07f7cfb6e246680c53927dd30, Notional: 1296902.3405975571 + {chain: 2, addr: "000000000000000000000000090185f2135308bad17527004364ebcc2d37e5f6", symbol: "SPELL", coinGeckoId: "spell-token", decimals: 18, price: 0.00073482}, // Addr: 0x090185f2135308bad17527004364ebcc2d37e5f6, Notional: 0.00073482 + {chain: 2, addr: "00000000000000000000000009a3ecafa817268f77be1283176b946c4ff2e608", symbol: "MIR", coinGeckoId: "mirror-protocol", decimals: 18, price: 0.02541862}, // Addr: 0x09a3ecafa817268f77be1283176b946c4ff2e608, Notional: 222.47737761729897 + {chain: 2, addr: "0000000000000000000000000a638f07acc6969abf392bb009f216d22adea36d", symbol: "BKN", coinGeckoId: "brickken", decimals: 18, price: 0.328349}, // Addr: 0x0a638f07acc6969abf392bb009f216d22adea36d, Notional: 2819496.5988757247 + {chain: 2, addr: "0000000000000000000000000ab87046fbb341d058f17cbc4c1133f25a20a52f", symbol: "gOHM", coinGeckoId: "governance-ohm", decimals: 18, price: 5398.41}, // Addr: 0x0ab87046fbb341d058f17cbc4c1133f25a20a52f, Notional: 902.8186977549 + {chain: 2, addr: "0000000000000000000000000b61c4f33bcdef83359ab97673cb5961c6435f4e", symbol: "EARN", coinGeckoId: "hold-2", decimals: 18, price: 0.00177104}, // Addr: 0x0b61c4f33bcdef83359ab97673cb5961c6435f4e, Notional: 10.350087335502751 + {chain: 2, addr: "0000000000000000000000000bc529c00c6401aef6d220be8c6ea1667f6ad93e", symbol: "YFI", coinGeckoId: "yearn-finance", decimals: 18, price: 7944.41}, // Addr: 0x0bc529c00c6401aef6d220be8c6ea1667f6ad93e, Notional: 263498.3736756566 + {chain: 2, addr: "0000000000000000000000000c572544a4ee47904d54aaa6a970af96b6f00e1b", symbol: "WAS", coinGeckoId: "wasder", decimals: 18, price: 0.00122578}, // Addr: 0x0c572544a4ee47904d54aaa6a970af96b6f00e1b, Notional: 1062.9169456464656 + {chain: 2, addr: "0000000000000000000000000d505c03d30e65f6e9b4ef88855a47a89e4b7676", symbol: "ZOOMER", coinGeckoId: "zoomer", decimals: 18, price: 0.00002106}, // Addr: 0x0d505c03d30e65f6e9b4ef88855a47a89e4b7676, Notional: 36434.75080587783 + {chain: 2, addr: "0000000000000000000000000d5639a1442730372e2a650a2900ba07937854f4", symbol: "CHUB", coinGeckoId: "callhub", decimals: 18, price: 0.0123122}, // Addr: 0x0d5639a1442730372e2a650a2900ba07937854f4, Notional: 73.8732 + {chain: 2, addr: "0000000000000000000000000d8775f648430679a709e98d2b0cb6250d2887ef", symbol: "BAT", coinGeckoId: "basic-attention-token", decimals: 18, price: 0.23073}, // Addr: 0x0d8775f648430679a709e98d2b0cb6250d2887ef, Notional: 284764.6598934532 + {chain: 2, addr: "0000000000000000000000000e186357c323c806c1efdad36d217f7a54b63d18", symbol: "CGT2.0", coinGeckoId: "curio-gas-token", decimals: 18, price: 0.00863141}, // Addr: 0x0e186357c323c806c1efdad36d217f7a54b63d18, Notional: 203250.63645106513 + {chain: 2, addr: "0000000000000000000000000f3adc247e91c3c50bc08721355a41037e89bc20", symbol: "ANC", coinGeckoId: "anchor-protocol", decimals: 18, price: 0.00954159}, // Addr: 0x0f3adc247e91c3c50bc08721355a41037e89bc20, Notional: 26.018065565900176 + {chain: 2, addr: "0000000000000000000000000f51bb10119727a7e5ea3538074fb341f56b09ad", symbol: "DAO", coinGeckoId: "dao-maker", decimals: 18, price: 0.325357}, // Addr: 0x0f51bb10119727a7e5ea3538074fb341f56b09ad, Notional: 2702.497190721747 + {chain: 2, addr: "0000000000000000000000000f5d2fb29fb7d3cfee444a200298f468908cc942", symbol: "MANA", coinGeckoId: "decentraland", decimals: 18, price: 0.464509}, // Addr: 0x0f5d2fb29fb7d3cfee444a200298f468908cc942, Notional: 43541.22105305113 + {chain: 2, addr: "000000000000000000000000102c776ddb30c754ded4fdcc77a19230a60d4e4f", symbol: "FLC", coinGeckoId: "flooring-lab-credit", decimals: 18, price: 0.00299848}, // Addr: 0x102c776ddb30c754ded4fdcc77a19230a60d4e4f, Notional: 62356.81036017395 + {chain: 2, addr: "0000000000000000000000001045f5ccb01daea4f8eab055f5fcbb7c0e7c89f0", symbol: "DFIAT", coinGeckoId: "defiato", decimals: 18, price: 0.00113772}, // Addr: 0x1045f5ccb01daea4f8eab055f5fcbb7c0e7c89f0, Notional: 2020.2857398038466 + {chain: 2, addr: "00000000000000000000000010633216e7e8281e33c86f02bf8e565a635d9770", symbol: "DVI", coinGeckoId: "dvision-network", decimals: 18, price: 0.0137498}, // Addr: 0x10633216e7e8281e33c86f02bf8e565a635d9770, Notional: 1.3749799999999999 + {chain: 2, addr: "000000000000000000000000111111111117dc0aa78b770fa6a738034120c302", symbol: "1INCH", coinGeckoId: "1inch", decimals: 18, price: 0.381911}, // Addr: 0x111111111117dc0aa78b770fa6a738034120c302, Notional: 171851.42863496454 + {chain: 2, addr: "00000000000000000000000012970e6868f88f6557b76120662c1b3e50a646bf", symbol: "LADYS", coinGeckoId: "milady-meme-coin", decimals: 18, price: 7.3369e-8}, // Addr: 0x12970e6868f88f6557b76120662c1b3e50a646bf, Notional: 7.71839089474813 + {chain: 2, addr: "00000000000000000000000012bb890508c125661e03b09ec06e404bc9289040", symbol: "RACA", coinGeckoId: "radio-caca", decimals: 18, price: 0.00019331}, // Addr: 0x12bb890508c125661e03b09ec06e404bc9289040, Notional: 7.993937108579478 + {chain: 2, addr: "000000000000000000000000138c2f1123cf3f82e4596d097c118eac6684940b", symbol: "ALPHA", coinGeckoId: "alphacoin", decimals: 18, price: 0.079633}, // Addr: 0x138c2f1123cf3f82e4596d097c118eac6684940b, Notional: 0.07883667 + {chain: 2, addr: "0000000000000000000000001494ca1f11d487c2bbe4543e90080aeba4ba3c2b", symbol: "DPI", coinGeckoId: "defipulse-index", decimals: 18, price: 138.04}, // Addr: 0x1494ca1f11d487c2bbe4543e90080aeba4ba3c2b, Notional: 4.2169066576 + {chain: 2, addr: "000000000000000000000000152649ea73beab28c5b49b26eb48f7ead6d4c898", symbol: "Cake", coinGeckoId: "pancakeswap-token", decimals: 18, price: 2.5}, // Addr: 0x152649ea73beab28c5b49b26eb48f7ead6d4c898, Notional: 5.034294325 + {chain: 2, addr: "00000000000000000000000015d4c048f83bd7e37d49ea4c83a07267ec4203da", symbol: "GALA", coinGeckoId: "gala", decimals: 8, price: 0.03424919}, // Addr: 0x15d4c048f83bd7e37d49ea4c83a07267ec4203da, Notional: 21.09750104 + {chain: 2, addr: "000000000000000000000000170dec83c7753aaad20c01a0016b5a2e143990d4", symbol: "WIGGER", coinGeckoId: "wigger", decimals: 18, price: 0.00006246}, // Addr: 0x170dec83c7753aaad20c01a0016b5a2e143990d4, Notional: 986.9466932207109 + {chain: 2, addr: "0000000000000000000000001796ae0b0fa4862485106a0de9b654efe301d0b2", symbol: "PMON", coinGeckoId: "polychain-monsters", decimals: 18, price: 0.125381}, // Addr: 0x1796ae0b0fa4862485106a0de9b654efe301d0b2, Notional: 4.952562485710169 + {chain: 2, addr: "00000000000000000000000018084fba666a33d37592fa2633fd49a74dd93a88", symbol: "tBTC", coinGeckoId: "tbtc", decimals: 18, price: 93127}, // Addr: 0x18084fba666a33d37592fa2633fd49a74dd93a88, Notional: 54880019.3448506 + {chain: 2, addr: "0000000000000000000000001864ce27e9f7517047933caae530674e8c70b8a7", symbol: "PIB", coinGeckoId: "pibble", decimals: 18, price: 0.00065046}, // Addr: 0x1864ce27e9f7517047933caae530674e8c70b8a7, Notional: 7.15506 + {chain: 2, addr: "00000000000000000000000018aaa7115705e8be94bffebde57af9bfc265b998", symbol: "AUDIO", coinGeckoId: "audius", decimals: 18, price: 0.15233}, // Addr: 0x18aaa7115705e8be94bffebde57af9bfc265b998, Notional: 5688660.714468047 + {chain: 2, addr: "00000000000000000000000019062190b1925b5b6689d7073fdfc8c2976ef8cb", symbol: "BZZ", coinGeckoId: "swarm-bzz", decimals: 16, price: 0.397872}, // Addr: 0x19062190b1925b5b6689d7073fdfc8c2976ef8cb, Notional: 3.9787200000000005e-9 + {chain: 2, addr: "0000000000000000000000001a11ea9d61588d756d9f1014c3cf0d226aedd279", symbol: "MILEI", coinGeckoId: "milei-token", decimals: 18, price: 0.02619182}, // Addr: 0x1a11ea9d61588d756d9f1014c3cf0d226aedd279, Notional: 1156.9577282757716 + {chain: 2, addr: "0000000000000000000000001a3496c18d558bd9c6c8f609e1b129f67ab08163", symbol: "DEP", coinGeckoId: "deapcoin", decimals: 18, price: 0.0017643}, // Addr: 0x1a3496c18d558bd9c6c8f609e1b129f67ab08163, Notional: 0.0017643 + {chain: 2, addr: "0000000000000000000000001a6658f40e51b372e593b7d2144c1402d5cf33e8", symbol: "PUBLX", coinGeckoId: "publc", decimals: 18, price: 0.0006149}, // Addr: 0x1a6658f40e51b372e593b7d2144c1402d5cf33e8, Notional: 12068.791486758768 + {chain: 2, addr: "0000000000000000000000001a7e4e63778b4f12a199c062f3efdd288afcbce8", symbol: "agEUR", coinGeckoId: "ageur", decimals: 18, price: 1.031}, // Addr: 0x1a7e4e63778b4f12a199c062f3efdd288afcbce8, Notional: 20040.11587438543 + {chain: 2, addr: "0000000000000000000000001abaea1f7c830bd89acc67ec4af516284b1bc33c", symbol: "EUROC", coinGeckoId: "euro-coin", decimals: 6, price: 1.036}, // Addr: 0x1abaea1f7c830bd89acc67ec4af516284b1bc33c, Notional: 1.5670328800000002 + {chain: 2, addr: "0000000000000000000000001c4853ec0d55e420002c5efabc7ed8e0ba7a4121", symbol: "Okinami", coinGeckoId: "kanagawa-nami", decimals: 9, price: 0.00132407}, // Addr: 0x1c4853ec0d55e420002c5efabc7ed8e0ba7a4121, Notional: 16.06909333322108 + {chain: 2, addr: "0000000000000000000000001c48f86ae57291f7686349f12601910bd8d470bb", symbol: "USDK", coinGeckoId: "usdk", decimals: 18, price: 0.999068}, // Addr: 0x1c48f86ae57291f7686349f12601910bd8d470bb, Notional: 2225.080494987341 {chain: 2, addr: "0000000000000000000000001c98b54d673c026c8286badca3e840aaf72931a3", symbol: "STSW", coinGeckoId: "stackswap", decimals: 6, price: 0.01399529}, // Addr: 0x1c98b54d673c026c8286badca3e840aaf72931a3, Notional: 699.9044529 - {chain: 2, addr: "0000000000000000000000001cf4592ebffd730c7dc92c1bdffdfc3b9efcf29a", symbol: "WAVES", coinGeckoId: "waves", decimals: 18, price: 2.05}, // Addr: 0x1cf4592ebffd730c7dc92c1bdffdfc3b9efcf29a, Notional: 2.1033 - {chain: 2, addr: "0000000000000000000000001f573d6fb3f13d689ff844b4ce37794d79a7ff1c", symbol: "BNT", coinGeckoId: "bancor", decimals: 18, price: 0.78675}, // Addr: 0x1f573d6fb3f13d689ff844b4ce37794d79a7ff1c, Notional: 7.8675 - {chain: 2, addr: "0000000000000000000000001f7e5118521b550bb1a9b435727c003eb033fc51", symbol: "AGLA", coinGeckoId: "angola", decimals: 18, price: 0.00397156}, // Addr: 0x1f7e5118521b550bb1a9b435727c003eb033fc51, Notional: 5758.762 - {chain: 2, addr: "0000000000000000000000001f9840a85d5af5bf1d1762f925bdaddc4201f984", symbol: "UNI", coinGeckoId: "uniswap", decimals: 18, price: 14.02}, // Addr: 0x1f9840a85d5af5bf1d1762f925bdaddc4201f984, Notional: 840269.0946122973 - {chain: 2, addr: "0000000000000000000000001fee5588cb1de19c70b6ad5399152d8c643fae7b", symbol: "PHTK", coinGeckoId: "phuntoken", decimals: 18, price: 0.00083207}, // Addr: 0x1fee5588cb1de19c70b6ad5399152d8c643fae7b, Notional: 0.83207 - {chain: 2, addr: "00000000000000000000000020a62aca58526836165ca53fe67dd884288c8abf", symbol: "RNB", coinGeckoId: "rentible", decimals: 18, price: 0.167719}, // Addr: 0x20a62aca58526836165ca53fe67dd884288c8abf, Notional: 8697.99348525336 - {chain: 2, addr: "00000000000000000000000020e7125677311fca903a8897042b9983f22ea295", symbol: "FWT", coinGeckoId: "freeway", decimals: 18, price: 0.0000531}, // Addr: 0x20e7125677311fca903a8897042b9983f22ea295, Notional: 0.003086230185387 - {chain: 2, addr: "00000000000000000000000021381e026ad6d8266244f2a583b35f9e4413fa2a", symbol: "FORM", coinGeckoId: "formation-fi", decimals: 18, price: 0.00068998}, // Addr: 0x21381e026ad6d8266244f2a583b35f9e4413fa2a, Notional: 241.0304920399333 - {chain: 2, addr: "00000000000000000000000021bfbda47a0b4b5b1248c767ee49f7caa9b23697", symbol: "OVR", coinGeckoId: "ovr", decimals: 18, price: 0.210239}, // Addr: 0x21bfbda47a0b4b5b1248c767ee49f7caa9b23697, Notional: 31.53585 - {chain: 2, addr: "000000000000000000000000221657776846890989a759ba2973e427dff5c9bb", symbol: "REPv2", coinGeckoId: "augur", decimals: 18, price: 0.702739}, // Addr: 0x221657776846890989a759ba2973e427dff5c9bb, Notional: 0.702739 - {chain: 2, addr: "0000000000000000000000002260fac5e5542a773aa44fbcfedf7c193bc2c599", symbol: "WBTC", coinGeckoId: "wrapped-bitcoin", decimals: 8, price: 94688}, // Addr: 0x2260fac5e5542a773aa44fbcfedf7c193bc2c599, Notional: 282101854.93543327 - {chain: 2, addr: "00000000000000000000000022c5543d1a35178cb03b33f929a959145e538532", symbol: "WAL", coinGeckoId: "the-wasted-lands", decimals: 18, price: 0.0000773}, // Addr: 0x22c5543d1a35178cb03b33f929a959145e538532, Notional: 0.102027634357462 - {chain: 2, addr: "00000000000000000000000022fc5a29bd3d6cce19a06f844019fd506fce4455", symbol: "ePendle", coinGeckoId: "equilibria-finance-ependle", decimals: 18, price: 1.71}, // Addr: 0x22fc5a29bd3d6cce19a06f844019fd506fce4455, Notional: 3403.3306826349 - {chain: 2, addr: "0000000000000000000000002370f9d504c7a6e775bf6e14b3f12846b594cd53", symbol: "JPYC", coinGeckoId: "jpyc", decimals: 18, price: 0.00758084}, // Addr: 0x2370f9d504c7a6e775bf6e14b3f12846b594cd53, Notional: 7.58084 - {chain: 2, addr: "00000000000000000000000024249b5a869a445c9b0ce269a08d73c618df9d21", symbol: "ETHEREUM", coinGeckoId: "harrypottertrumphomersimpson777inu", decimals: 8, price: 0.00118558}, // Addr: 0x24249b5a869a445c9b0ce269a08d73c618df9d21, Notional: 5.809342000000001 - {chain: 2, addr: "000000000000000000000000249e38ea4102d0cf8264d3701f1a0e39c4f2dc3b", symbol: "UFO", coinGeckoId: "ufo-gaming", decimals: 18, price: 7.97967e-7}, // Addr: 0x249e38ea4102d0cf8264d3701f1a0e39c4f2dc3b, Notional: 24.30008945073461 - {chain: 2, addr: "000000000000000000000000255f1b39172f65dc6406b8bee8b08155c45fe1b6", symbol: "HARAMBE", coinGeckoId: "harambecoin", decimals: 18, price: 6.6701e-7}, // Addr: 0x255f1b39172f65dc6406b8bee8b08155c45fe1b6, Notional: 89157.67965882775 - {chain: 2, addr: "00000000000000000000000025722cd432d02895d9be45f5deb60fc479c8781e", symbol: "SPONGE", coinGeckoId: "sponge-f08b2fe4-9d9c-47c3-b5a0-84c2ac3bbbff", decimals: 18, price: 0.00003423}, // Addr: 0x25722cd432d02895d9be45f5deb60fc479c8781e, Notional: 1.204165053935508 - {chain: 2, addr: "0000000000000000000000002598c30330d5771ae9f983979209486ae26de875", symbol: "AI", coinGeckoId: "any-inu", decimals: 18, price: 0.00000789}, // Addr: 0x2598c30330d5771ae9f983979209486ae26de875, Notional: 477575.457681183 - {chain: 2, addr: "00000000000000000000000025cbb21a9da7c3c63bb77ccca5b2e2482aedb710", symbol: "HOBA", coinGeckoId: "honey-badger-2", decimals: 9, price: 0.373129}, // Addr: 0x25cbb21a9da7c3c63bb77ccca5b2e2482aedb710, Notional: 5585.914759639936 - {chain: 2, addr: "00000000000000000000000027702a26126e0b3702af63ee09ac4d1a084ef628", symbol: "ALEPH", coinGeckoId: "aleph", decimals: 18, price: 0.169864}, // Addr: 0x27702a26126e0b3702af63ee09ac4d1a084ef628, Notional: 1065033.731748767 - {chain: 2, addr: "0000000000000000000000002781246fe707bb15cee3e5ea354e2154a2877b16", symbol: "EL", coinGeckoId: "elysia", decimals: 18, price: 0.00593955}, // Addr: 0x2781246fe707bb15cee3e5ea354e2154a2877b16, Notional: 95355.86633273335 - {chain: 2, addr: "0000000000000000000000002ad9addd0d97ec3cdba27f92bf6077893b76ab0b", symbol: "PLANET", coinGeckoId: "planet-token", decimals: 18, price: 0.00000393}, // Addr: 0x2ad9addd0d97ec3cdba27f92bf6077893b76ab0b, Notional: 146946.3211336379 - {chain: 2, addr: "0000000000000000000000002b591e99afe9f32eaa6214f7b7629768c40eeb39", symbol: "HEX", coinGeckoId: "hex", decimals: 8, price: 0.00436553}, // Addr: 0x2b591e99afe9f32eaa6214f7b7629768c40eeb39, Notional: 122.06475163981035 - {chain: 2, addr: "0000000000000000000000002ba592f78db6436527729929aaf6c908497cb200", symbol: "CREAM", coinGeckoId: "cream-2", decimals: 18, price: 18.93}, // Addr: 0x2ba592f78db6436527729929aaf6c908497cb200, Notional: 187.984787139 - {chain: 2, addr: "0000000000000000000000002c537e5624e4af88a7ae4060c022609376c8d0eb", symbol: "TRYB", coinGeckoId: "bilira", decimals: 6, price: 0.02884969}, // Addr: 0x2c537e5624e4af88a7ae4060c022609376c8d0eb, Notional: 193.67291374916664 - {chain: 2, addr: "0000000000000000000000002c8ea636345a231e4b1a28f6eeb2072ed909c406", symbol: "MemElon", coinGeckoId: "meme-elon-doge-floki-2", decimals: 18, price: 5.2038e-11}, // Addr: 0x2c8ea636345a231e4b1a28f6eeb2072ed909c406, Notional: 9.36684 - {chain: 2, addr: "0000000000000000000000002c95d751da37a5c1d9c5a7fd465c1d50f3d96160", symbol: "WASSIE", coinGeckoId: "wassie", decimals: 18, price: 0.00000557}, // Addr: 0x2c95d751da37a5c1d9c5a7fd465c1d50f3d96160, Notional: 352465.96540384885 - {chain: 2, addr: "0000000000000000000000002cb5d9fd89d48c516f11904117c57e3934f39524", symbol: "CUTE", coinGeckoId: "pepe-uwu", decimals: 18, price: 1.7803e-8}, // Addr: 0x2cb5d9fd89d48c516f11904117c57e3934f39524, Notional: 2056.1211728282287 - {chain: 2, addr: "0000000000000000000000002e95cea14dd384429eb3c4331b776c4cfbb6fcd9", symbol: "THN", coinGeckoId: "throne", decimals: 18, price: 0.00131364}, // Addr: 0x2e95cea14dd384429eb3c4331b776c4cfbb6fcd9, Notional: 0.02364552 + {chain: 2, addr: "0000000000000000000000001cf4592ebffd730c7dc92c1bdffdfc3b9efcf29a", symbol: "WAVES", coinGeckoId: "waves", decimals: 18, price: 1.51}, // Addr: 0x1cf4592ebffd730c7dc92c1bdffdfc3b9efcf29a, Notional: 1.54926 + {chain: 2, addr: "0000000000000000000000001f573d6fb3f13d689ff844b4ce37794d79a7ff1c", symbol: "BNT", coinGeckoId: "bancor", decimals: 18, price: 0.656889}, // Addr: 0x1f573d6fb3f13d689ff844b4ce37794d79a7ff1c, Notional: 6.56889 + {chain: 2, addr: "0000000000000000000000001f7e5118521b550bb1a9b435727c003eb033fc51", symbol: "AGLA", coinGeckoId: "angola", decimals: 18, price: 0.00499423}, // Addr: 0x1f7e5118521b550bb1a9b435727c003eb033fc51, Notional: 7241.6335 + {chain: 2, addr: "0000000000000000000000001f9840a85d5af5bf1d1762f925bdaddc4201f984", symbol: "UNI", coinGeckoId: "uniswap", decimals: 18, price: 13.19}, // Addr: 0x1f9840a85d5af5bf1d1762f925bdaddc4201f984, Notional: 793820.2830368124 + {chain: 2, addr: "0000000000000000000000001fee5588cb1de19c70b6ad5399152d8c643fae7b", symbol: "PHTK", coinGeckoId: "phuntoken", decimals: 18, price: 0.00091536}, // Addr: 0x1fee5588cb1de19c70b6ad5399152d8c643fae7b, Notional: 0.9153600000000001 + {chain: 2, addr: "00000000000000000000000020a62aca58526836165ca53fe67dd884288c8abf", symbol: "RNB", coinGeckoId: "rentible", decimals: 18, price: 0.110229}, // Addr: 0x20a62aca58526836165ca53fe67dd884288c8abf, Notional: 5943.636726409913 + {chain: 2, addr: "00000000000000000000000020e7125677311fca903a8897042b9983f22ea295", symbol: "FWT", coinGeckoId: "freeway", decimals: 18, price: 0.00005064}, // Addr: 0x20e7125677311fca903a8897042b9983f22ea295, Notional: 0.0029432522897928 + {chain: 2, addr: "00000000000000000000000021381e026ad6d8266244f2a583b35f9e4413fa2a", symbol: "FORM", coinGeckoId: "formation-fi", decimals: 18, price: 0.0006149}, // Addr: 0x21381e026ad6d8266244f2a583b35f9e4413fa2a, Notional: 214.80281972717324 + {chain: 2, addr: "00000000000000000000000021bfbda47a0b4b5b1248c767ee49f7caa9b23697", symbol: "OVR", coinGeckoId: "ovr", decimals: 18, price: 0.311931}, // Addr: 0x21bfbda47a0b4b5b1248c767ee49f7caa9b23697, Notional: 46.78965 + {chain: 2, addr: "000000000000000000000000221657776846890989a759ba2973e427dff5c9bb", symbol: "REPv2", coinGeckoId: "augur", decimals: 18, price: 0.588726}, // Addr: 0x221657776846890989a759ba2973e427dff5c9bb, Notional: 0.588726 + {chain: 2, addr: "0000000000000000000000002260fac5e5542a773aa44fbcfedf7c193bc2c599", symbol: "WBTC", coinGeckoId: "wrapped-bitcoin", decimals: 8, price: 93245}, // Addr: 0x2260fac5e5542a773aa44fbcfedf7c193bc2c599, Notional: 302004666.0986225 + {chain: 2, addr: "00000000000000000000000022c5543d1a35178cb03b33f929a959145e538532", symbol: "WAL", coinGeckoId: "the-wasted-lands", decimals: 18, price: 0.00007653}, // Addr: 0x22c5543d1a35178cb03b33f929a959145e538532, Notional: 0.1010113176892182 + {chain: 2, addr: "00000000000000000000000022fc5a29bd3d6cce19a06f844019fd506fce4455", symbol: "ePendle", coinGeckoId: "equilibria-finance-ependle", decimals: 18, price: 1.49}, // Addr: 0x22fc5a29bd3d6cce19a06f844019fd506fce4455, Notional: 2965.4752731731 + {chain: 2, addr: "0000000000000000000000002370f9d504c7a6e775bf6e14b3f12846b594cd53", symbol: "JPYC", coinGeckoId: "jpyc", decimals: 18, price: 0.00714334}, // Addr: 0x2370f9d504c7a6e775bf6e14b3f12846b594cd53, Notional: 7.143339999999999 + {chain: 2, addr: "00000000000000000000000024249b5a869a445c9b0ce269a08d73c618df9d21", symbol: "ETHEREUM", coinGeckoId: "harrypottertrumphomersimpson777inu", decimals: 8, price: 0.00049162}, // Addr: 0x24249b5a869a445c9b0ce269a08d73c618df9d21, Notional: 2.408938 + {chain: 2, addr: "000000000000000000000000249e38ea4102d0cf8264d3701f1a0e39c4f2dc3b", symbol: "UFO", coinGeckoId: "ufo-gaming", decimals: 18, price: 5.8381e-7}, // Addr: 0x249e38ea4102d0cf8264d3701f1a0e39c4f2dc3b, Notional: 17.778473573761037 + {chain: 2, addr: "000000000000000000000000255f1b39172f65dc6406b8bee8b08155c45fe1b6", symbol: "HARAMBE", coinGeckoId: "harambecoin", decimals: 18, price: 5.6888e-7}, // Addr: 0x255f1b39172f65dc6406b8bee8b08155c45fe1b6, Notional: 75391.85220962073 + {chain: 2, addr: "00000000000000000000000025722cd432d02895d9be45f5deb60fc479c8781e", symbol: "SPONGE", coinGeckoId: "sponge-f08b2fe4-9d9c-47c3-b5a0-84c2ac3bbbff", decimals: 18, price: 0.00011489}, // Addr: 0x25722cd432d02895d9be45f5deb60fc479c8781e, Notional: 4.041674643489644 + {chain: 2, addr: "0000000000000000000000002598c30330d5771ae9f983979209486ae26de875", symbol: "AI", coinGeckoId: "any-inu", decimals: 18, price: 0.00000937}, // Addr: 0x2598c30330d5771ae9f983979209486ae26de875, Notional: 533611.1746505223 + {chain: 2, addr: "00000000000000000000000025cbb21a9da7c3c63bb77ccca5b2e2482aedb710", symbol: "HOBA", coinGeckoId: "honey-badger-2", decimals: 9, price: 0.231395}, // Addr: 0x25cbb21a9da7c3c63bb77ccca5b2e2482aedb710, Notional: 3589.1358805274085 + {chain: 2, addr: "00000000000000000000000027702a26126e0b3702af63ee09ac4d1a084ef628", symbol: "ALEPH", coinGeckoId: "aleph", decimals: 18, price: 0.132321}, // Addr: 0x27702a26126e0b3702af63ee09ac4d1a084ef628, Notional: 814065.7820569059 + {chain: 2, addr: "0000000000000000000000002781246fe707bb15cee3e5ea354e2154a2877b16", symbol: "EL", coinGeckoId: "elysia", decimals: 18, price: 0.00844288}, // Addr: 0x2781246fe707bb15cee3e5ea354e2154a2877b16, Notional: 130992.11628536854 + {chain: 2, addr: "0000000000000000000000002ad9addd0d97ec3cdba27f92bf6077893b76ab0b", symbol: "PLANET", coinGeckoId: "planet-token", decimals: 18, price: 0.00000299}, // Addr: 0x2ad9addd0d97ec3cdba27f92bf6077893b76ab0b, Notional: 111798.85501007056 + {chain: 2, addr: "0000000000000000000000002b591e99afe9f32eaa6214f7b7629768c40eeb39", symbol: "HEX", coinGeckoId: "hex", decimals: 8, price: 0.00316472}, // Addr: 0x2b591e99afe9f32eaa6214f7b7629768c40eeb39, Notional: 88.48885720852695 + {chain: 2, addr: "0000000000000000000000002ba592f78db6436527729929aaf6c908497cb200", symbol: "CREAM", coinGeckoId: "cream-2", decimals: 18, price: 13.16}, // Addr: 0x2ba592f78db6436527729929aaf6c908497cb200, Notional: 130.685673468 + {chain: 2, addr: "0000000000000000000000002c537e5624e4af88a7ae4060c022609376c8d0eb", symbol: "TRYB", coinGeckoId: "bilira", decimals: 6, price: 0.0279144}, // Addr: 0x2c537e5624e4af88a7ae4060c022609376c8d0eb, Notional: 187.3941516723312 + {chain: 2, addr: "0000000000000000000000002c8ea636345a231e4b1a28f6eeb2072ed909c406", symbol: "MemElon", coinGeckoId: "meme-elon-doge-floki-2", decimals: 18, price: 2.1905e-11}, // Addr: 0x2c8ea636345a231e4b1a28f6eeb2072ed909c406, Notional: 3.9429000000000003 + {chain: 2, addr: "0000000000000000000000002c95d751da37a5c1d9c5a7fd465c1d50f3d96160", symbol: "WASSIE", coinGeckoId: "wassie", decimals: 18, price: 0.00000371}, // Addr: 0x2c95d751da37a5c1d9c5a7fd465c1d50f3d96160, Notional: 242413.70976115434 + {chain: 2, addr: "0000000000000000000000002cb5d9fd89d48c516f11904117c57e3934f39524", symbol: "CUTE", coinGeckoId: "pepe-uwu", decimals: 18, price: 6.6569e-8}, // Addr: 0x2cb5d9fd89d48c516f11904117c57e3934f39524, Notional: 7688.250876481625 + {chain: 2, addr: "0000000000000000000000002e95cea14dd384429eb3c4331b776c4cfbb6fcd9", symbol: "THN", coinGeckoId: "throne", decimals: 18, price: 0.0013672}, // Addr: 0x2e95cea14dd384429eb3c4331b776c4cfbb6fcd9, Notional: 0.024609600000000002 {chain: 2, addr: "000000000000000000000000309627af60f0926daa6041b8279484312f2bf060", symbol: "USDB", coinGeckoId: "usd-bancor", decimals: 18, price: 4.827e-9}, // Addr: 0x309627af60f0926daa6041b8279484312f2bf060, Notional: 0.00000246177 - {chain: 2, addr: "00000000000000000000000030d20208d987713f46dfd34ef128bb16c404d10f", symbol: "SD", coinGeckoId: "stader", decimals: 18, price: 1.026}, // Addr: 0x30d20208d987713f46dfd34ef128bb16c404d10f, Notional: 614490.019068435 - {chain: 2, addr: "00000000000000000000000031429d1856ad1377a8a0079410b297e1a9e214c2", symbol: "ANGLE", coinGeckoId: "angle-protocol", decimals: 18, price: 0.02465403}, // Addr: 0x31429d1856ad1377a8a0079410b297e1a9e214c2, Notional: 1878.0343126476307 - {chain: 2, addr: "00000000000000000000000032353a6c91143bfd6c7d363b546e62a9a2489a20", symbol: "AGLD", coinGeckoId: "adventure-gold", decimals: 18, price: 1.41}, // Addr: 0x32353a6c91143bfd6c7d363b546e62a9a2489a20, Notional: 2518.5073748979 - {chain: 2, addr: "00000000000000000000000032e7c8a6e920a3cf224b678112ac78fdc0fb09d1", symbol: "BOO", coinGeckoId: "boo-2", decimals: 18, price: 0.00005478}, // Addr: 0x32e7c8a6e920a3cf224b678112ac78fdc0fb09d1, Notional: 3.623615459227183 - {chain: 2, addr: "0000000000000000000000003301ee63fb29f863f2333bd4466acb46cd8323e6", symbol: "AKITA", coinGeckoId: "akita-inu", decimals: 18, price: 1.14886e-7}, // Addr: 0x3301ee63fb29f863f2333bd4466acb46cd8323e6, Notional: 28.828878124631427 - {chain: 2, addr: "00000000000000000000000033349b282065b0284d756f0577fb39c158f935e6", symbol: "MPL", coinGeckoId: "maple", decimals: 18, price: 18.63}, // Addr: 0x33349b282065b0284d756f0577fb39c158f935e6, Notional: 11536.7901141906 - {chain: 2, addr: "00000000000000000000000033d0568941c0c64ff7e0fb4fba0b11bd37deed9f", symbol: "RAMP", coinGeckoId: "ramp", decimals: 18, price: 0.086508}, // Addr: 0x33d0568941c0c64ff7e0fb4fba0b11bd37deed9f, Notional: 0.8650800000000001 - {chain: 2, addr: "00000000000000000000000033e80a92a9ea73dd02f6e732d1702d58c68388ca", symbol: "XB", coinGeckoId: "xbanking", decimals: 2, price: 0.278635}, // Addr: 0x33e80a92a9ea73dd02f6e732d1702d58c68388ca, Notional: 3698.8796250000005 - {chain: 2, addr: "00000000000000000000000033f391f4c4fe802b70b77ae37670037a92114a7c", symbol: "BURP", coinGeckoId: "burp", decimals: 18, price: 0.00031354}, // Addr: 0x33f391f4c4fe802b70b77ae37670037a92114a7c, Notional: 0.49980083709539824 - {chain: 2, addr: "0000000000000000000000003432b6a60d23ca0dfca7761b7ab56459d9c964d0", symbol: "FXS", coinGeckoId: "frax-share", decimals: 18, price: 3.57}, // Addr: 0x3432b6a60d23ca0dfca7761b7ab56459d9c964d0, Notional: 363667.02658625005 - {chain: 2, addr: "0000000000000000000000003506424f91fd33084466f402d5d97f05f8e3b4af", symbol: "CHZ", coinGeckoId: "chiliz", decimals: 18, price: 0.10037}, // Addr: 0x3506424f91fd33084466f402d5d97f05f8e3b4af, Notional: 35866.08962265884 - {chain: 2, addr: "000000000000000000000000354c8cda7e3b737d360513a0dc5abcee8ee1cea3", symbol: "BABYTRUMP", coinGeckoId: "babytrump", decimals: 18, price: 0.00859074}, // Addr: 0x354c8cda7e3b737d360513a0dc5abcee8ee1cea3, Notional: 48715.07154389893 - {chain: 2, addr: "0000000000000000000000003593d125a4f7849a1b059e64f4517a86dd60c95d", symbol: "OM", coinGeckoId: "mantra-dao", decimals: 18, price: 3.62}, // Addr: 0x3593d125a4f7849a1b059e64f4517a86dd60c95d, Notional: 6004.742714091 - {chain: 2, addr: "000000000000000000000000362bc847a3a9637d3af6624eec853618a43ed7d2", symbol: "PRQ", coinGeckoId: "parsiq", decimals: 18, price: 0.100655}, // Addr: 0x362bc847a3a9637d3af6624eec853618a43ed7d2, Notional: 122.91521782241 - {chain: 2, addr: "000000000000000000000000368c5290b13caa10284db58b4ad4f3e9ee8bf4c9", symbol: "KKO", coinGeckoId: "kineko", decimals: 18, price: 0.00024525}, // Addr: 0x368c5290b13caa10284db58b4ad4f3e9ee8bf4c9, Notional: 0.24904169267469753 - {chain: 2, addr: "000000000000000000000000383518188c0c6d7730d91b2c03a03c837814a899", symbol: "OHM", coinGeckoId: "olympus-v1", decimals: 9, price: 105.36}, // Addr: 0x383518188c0c6d7730d91b2c03a03c837814a899, Notional: 5.268000000000001 - {chain: 2, addr: "0000000000000000000000003845badade8e6dff049820680d1f14bd3903a5d0", symbol: "SAND", coinGeckoId: "the-sandbox", decimals: 18, price: 0.618816}, // Addr: 0x3845badade8e6dff049820680d1f14bd3903a5d0, Notional: 76053.95513132904 - {chain: 2, addr: "000000000000000000000000389999216860ab8e0175387a0c90e5c52522c945", symbol: "FEG", coinGeckoId: "feg-token", decimals: 9, price: 2.87583e-10}, // Addr: 0x389999216860ab8e0175387a0c90e5c52522c945, Notional: 2.7032802056366334 - {chain: 2, addr: "00000000000000000000000038e382f74dfb84608f3c1f10187f6bef5951de93", symbol: "MUBI", coinGeckoId: "multibit", decimals: 18, price: 0.03520993}, // Addr: 0x38e382f74dfb84608f3c1f10187f6bef5951de93, Notional: 629.5877763792755 - {chain: 2, addr: "000000000000000000000000394a16744dcd805bb0ca7252e70691f0dcac56aa", symbol: "TRZ", coinGeckoId: "trazable", decimals: 18, price: 0.00048946}, // Addr: 0x394a16744dcd805bb0ca7252e70691f0dcac56aa, Notional: 22.829175686275555 - {chain: 2, addr: "0000000000000000000000003a856d4effa670c54585a5d523e96513e148e95d", symbol: "TRIAS", coinGeckoId: "trias-token", decimals: 18, price: 5.98}, // Addr: 0x3a856d4effa670c54585a5d523e96513e148e95d, Notional: 413.91113695620004 - {chain: 2, addr: "0000000000000000000000003b484b82567a09e2588a13d54d032153f0c0aee0", symbol: "SOS", coinGeckoId: "opendao", decimals: 18, price: 1.2811e-8}, // Addr: 0x3b484b82567a09e2588a13d54d032153f0c0aee0, Notional: 10.67792298629234 + {chain: 2, addr: "00000000000000000000000030d20208d987713f46dfd34ef128bb16c404d10f", symbol: "SD", coinGeckoId: "stader", decimals: 18, price: 1.38}, // Addr: 0x30d20208d987713f46dfd34ef128bb16c404d10f, Notional: 831931.3479257411 + {chain: 2, addr: "00000000000000000000000031429d1856ad1377a8a0079410b297e1a9e214c2", symbol: "ANGLE", coinGeckoId: "angle-protocol", decimals: 18, price: 0.02023447}, // Addr: 0x31429d1856ad1377a8a0079410b297e1a9e214c2, Notional: 1541.371895720055 + {chain: 2, addr: "00000000000000000000000032353a6c91143bfd6c7d363b546e62a9a2489a20", symbol: "AGLD", coinGeckoId: "adventure-gold", decimals: 18, price: 2.44}, // Addr: 0x32353a6c91143bfd6c7d363b546e62a9a2489a20, Notional: 3808.9088425992 + {chain: 2, addr: "00000000000000000000000032e7c8a6e920a3cf224b678112ac78fdc0fb09d1", symbol: "BOO", coinGeckoId: "boo-2", decimals: 18, price: 0.00005436}, // Addr: 0x32e7c8a6e920a3cf224b678112ac78fdc0fb09d1, Notional: 3.5958330844028783 + {chain: 2, addr: "0000000000000000000000003301ee63fb29f863f2333bd4466acb46cd8323e6", symbol: "AKITA", coinGeckoId: "akita-inu", decimals: 18, price: 9.8823e-8}, // Addr: 0x3301ee63fb29f863f2333bd4466acb46cd8323e6, Notional: 24.79811485220524 + {chain: 2, addr: "00000000000000000000000033349b282065b0284d756f0577fb39c158f935e6", symbol: "MPL", coinGeckoId: "maple", decimals: 18, price: 15.64}, // Addr: 0x33349b282065b0284d756f0577fb39c158f935e6, Notional: 10987.0279002256 + {chain: 2, addr: "00000000000000000000000033d0568941c0c64ff7e0fb4fba0b11bd37deed9f", symbol: "RAMP", coinGeckoId: "ramp", decimals: 18, price: 0.065342}, // Addr: 0x33d0568941c0c64ff7e0fb4fba0b11bd37deed9f, Notional: 0.65342 + {chain: 2, addr: "00000000000000000000000033e80a92a9ea73dd02f6e732d1702d58c68388ca", symbol: "XB", coinGeckoId: "xbanking", decimals: 2, price: 0.431963}, // Addr: 0x33e80a92a9ea73dd02f6e732d1702d58c68388ca, Notional: 5734.308825 + {chain: 2, addr: "00000000000000000000000033f391f4c4fe802b70b77ae37670037a92114a7c", symbol: "BURP", coinGeckoId: "burp", decimals: 18, price: 0.00026018}, // Addr: 0x33f391f4c4fe802b70b77ae37670037a92114a7c, Notional: 0.4147419206336694 + {chain: 2, addr: "0000000000000000000000003432b6a60d23ca0dfca7761b7ab56459d9c964d0", symbol: "FXS", coinGeckoId: "frax-share", decimals: 18, price: 3.49}, // Addr: 0x3432b6a60d23ca0dfca7761b7ab56459d9c964d0, Notional: 355517.6254302557 + {chain: 2, addr: "0000000000000000000000003506424f91fd33084466f402d5d97f05f8e3b4af", symbol: "CHZ", coinGeckoId: "chiliz", decimals: 18, price: 0.081644}, // Addr: 0x3506424f91fd33084466f402d5d97f05f8e3b4af, Notional: 29174.56432352653 + {chain: 2, addr: "000000000000000000000000354c8cda7e3b737d360513a0dc5abcee8ee1cea3", symbol: "BABYTRUMP", coinGeckoId: "babytrump", decimals: 18, price: 0.00823909}, // Addr: 0x354c8cda7e3b737d360513a0dc5abcee8ee1cea3, Notional: 51769.06640222165 + {chain: 2, addr: "0000000000000000000000003593d125a4f7849a1b059e64f4517a86dd60c95d", symbol: "OM", coinGeckoId: "mantra-dao", decimals: 18, price: 3.84}, // Addr: 0x3593d125a4f7849a1b059e64f4517a86dd60c95d, Notional: 6369.671829312 + {chain: 2, addr: "000000000000000000000000362bc847a3a9637d3af6624eec853618a43ed7d2", symbol: "PRQ", coinGeckoId: "parsiq", decimals: 18, price: 0.262368}, // Addr: 0x362bc847a3a9637d3af6624eec853618a43ed7d2, Notional: 320.391633496896 + {chain: 2, addr: "000000000000000000000000368c5290b13caa10284db58b4ad4f3e9ee8bf4c9", symbol: "KKO", coinGeckoId: "kineko", decimals: 18, price: 0.00023768}, // Addr: 0x368c5290b13caa10284db58b4ad4f3e9ee8bf4c9, Notional: 0.24135465653383117 + {chain: 2, addr: "000000000000000000000000383518188c0c6d7730d91b2c03a03c837814a899", symbol: "OHM", coinGeckoId: "olympus-v1", decimals: 9, price: 115.18}, // Addr: 0x383518188c0c6d7730d91b2c03a03c837814a899, Notional: 5.759 + {chain: 2, addr: "0000000000000000000000003845badade8e6dff049820680d1f14bd3903a5d0", symbol: "SAND", coinGeckoId: "the-sandbox", decimals: 18, price: 0.546103}, // Addr: 0x3845badade8e6dff049820680d1f14bd3903a5d0, Notional: 62397.82769716002 + {chain: 2, addr: "000000000000000000000000389999216860ab8e0175387a0c90e5c52522c945", symbol: "FEG", coinGeckoId: "feg-token", decimals: 9, price: 8.8569e-11}, // Addr: 0x389999216860ab8e0175387a0c90e5c52522c945, Notional: 0.8325486017359545 + {chain: 2, addr: "00000000000000000000000038e382f74dfb84608f3c1f10187f6bef5951de93", symbol: "MUBI", coinGeckoId: "multibit", decimals: 18, price: 0.02101726}, // Addr: 0x38e382f74dfb84608f3c1f10187f6bef5951de93, Notional: 440.0794668984056 + {chain: 2, addr: "000000000000000000000000394a16744dcd805bb0ca7252e70691f0dcac56aa", symbol: "TRZ", coinGeckoId: "trazable", decimals: 18, price: 0.00048995}, // Addr: 0x394a16744dcd805bb0ca7252e70691f0dcac56aa, Notional: 22.852030048401723 + {chain: 2, addr: "0000000000000000000000003a856d4effa670c54585a5d523e96513e148e95d", symbol: "TRIAS", coinGeckoId: "trias-token", decimals: 18, price: 3.37}, // Addr: 0x3a856d4effa670c54585a5d523e96513e148e95d, Notional: 233.2576139703 + {chain: 2, addr: "0000000000000000000000003b484b82567a09e2588a13d54d032153f0c0aee0", symbol: "SOS", coinGeckoId: "opendao", decimals: 18, price: 1.1713e-8}, // Addr: 0x3b484b82567a09e2588a13d54d032153f0c0aee0, Notional: 9.762743887162767 {chain: 2, addr: "0000000000000000000000003d2b66bc4f9d6388bd2d97b95b565be1686aefb3", symbol: "LAMBO", coinGeckoId: "lambo-0fcbf0f7-1a8f-470d-ba09-797d5e95d836", decimals: 18, price: 1e-18}, // Addr: 0x3d2b66bc4f9d6388bd2d97b95b565be1686aefb3, Notional: 1.62256681646345e-12 {chain: 2, addr: "0000000000000000000000003d371413dd5489f3a04c07c0c2ce369c20986ceb", symbol: "YOUC", coinGeckoId: "youcash", decimals: 10, price: 0.088049}, // Addr: 0x3d371413dd5489f3a04c07c0c2ce369c20986ceb, Notional: 2175.3365802163526 - {chain: 2, addr: "0000000000000000000000003e70f6806171873d17d4bfc984a6f9d20f5a9018", symbol: "COIN", coinGeckoId: "brianarmstrongtrumpyellen", decimals: 18, price: 0.00013519}, // Addr: 0x3e70f6806171873d17d4bfc984a6f9d20f5a9018, Notional: 228.68299314860357 - {chain: 2, addr: "00000000000000000000000040d1f63b5d2048e67e9bedb1b4c2f1a9fb4b6817", symbol: "GOLD", coinGeckoId: "golden-goose", decimals: 18, price: 0.000024}, // Addr: 0x40d1f63b5d2048e67e9bedb1b4c2f1a9fb4b6817, Notional: 0.000017578800000000002 - {chain: 2, addr: "00000000000000000000000041e5560054824ea6b0732e656e3ad64e20e94e45", symbol: "CVC", coinGeckoId: "civic", decimals: 8, price: 0.162001}, // Addr: 0x41e5560054824ea6b0732e656e3ad64e20e94e45, Notional: 32.4002 - {chain: 2, addr: "000000000000000000000000420412e765bfa6d85aaac94b4f7b708c89be2e2b", symbol: "BRZ", coinGeckoId: "brz", decimals: 4, price: 0.159991}, // Addr: 0x420412e765bfa6d85aaac94b4f7b708c89be2e2b, Notional: 16.319081999999998 - {chain: 2, addr: "00000000000000000000000042069d11a2cc72388a2e06210921e839cfbd3280", symbol: "GNOME", coinGeckoId: "gnomeland", decimals: 18, price: 0.00033993}, // Addr: 0x42069d11a2cc72388a2e06210921e839cfbd3280, Notional: 381.0019112812427 - {chain: 2, addr: "000000000000000000000000423f4e6138e475d85cf7ea071ac92097ed631eea", symbol: "PNDC", coinGeckoId: "pond-coin", decimals: 18, price: 5.3444e-8}, // Addr: 0x423f4e6138e475d85cf7ea071ac92097ed631eea, Notional: 0.22964004974 - {chain: 2, addr: "000000000000000000000000427a03fb96d9a94a6727fbcfbba143444090dd64", symbol: "PIXL", coinGeckoId: "sappy-seals-pixl", decimals: 18, price: 0.03945239}, // Addr: 0x427a03fb96d9a94a6727fbcfbba143444090dd64, Notional: 0.43397629 - {chain: 2, addr: "0000000000000000000000004295c8556afee00264c0789dde2ddd2dba71acfe", symbol: "BISC", coinGeckoId: "bidao-smart-chain", decimals: 18, price: 0.00009331}, // Addr: 0x4295c8556afee00264c0789dde2ddd2dba71acfe, Notional: 93659.69222213753 - {chain: 2, addr: "0000000000000000000000004297394c20800e8a38a619a243e9bbe7681ff24e", symbol: "HOTCROSS", coinGeckoId: "hot-cross", decimals: 18, price: 0.00454378}, // Addr: 0x4297394c20800e8a38a619a243e9bbe7681ff24e, Notional: 4.54378 - {chain: 2, addr: "000000000000000000000000436da116249044e8b4464f0cf21dd93311d88190", symbol: "ZEUM", coinGeckoId: "colizeum", decimals: 18, price: 0.00087503}, // Addr: 0x436da116249044e8b4464f0cf21dd93311d88190, Notional: 875.03 - {chain: 2, addr: "00000000000000000000000043d4a3cd90ddd2f8f4f693170c9c8098163502ad", symbol: "D2D", coinGeckoId: "prime", decimals: 18, price: 0.00711159}, // Addr: 0x43d4a3cd90ddd2f8f4f693170c9c8098163502ad, Notional: 577.5440091278124 - {chain: 2, addr: "00000000000000000000000043fe2b0c5485c10e772a1843e32a7642ace5b88c", symbol: "RPILL", coinGeckoId: "red-pill-2", decimals: 18, price: 9.35549e-7}, // Addr: 0x43fe2b0c5485c10e772a1843e32a7642ace5b88c, Notional: 12940.462238458791 - {chain: 2, addr: "0000000000000000000000004507cef57c46789ef8d1a19ea45f4216bae2b528", symbol: "TOKEN", coinGeckoId: "tokenfi", decimals: 9, price: 0.067536}, // Addr: 0x4507cef57c46789ef8d1a19ea45f4216bae2b528, Notional: 4499.409167356179 - {chain: 2, addr: "00000000000000000000000045804880de22913dafe09f4980848ece6ecbaf78", symbol: "PAXG", coinGeckoId: "pax-gold", decimals: 18, price: 2641.19}, // Addr: 0x45804880de22913dafe09f4980848ece6ecbaf78, Notional: 9492.3468482448 - {chain: 2, addr: "000000000000000000000000464fdb8affc9bac185a7393fd4298137866dcfb8", symbol: "REALM", coinGeckoId: "realm", decimals: 18, price: 0.00130586}, // Addr: 0x464fdb8affc9bac185a7393fd4298137866dcfb8, Notional: 1.30586 - {chain: 2, addr: "0000000000000000000000004674672bcddda2ea5300f5207e1158185c944bc0", symbol: "GXT", coinGeckoId: "gem-exchange-and-trading", decimals: 18, price: 0.00010226}, // Addr: 0x4674672bcddda2ea5300f5207e1158185c944bc0, Notional: 43626.043418086185 - {chain: 2, addr: "0000000000000000000000004691937a7508860f876c9c0a2a617e7d9e945d4b", symbol: "WOO", coinGeckoId: "woo-network", decimals: 18, price: 0.294151}, // Addr: 0x4691937a7508860f876c9c0a2a617e7d9e945d4b, Notional: 5.88302 - {chain: 2, addr: "00000000000000000000000046cca329970b33e1a007dd4ef0594a1cedb3e72a", symbol: "YESP", coinGeckoId: "yesports", decimals: 18, price: 0.00021631}, // Addr: 0x46cca329970b33e1a007dd4ef0594a1cedb3e72a, Notional: 35.368922424116 - {chain: 2, addr: "000000000000000000000000471ea49dd8e60e697f4cac262b5fafcc307506e4", symbol: "xcRMRK", coinGeckoId: "rmrk", decimals: 10, price: 0.410762}, // Addr: 0x471ea49dd8e60e697f4cac262b5fafcc307506e4, Notional: 0.41092337606694 - {chain: 2, addr: "0000000000000000000000004730fb1463a6f1f44aeb45f6c5c422427f37f4d0", symbol: "FOUR", coinGeckoId: "the-4th-pillar", decimals: 18, price: 0.00071428}, // Addr: 0x4730fb1463a6f1f44aeb45f6c5c422427f37f4d0, Notional: 3334.6517728738972 - {chain: 2, addr: "0000000000000000000000004740735aa98dc8aa232bd049f8f0210458e7fca3", symbol: "RDT", coinGeckoId: "ridotto", decimals: 18, price: 0.01135525}, // Addr: 0x4740735aa98dc8aa232bd049f8f0210458e7fca3, Notional: 1.0273094675 - {chain: 2, addr: "000000000000000000000000476c5e26a75bd202a9683ffd34359c0cc15be0ff", symbol: "SRM", coinGeckoId: "serum", decimals: 6, price: 0.03891126}, // Addr: 0x476c5e26a75bd202a9683ffd34359c0cc15be0ff, Notional: 121102.89736677831 - {chain: 2, addr: "000000000000000000000000485d17a6f1b8780392d53d64751824253011a260", symbol: "TIME", coinGeckoId: "chronobank", decimals: 8, price: 22.63}, // Addr: 0x485d17a6f1b8780392d53d64751824253011a260, Notional: 20.367 - {chain: 2, addr: "000000000000000000000000490e3f4af13e1616ec97a8c6600c1061a8d0253e", symbol: "TRR", coinGeckoId: "terran-coin", decimals: 18, price: 0.0010422}, // Addr: 0x490e3f4af13e1616ec97a8c6600c1061a8d0253e, Notional: 2.7618300000000002 - {chain: 2, addr: "0000000000000000000000004a220e6096b25eadb88358cb44068a3248254675", symbol: "QNT", coinGeckoId: "quant-network", decimals: 18, price: 113.11}, // Addr: 0x4a220e6096b25eadb88358cb44068a3248254675, Notional: 5.6555 - {chain: 2, addr: "0000000000000000000000004b1e80cac91e2216eeb63e29b957eb91ae9c2be8", symbol: "JUP", coinGeckoId: "jupiter", decimals: 18, price: 0.0007861}, // Addr: 0x4b1e80cac91e2216eeb63e29b957eb91ae9c2be8, Notional: 20.393633562709084 - {chain: 2, addr: "0000000000000000000000004bd70556ae3f8a6ec6c4080a0c327b24325438f3", symbol: "HXRO", coinGeckoId: "hxro", decimals: 18, price: 0.00318074}, // Addr: 0x4bd70556ae3f8a6ec6c4080a0c327b24325438f3, Notional: 2207580.184027353 - {chain: 2, addr: "0000000000000000000000004c9edd5852cd905f086c759e8383e09bff1e68b3", symbol: "USDe", coinGeckoId: "ethena-usde", decimals: 18, price: 1.001}, // Addr: 0x4c9edd5852cd905f086c759e8383e09bff1e68b3, Notional: 25.025 - {chain: 2, addr: "0000000000000000000000004d224452801aced8b2f0aebe155379bb5d594381", symbol: "APE", coinGeckoId: "apecoin", decimals: 18, price: 1.47}, // Addr: 0x4d224452801aced8b2f0aebe155379bb5d594381, Notional: 122.5965894321 - {chain: 2, addr: "0000000000000000000000004da34f8264cb33a5c9f17081b9ef5ff6091116f4", symbol: "ELFI", coinGeckoId: "elyfi", decimals: 18, price: 0.0092183}, // Addr: 0x4da34f8264cb33a5c9f17081b9ef5ff6091116f4, Notional: 166011.91735788196 - {chain: 2, addr: "0000000000000000000000004e15361fd6b4bb609fa63c81a2be19d873717870", symbol: "FTM", coinGeckoId: "wrapped-fantom", decimals: 18, price: 1.003}, // Addr: 0x4e15361fd6b4bb609fa63c81a2be19d873717870, Notional: 9624.28381409639 - {chain: 2, addr: "0000000000000000000000004ec1b60b96193a64acae44778e51f7bff2007831", symbol: "EDGE", coinGeckoId: "edge", decimals: 18, price: 0.233007}, // Addr: 0x4ec1b60b96193a64acae44778e51f7bff2007831, Notional: 1992.55194155712 - {chain: 2, addr: "0000000000000000000000004fabb145d64652a948d72533023f6e7a623c7c53", symbol: "BUSD", coinGeckoId: "binance-usd", decimals: 18, price: 0.991874}, // Addr: 0x4fabb145d64652a948d72533023f6e7a623c7c53, Notional: 11978.247675281395 - {chain: 2, addr: "00000000000000000000000050b806c5fe274c07e46b96be8c68d2fd2d9597b4", symbol: "$TUCKER", coinGeckoId: "tucker-carlson", decimals: 18, price: 9.6096e-7}, // Addr: 0x50b806c5fe274c07e46b96be8c68d2fd2d9597b4, Notional: 1357.024519891632 - {chain: 2, addr: "00000000000000000000000050d1c9771902476076ecfc8b2a83ad6b9355a4c9", symbol: "FTX Token", coinGeckoId: "ftx-token", decimals: 18, price: 2.43}, // Addr: 0x50d1c9771902476076ecfc8b2a83ad6b9355a4c9, Notional: 583687.3488772293 - {chain: 2, addr: "000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca", symbol: "LINK", coinGeckoId: "chainlink", decimals: 18, price: 19.89}, // Addr: 0x514910771af9ca656af840dff83e8264ecf986ca, Notional: 422713.90488771995 + {chain: 2, addr: "0000000000000000000000003e70f6806171873d17d4bfc984a6f9d20f5a9018", symbol: "COIN", coinGeckoId: "brianarmstrongtrumpyellen", decimals: 18, price: 0.00010447}, // Addr: 0x3e70f6806171873d17d4bfc984a6f9d20f5a9018, Notional: 176.71804345169474 + {chain: 2, addr: "00000000000000000000000040d1f63b5d2048e67e9bedb1b4c2f1a9fb4b6817", symbol: "GOLD", coinGeckoId: "golden-goose", decimals: 18, price: 0.00006086}, // Addr: 0x40d1f63b5d2048e67e9bedb1b4c2f1a9fb4b6817, Notional: 0.000044576907 + {chain: 2, addr: "00000000000000000000000041e5560054824ea6b0732e656e3ad64e20e94e45", symbol: "CVC", coinGeckoId: "civic", decimals: 8, price: 0.221045}, // Addr: 0x41e5560054824ea6b0732e656e3ad64e20e94e45, Notional: 44.208999999999996 + {chain: 2, addr: "000000000000000000000000420412e765bfa6d85aaac94b4f7b708c89be2e2b", symbol: "BRZ", coinGeckoId: "brz", decimals: 4, price: 0.16085}, // Addr: 0x420412e765bfa6d85aaac94b4f7b708c89be2e2b, Notional: 16.4067 + {chain: 2, addr: "00000000000000000000000042069d11a2cc72388a2e06210921e839cfbd3280", symbol: "GNOME", coinGeckoId: "gnomeland", decimals: 18, price: 0.00022658}, // Addr: 0x42069d11a2cc72388a2e06210921e839cfbd3280, Notional: 253.95644120290638 + {chain: 2, addr: "000000000000000000000000423f4e6138e475d85cf7ea071ac92097ed631eea", symbol: "PNDC", coinGeckoId: "pond-coin", decimals: 18, price: 7.2599e-8}, // Addr: 0x423f4e6138e475d85cf7ea071ac92097ed631eea, Notional: 0.311945924165 + {chain: 2, addr: "000000000000000000000000427a03fb96d9a94a6727fbcfbba143444090dd64", symbol: "PIXL", coinGeckoId: "sappy-seals-pixl", decimals: 18, price: 0.08815}, // Addr: 0x427a03fb96d9a94a6727fbcfbba143444090dd64, Notional: 0.9696500000000001 + {chain: 2, addr: "0000000000000000000000004295c8556afee00264c0789dde2ddd2dba71acfe", symbol: "BISC", coinGeckoId: "bidao-smart-chain", decimals: 18, price: 0.00012597}, // Addr: 0x4295c8556afee00264c0789dde2ddd2dba71acfe, Notional: 126442.09012134459 + {chain: 2, addr: "0000000000000000000000004297394c20800e8a38a619a243e9bbe7681ff24e", symbol: "HOTCROSS", coinGeckoId: "hot-cross", decimals: 18, price: 0.0120224}, // Addr: 0x4297394c20800e8a38a619a243e9bbe7681ff24e, Notional: 12.022400000000001 + {chain: 2, addr: "000000000000000000000000436da116249044e8b4464f0cf21dd93311d88190", symbol: "ZEUM", coinGeckoId: "colizeum", decimals: 18, price: 0.00085967}, // Addr: 0x436da116249044e8b4464f0cf21dd93311d88190, Notional: 859.67 + {chain: 2, addr: "00000000000000000000000043d4a3cd90ddd2f8f4f693170c9c8098163502ad", symbol: "D2D", coinGeckoId: "prime", decimals: 18, price: 0.00669707}, // Addr: 0x43d4a3cd90ddd2f8f4f693170c9c8098163502ad, Notional: 543.8801529910469 + {chain: 2, addr: "00000000000000000000000043fe2b0c5485c10e772a1843e32a7642ace5b88c", symbol: "RPILL", coinGeckoId: "red-pill-2", decimals: 18, price: 0.00000137}, // Addr: 0x43fe2b0c5485c10e772a1843e32a7642ace5b88c, Notional: 18667.74733955734 + {chain: 2, addr: "0000000000000000000000004507cef57c46789ef8d1a19ea45f4216bae2b528", symbol: "TOKEN", coinGeckoId: "tokenfi", decimals: 9, price: 0.061928}, // Addr: 0x4507cef57c46789ef8d1a19ea45f4216bae2b528, Notional: 4125.790851042902 + {chain: 2, addr: "00000000000000000000000045804880de22913dafe09f4980848ece6ecbaf78", symbol: "PAXG", coinGeckoId: "pax-gold", decimals: 18, price: 2623.82}, // Addr: 0x45804880de22913dafe09f4980848ece6ecbaf78, Notional: 11808.526442717 + {chain: 2, addr: "000000000000000000000000464fdb8affc9bac185a7393fd4298137866dcfb8", symbol: "REALM", coinGeckoId: "realm", decimals: 18, price: 0.00078147}, // Addr: 0x464fdb8affc9bac185a7393fd4298137866dcfb8, Notional: 0.78147 + {chain: 2, addr: "0000000000000000000000004674672bcddda2ea5300f5207e1158185c944bc0", symbol: "GXT", coinGeckoId: "gem-exchange-and-trading", decimals: 18, price: 0.00001828}, // Addr: 0x4674672bcddda2ea5300f5207e1158185c944bc0, Notional: 7798.592545302323 + {chain: 2, addr: "0000000000000000000000004691937a7508860f876c9c0a2a617e7d9e945d4b", symbol: "WOO", coinGeckoId: "woo-network", decimals: 18, price: 0.207659}, // Addr: 0x4691937a7508860f876c9c0a2a617e7d9e945d4b, Notional: 4.15318 + {chain: 2, addr: "00000000000000000000000046cca329970b33e1a007dd4ef0594a1cedb3e72a", symbol: "YESP", coinGeckoId: "yesports", decimals: 18, price: 0.0001673}, // Addr: 0x46cca329970b33e1a007dd4ef0594a1cedb3e72a, Notional: 27.355280484279998 + {chain: 2, addr: "000000000000000000000000471ea49dd8e60e697f4cac262b5fafcc307506e4", symbol: "xcRMRK", coinGeckoId: "rmrk", decimals: 10, price: 0.282867}, // Addr: 0x471ea49dd8e60e697f4cac262b5fafcc307506e4, Notional: 0.28297812995828997 + {chain: 2, addr: "0000000000000000000000004730fb1463a6f1f44aeb45f6c5c422427f37f4d0", symbol: "FOUR", coinGeckoId: "the-4th-pillar", decimals: 18, price: 0.00137212}, // Addr: 0x4730fb1463a6f1f44aeb45f6c5c422427f37f4d0, Notional: 6405.810593318771 + {chain: 2, addr: "0000000000000000000000004740735aa98dc8aa232bd049f8f0210458e7fca3", symbol: "RDT", coinGeckoId: "ridotto", decimals: 18, price: 0.01128631}, // Addr: 0x4740735aa98dc8aa232bd049f8f0210458e7fca3, Notional: 1.0210724657 + {chain: 2, addr: "000000000000000000000000476c5e26a75bd202a9683ffd34359c0cc15be0ff", symbol: "SRM", coinGeckoId: "serum", decimals: 6, price: 0.03198372}, // Addr: 0x476c5e26a75bd202a9683ffd34359c0cc15be0ff, Notional: 99542.42449532024 + {chain: 2, addr: "000000000000000000000000485d17a6f1b8780392d53d64751824253011a260", symbol: "TIME", coinGeckoId: "chronobank", decimals: 8, price: 20.99}, // Addr: 0x485d17a6f1b8780392d53d64751824253011a260, Notional: 18.891 + {chain: 2, addr: "000000000000000000000000490e3f4af13e1616ec97a8c6600c1061a8d0253e", symbol: "TRR", coinGeckoId: "terran-coin", decimals: 18, price: 0.00029301}, // Addr: 0x490e3f4af13e1616ec97a8c6600c1061a8d0253e, Notional: 0.7764765 + {chain: 2, addr: "0000000000000000000000004a220e6096b25eadb88358cb44068a3248254675", symbol: "QNT", coinGeckoId: "quant-network", decimals: 18, price: 105.62}, // Addr: 0x4a220e6096b25eadb88358cb44068a3248254675, Notional: 5.281000000000001 + {chain: 2, addr: "0000000000000000000000004b1e80cac91e2216eeb63e29b957eb91ae9c2be8", symbol: "JUP", coinGeckoId: "jupiter", decimals: 18, price: 0.00073986}, // Addr: 0x4b1e80cac91e2216eeb63e29b957eb91ae9c2be8, Notional: 19.19403857995922 + {chain: 2, addr: "0000000000000000000000004bd70556ae3f8a6ec6c4080a0c327b24325438f3", symbol: "HXRO", coinGeckoId: "hxro", decimals: 18, price: 0.00735226}, // Addr: 0x4bd70556ae3f8a6ec6c4080a0c327b24325438f3, Notional: 5103090.035194444 + {chain: 2, addr: "0000000000000000000000004c9edd5852cd905f086c759e8383e09bff1e68b3", symbol: "USDe", coinGeckoId: "ethena-usde", decimals: 18, price: 0.996651}, // Addr: 0x4c9edd5852cd905f086c759e8383e09bff1e68b3, Notional: 24.916275 + {chain: 2, addr: "0000000000000000000000004d224452801aced8b2f0aebe155379bb5d594381", symbol: "APE", coinGeckoId: "apecoin", decimals: 18, price: 1.2}, // Addr: 0x4d224452801aced8b2f0aebe155379bb5d594381, Notional: 100.078848516 + {chain: 2, addr: "0000000000000000000000004da34f8264cb33a5c9f17081b9ef5ff6091116f4", symbol: "ELFI", coinGeckoId: "elyfi", decimals: 18, price: 0.00903}, // Addr: 0x4da34f8264cb33a5c9f17081b9ef5ff6091116f4, Notional: 158829.1720786833 + {chain: 2, addr: "0000000000000000000000004e15361fd6b4bb609fa63c81a2be19d873717870", symbol: "FTM", coinGeckoId: "wrapped-fantom", decimals: 18, price: 0.675103}, // Addr: 0x4e15361fd6b4bb609fa63c81a2be19d873717870, Notional: 6620.284688848877 + {chain: 2, addr: "0000000000000000000000004ec1b60b96193a64acae44778e51f7bff2007831", symbol: "EDGE", coinGeckoId: "edge", decimals: 18, price: 0.935752}, // Addr: 0x4ec1b60b96193a64acae44778e51f7bff2007831, Notional: 40.88568556618448 + {chain: 2, addr: "0000000000000000000000004fabb145d64652a948d72533023f6e7a623c7c53", symbol: "BUSD", coinGeckoId: "binance-usd", decimals: 18, price: 0.994995}, // Addr: 0x4fabb145d64652a948d72533023f6e7a623c7c53, Notional: 12025.88800832859 + {chain: 2, addr: "00000000000000000000000050b806c5fe274c07e46b96be8c68d2fd2d9597b4", symbol: "$TUCKER", coinGeckoId: "tucker-carlson", decimals: 18, price: 6.56677e-7}, // Addr: 0x50b806c5fe274c07e46b96be8c68d2fd2d9597b4, Notional: 927.3297438487318 + {chain: 2, addr: "00000000000000000000000050d1c9771902476076ecfc8b2a83ad6b9355a4c9", symbol: "FTX Token", coinGeckoId: "ftx-token", decimals: 18, price: 3.64}, // Addr: 0x50d1c9771902476076ecfc8b2a83ad6b9355a4c9, Notional: 871124.4170271188 + {chain: 2, addr: "000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca", symbol: "LINK", coinGeckoId: "chainlink", decimals: 18, price: 19.87}, // Addr: 0x514910771af9ca656af840dff83e8264ecf986ca, Notional: 420990.3827066428 {chain: 2, addr: "00000000000000000000000051fe2e572e97bfeb1d719809d743ec2675924edc", symbol: "VPAD", coinGeckoId: "vlaunch", decimals: 18, price: 0.08336}, // Addr: 0x51fe2e572e97bfeb1d719809d743ec2675924edc, Notional: 8.119264000000001 - {chain: 2, addr: "00000000000000000000000052284158e02425290f6b627aeb5fff65edf058ad", symbol: "FMB", coinGeckoId: "flappymoonbird", decimals: 18, price: 0.01302421}, // Addr: 0x52284158e02425290f6b627aeb5fff65edf058ad, Notional: 40967.19725165132 - {chain: 2, addr: "0000000000000000000000005483dc6abda5f094865120b2d251b5744fc2ecb5", symbol: "TPAD", coinGeckoId: "taopad", decimals: 18, price: 0.086345}, // Addr: 0x5483dc6abda5f094865120b2d251b5744fc2ecb5, Notional: 31.025209049373704 - {chain: 2, addr: "0000000000000000000000005488eff1976e4a56b4255e926d419a7054df196a", symbol: "CITTY", coinGeckoId: "citty-meme-coin", decimals: 18, price: 0.00581216}, // Addr: 0x5488eff1976e4a56b4255e926d419a7054df196a, Notional: 1453.7026555755815 - {chain: 2, addr: "00000000000000000000000056015bbe3c01fe05bc30a8a9a9fd9a88917e7db3", symbol: "CAT", coinGeckoId: "cat-token", decimals: 18, price: 0.08072}, // Addr: 0x56015bbe3c01fe05bc30a8a9a9fd9a88917e7db3, Notional: 161.44 - {chain: 2, addr: "000000000000000000000000569d0e52c3dbe95983bcc2434cb9f69d905be919", symbol: "roar", coinGeckoId: "roaring-kitty", decimals: 9, price: 0.00017772}, // Addr: 0x569d0e52c3dbe95983bcc2434cb9f69d905be919, Notional: 8289.602654560544 - {chain: 2, addr: "00000000000000000000000056b4f8c39e07d4d5d91692acf9d0f6d4d3493763", symbol: "TRISM", coinGeckoId: "trism", decimals: 18, price: 0.00052052}, // Addr: 0x56b4f8c39e07d4d5d91692acf9d0f6d4d3493763, Notional: 8.681387859739393 - {chain: 2, addr: "000000000000000000000000576e2bed8f7b46d34016198911cdf9886f78bea7", symbol: "TRUMP", coinGeckoId: "maga", decimals: 9, price: 1.53}, // Addr: 0x576e2bed8f7b46d34016198911cdf9886f78bea7, Notional: 6889576.495689488 - {chain: 2, addr: "000000000000000000000000582d872a1b094fc48f5de31d3b73f2d9be47def1", symbol: "TONCOIN", coinGeckoId: "the-open-network", decimals: 9, price: 6.45}, // Addr: 0x582d872a1b094fc48f5de31d3b73f2d9be47def1, Notional: 4465.528422084 - {chain: 2, addr: "00000000000000000000000058b6a8a3302369daec383334672404ee733ab239", symbol: "LPT", coinGeckoId: "livepeer", decimals: 18, price: 14.79}, // Addr: 0x58b6a8a3302369daec383334672404ee733ab239, Notional: 30.4556772981 - {chain: 2, addr: "00000000000000000000000058cb30368ceb2d194740b144eab4c2da8a917dcb", symbol: "ZYN", coinGeckoId: "zyncoin-2", decimals: 18, price: 0.02797399}, // Addr: 0x58cb30368ceb2d194740b144eab4c2da8a917dcb, Notional: 2540887.085312446 - {chain: 2, addr: "000000000000000000000000594daad7d77592a2b97b725a7ad59d7e188b5bfa", symbol: "APU", coinGeckoId: "apu-s-club", decimals: 18, price: 0.00084367}, // Addr: 0x594daad7d77592a2b97b725a7ad59d7e188b5bfa, Notional: 1750532.5797030034 - {chain: 2, addr: "000000000000000000000000595832f8fc6bf59c85c527fec3740a1b7a361269", symbol: "POWR", coinGeckoId: "power-ledger", decimals: 6, price: 0.30543}, // Addr: 0x595832f8fc6bf59c85c527fec3740a1b7a361269, Notional: 2901.5849999999996 - {chain: 2, addr: "00000000000000000000000059f4f336bf3d0c49dbfba4a74ebd2a6ace40539a", symbol: "CAT", coinGeckoId: "catcoin-cash", decimals: 9, price: 2.84432e-10}, // Addr: 0x59f4f336bf3d0c49dbfba4a74ebd2a6ace40539a, Notional: 35.46702436568279 - {chain: 2, addr: "0000000000000000000000005a98fcbea516cf06857215779fd812ca3bef1b32", symbol: "LDO", coinGeckoId: "lido-dao", decimals: 18, price: 1.75}, // Addr: 0x5a98fcbea516cf06857215779fd812ca3bef1b32, Notional: 847001.2285319024 - {chain: 2, addr: "0000000000000000000000005b52bfb8062ce664d74bbcd4cd6dc7df53fd7233", symbol: "ZENIQ", coinGeckoId: "zeniq", decimals: 18, price: 0.0069559}, // Addr: 0x5b52bfb8062ce664d74bbcd4cd6dc7df53fd7233, Notional: 1.8958656073268938 - {chain: 2, addr: "0000000000000000000000005da151b95657e788076d04d56234bd93e409cb09", symbol: "OTSea", coinGeckoId: "otsea", decimals: 18, price: 0.02314315}, // Addr: 0x5da151b95657e788076d04d56234bd93e409cb09, Notional: 7048.744412754665 - {chain: 2, addr: "0000000000000000000000005de8ab7e27f6e7a1fff3e5b337584aa43961beef", symbol: "SDEX", coinGeckoId: "smardex", decimals: 18, price: 0.0125874}, // Addr: 0x5de8ab7e27f6e7a1fff3e5b337584aa43961beef, Notional: 11857240.404892635 - {chain: 2, addr: "0000000000000000000000005eeaa2dcb23056f4e8654a349e57ebe5e76b5e6e", symbol: "VPP", coinGeckoId: "virtue-poker", decimals: 18, price: 0.00419504}, // Addr: 0x5eeaa2dcb23056f4e8654a349e57ebe5e76b5e6e, Notional: 0.419504 - {chain: 2, addr: "0000000000000000000000005f48d1fd6814cd1cd38aeb895755e57d519196d1", symbol: "WINS", coinGeckoId: "wins", decimals: 18, price: 0.03012258}, // Addr: 0x5f48d1fd6814cd1cd38aeb895755e57d519196d1, Notional: 3003395.36463498 - {chain: 2, addr: "0000000000000000000000005f944b0c4315cb7c3a846b025ab4045da44abf6c", symbol: "GCAKE", coinGeckoId: "pancake-games", decimals: 18, price: 9.5409e-8}, // Addr: 0x5f944b0c4315cb7c3a846b025ab4045da44abf6c, Notional: 0.07134345787051306 - {chain: 2, addr: "0000000000000000000000005f98805a4e8be255a32880fdec7f6728c6568ba0", symbol: "LUSD", coinGeckoId: "liquity-usd", decimals: 18, price: 0.997951}, // Addr: 0x5f98805a4e8be255a32880fdec7f6728c6568ba0, Notional: 1.995902 - {chain: 2, addr: "0000000000000000000000005fab9761d60419c9eeebe3915a8fa1ed7e8d2e1b", symbol: "DIMO", coinGeckoId: "dimo", decimals: 18, price: 0.224073}, // Addr: 0x5fab9761d60419c9eeebe3915a8fa1ed7e8d2e1b, Notional: 0.224073 - {chain: 2, addr: "0000000000000000000000006149c26cd2f7b5ccdb32029af817123f6e37df5b", symbol: "LPOOL", coinGeckoId: "launchpool", decimals: 18, price: 0.053112}, // Addr: 0x6149c26cd2f7b5ccdb32029af817123f6e37df5b, Notional: 0.053112 - {chain: 2, addr: "000000000000000000000000614da3b37b6f66f7ce69b4bbbcf9a55ce6168707", symbol: "MMX", coinGeckoId: "m2-global-wealth-limited-mmx", decimals: 18, price: 0.901384}, // Addr: 0x614da3b37b6f66f7ce69b4bbbcf9a55ce6168707, Notional: 67772.04780300976 - {chain: 2, addr: "00000000000000000000000064df3aab3b21cc275bb76c4a581cf8b726478ee0", symbol: "CRAMER", coinGeckoId: "cramer-coin", decimals: 18, price: 0.0006185}, // Addr: 0x64df3aab3b21cc275bb76c4a581cf8b726478ee0, Notional: 22128.531379428234 - {chain: 2, addr: "00000000000000000000000065e6b60ea01668634d68d0513fe814679f925bad", symbol: "PIXEL", coinGeckoId: "pixelverse", decimals: 18, price: 0.00046024}, // Addr: 0x65e6b60ea01668634d68d0513fe814679f925bad, Notional: 60113.18691915898 - {chain: 2, addr: "00000000000000000000000065ef703f5594d2573eb71aaf55bc0cb548492df4", symbol: "MULTI", coinGeckoId: "multichain", decimals: 18, price: 0.577897}, // Addr: 0x65ef703f5594d2573eb71aaf55bc0cb548492df4, Notional: 973.8706554313546 - {chain: 2, addr: "000000000000000000000000667102bd3413bfeaa3dffb48fa8288819e480a88", symbol: "TKX", coinGeckoId: "tokenize-xchange", decimals: 8, price: 13.69}, // Addr: 0x667102bd3413bfeaa3dffb48fa8288819e480a88, Notional: 410.7 - {chain: 2, addr: "000000000000000000000000667210a731447f8b385e068205759be2311b86d4", symbol: "ETF", coinGeckoId: "etf-the-token", decimals: 18, price: 0.00442728}, // Addr: 0x667210a731447f8b385e068205759be2311b86d4, Notional: 2617.786883862795 - {chain: 2, addr: "00000000000000000000000066c0dded8433c9ea86c8cf91237b14e10b4d70b7", symbol: "Mars", coinGeckoId: "mars", decimals: 18, price: 0.0000428}, // Addr: 0x66c0dded8433c9ea86c8cf91237b14e10b4d70b7, Notional: 6.266734376506515 - {chain: 2, addr: "0000000000000000000000006731827cb6879a2091ce3ab3423f7bf20539b579", symbol: "MPWR", coinGeckoId: "clubrare-empower", decimals: 18, price: 0.00004394}, // Addr: 0x6731827cb6879a2091ce3ab3423f7bf20539b579, Notional: 0.00008788 - {chain: 2, addr: "0000000000000000000000006781a0f84c7e9e846dcb84a9a5bd49333067b104", symbol: "ZAP", coinGeckoId: "zap", decimals: 18, price: 0.0037053}, // Addr: 0x6781a0f84c7e9e846dcb84a9a5bd49333067b104, Notional: 14.505734176176302 - {chain: 2, addr: "00000000000000000000000067f4c72a50f8df6487720261e188f2abe83f57d7", symbol: "wPOKT", coinGeckoId: "wrapped-pokt", decimals: 6, price: 0.05444}, // Addr: 0x67f4c72a50f8df6487720261e188f2abe83f57d7, Notional: 1.14324 - {chain: 2, addr: "00000000000000000000000068bbed6a47194eff1cf514b50ea91895597fc91e", symbol: "ANDY", coinGeckoId: "andy-the-wisguy", decimals: 18, price: 0.00025208}, // Addr: 0x68bbed6a47194eff1cf514b50ea91895597fc91e, Notional: 440.9224819845288 + {chain: 2, addr: "00000000000000000000000052284158e02425290f6b627aeb5fff65edf058ad", symbol: "FMB", coinGeckoId: "flappymoonbird", decimals: 18, price: 0.01460338}, // Addr: 0x52284158e02425290f6b627aeb5fff65edf058ad, Notional: 45065.790754211645 + {chain: 2, addr: "0000000000000000000000005483dc6abda5f094865120b2d251b5744fc2ecb5", symbol: "TPAD", coinGeckoId: "taopad", decimals: 18, price: 0.070961}, // Addr: 0x5483dc6abda5f094865120b2d251b5744fc2ecb5, Notional: 25.49747940648106 + {chain: 2, addr: "0000000000000000000000005488eff1976e4a56b4255e926d419a7054df196a", symbol: "CITTY", coinGeckoId: "citty-meme-coin", decimals: 18, price: 0.00332339}, // Addr: 0x5488eff1976e4a56b4255e926d419a7054df196a, Notional: 831.2264061060487 + {chain: 2, addr: "00000000000000000000000056015bbe3c01fe05bc30a8a9a9fd9a88917e7db3", symbol: "CAT", coinGeckoId: "cat-token", decimals: 18, price: 0.057747}, // Addr: 0x56015bbe3c01fe05bc30a8a9a9fd9a88917e7db3, Notional: 115.494 + {chain: 2, addr: "000000000000000000000000569d0e52c3dbe95983bcc2434cb9f69d905be919", symbol: "roar", coinGeckoId: "roaring-kitty", decimals: 9, price: 0.00013069}, // Addr: 0x569d0e52c3dbe95983bcc2434cb9f69d905be919, Notional: 6274.808154689729 + {chain: 2, addr: "00000000000000000000000056b4f8c39e07d4d5d91692acf9d0f6d4d3493763", symbol: "TRISM", coinGeckoId: "trism", decimals: 18, price: 0.00052052}, // Addr: 0x56b4f8c39e07d4d5d91692acf9d0f6d4d3493763, Notional: 10.018256892340899 + {chain: 2, addr: "000000000000000000000000576e2bed8f7b46d34016198911cdf9886f78bea7", symbol: "TRUMP", coinGeckoId: "maga", decimals: 9, price: 1.69}, // Addr: 0x576e2bed8f7b46d34016198911cdf9886f78bea7, Notional: 7790276.390686443 + {chain: 2, addr: "000000000000000000000000582d872a1b094fc48f5de31d3b73f2d9be47def1", symbol: "TONCOIN", coinGeckoId: "the-open-network", decimals: 9, price: 5.48}, // Addr: 0x582d872a1b094fc48f5de31d3b73f2d9be47def1, Notional: 3793.9683338016002 + {chain: 2, addr: "00000000000000000000000058b6a8a3302369daec383334672404ee733ab239", symbol: "LPT", coinGeckoId: "livepeer", decimals: 18, price: 14.88}, // Addr: 0x58b6a8a3302369daec383334672404ee733ab239, Notional: 30.6410059632 + {chain: 2, addr: "00000000000000000000000058cb30368ceb2d194740b144eab4c2da8a917dcb", symbol: "ZYN", coinGeckoId: "zyncoin-2", decimals: 18, price: 0.01956693}, // Addr: 0x58cb30368ceb2d194740b144eab4c2da8a917dcb, Notional: 1569886.3290811589 + {chain: 2, addr: "000000000000000000000000594daad7d77592a2b97b725a7ad59d7e188b5bfa", symbol: "APU", coinGeckoId: "apu-s-club", decimals: 18, price: 0.00048746}, // Addr: 0x594daad7d77592a2b97b725a7ad59d7e188b5bfa, Notional: 956151.9763995451 + {chain: 2, addr: "000000000000000000000000595832f8fc6bf59c85c527fec3740a1b7a361269", symbol: "POWR", coinGeckoId: "power-ledger", decimals: 6, price: 0.271216}, // Addr: 0x595832f8fc6bf59c85c527fec3740a1b7a361269, Notional: 2576.552 + {chain: 2, addr: "00000000000000000000000059f4f336bf3d0c49dbfba4a74ebd2a6ace40539a", symbol: "CAT", coinGeckoId: "catcoin-cash", decimals: 9, price: 1.96287e-10}, // Addr: 0x59f4f336bf3d0c49dbfba4a74ebd2a6ace40539a, Notional: 24.475852968958407 + {chain: 2, addr: "0000000000000000000000005a98fcbea516cf06857215779fd812ca3bef1b32", symbol: "LDO", coinGeckoId: "lido-dao", decimals: 18, price: 1.75}, // Addr: 0x5a98fcbea516cf06857215779fd812ca3bef1b32, Notional: 845654.3003379625 + {chain: 2, addr: "0000000000000000000000005b52bfb8062ce664d74bbcd4cd6dc7df53fd7233", symbol: "ZENIQ", coinGeckoId: "zeniq", decimals: 18, price: 0.00663845}, // Addr: 0x5b52bfb8062ce664d74bbcd4cd6dc7df53fd7233, Notional: 1.8093430096693768 + {chain: 2, addr: "0000000000000000000000005da151b95657e788076d04d56234bd93e409cb09", symbol: "OTSea", coinGeckoId: "otsea", decimals: 18, price: 0.01461225}, // Addr: 0x5da151b95657e788076d04d56234bd93e409cb09, Notional: 3911.7232965358185 + {chain: 2, addr: "0000000000000000000000005de8ab7e27f6e7a1fff3e5b337584aa43961beef", symbol: "SDEX", coinGeckoId: "smardex", decimals: 18, price: 0.01617981}, // Addr: 0x5de8ab7e27f6e7a1fff3e5b337584aa43961beef, Notional: 13622698.576382019 + {chain: 2, addr: "0000000000000000000000005eeaa2dcb23056f4e8654a349e57ebe5e76b5e6e", symbol: "VPP", coinGeckoId: "virtue-poker", decimals: 18, price: 0.00704262}, // Addr: 0x5eeaa2dcb23056f4e8654a349e57ebe5e76b5e6e, Notional: 0.704262 + {chain: 2, addr: "0000000000000000000000005f48d1fd6814cd1cd38aeb895755e57d519196d1", symbol: "WINS", coinGeckoId: "wins", decimals: 18, price: 0.02992344}, // Addr: 0x5f48d1fd6814cd1cd38aeb895755e57d519196d1, Notional: 2983539.9554066397 + {chain: 2, addr: "0000000000000000000000005f944b0c4315cb7c3a846b025ab4045da44abf6c", symbol: "GCAKE", coinGeckoId: "pancake-games", decimals: 18, price: 8.3813e-8}, // Addr: 0x5f944b0c4315cb7c3a846b025ab4045da44abf6c, Notional: 0.06267238137388832 + {chain: 2, addr: "0000000000000000000000005f98805a4e8be255a32880fdec7f6728c6568ba0", symbol: "LUSD", coinGeckoId: "liquity-usd", decimals: 18, price: 0.997526}, // Addr: 0x5f98805a4e8be255a32880fdec7f6728c6568ba0, Notional: 1.995052 + {chain: 2, addr: "0000000000000000000000005fab9761d60419c9eeebe3915a8fa1ed7e8d2e1b", symbol: "DIMO", coinGeckoId: "dimo", decimals: 18, price: 0.165445}, // Addr: 0x5fab9761d60419c9eeebe3915a8fa1ed7e8d2e1b, Notional: 0.165445 + {chain: 2, addr: "0000000000000000000000006149c26cd2f7b5ccdb32029af817123f6e37df5b", symbol: "LPOOL", coinGeckoId: "launchpool", decimals: 18, price: 0.061193}, // Addr: 0x6149c26cd2f7b5ccdb32029af817123f6e37df5b, Notional: 0.061193 + {chain: 2, addr: "000000000000000000000000614da3b37b6f66f7ce69b4bbbcf9a55ce6168707", symbol: "MMX", coinGeckoId: "m2-global-wealth-limited-mmx", decimals: 18, price: 1.54}, // Addr: 0x614da3b37b6f66f7ce69b4bbbcf9a55ce6168707, Notional: 92914.84854806 + {chain: 2, addr: "00000000000000000000000064df3aab3b21cc275bb76c4a581cf8b726478ee0", symbol: "CRAMER", coinGeckoId: "cramer-coin", decimals: 18, price: 0.00041383}, // Addr: 0x64df3aab3b21cc275bb76c4a581cf8b726478ee0, Notional: 15057.062907259673 + {chain: 2, addr: "00000000000000000000000065e6b60ea01668634d68d0513fe814679f925bad", symbol: "PIXEL", coinGeckoId: "pixelverse", decimals: 18, price: 0.00040843}, // Addr: 0x65e6b60ea01668634d68d0513fe814679f925bad, Notional: 53346.14317180623 + {chain: 2, addr: "00000000000000000000000065ef703f5594d2573eb71aaf55bc0cb548492df4", symbol: "MULTI", coinGeckoId: "multichain", decimals: 18, price: 0.380015}, // Addr: 0x65ef703f5594d2573eb71aaf55bc0cb548492df4, Notional: 651.4208127900669 + {chain: 2, addr: "000000000000000000000000667102bd3413bfeaa3dffb48fa8288819e480a88", symbol: "TKX", coinGeckoId: "tokenize-xchange", decimals: 8, price: 28.92}, // Addr: 0x667102bd3413bfeaa3dffb48fa8288819e480a88, Notional: 668.5697015472 + {chain: 2, addr: "000000000000000000000000667210a731447f8b385e068205759be2311b86d4", symbol: "ETF", coinGeckoId: "etf-the-token", decimals: 18, price: 0.0054528}, // Addr: 0x667210a731447f8b385e068205759be2311b86d4, Notional: 3224.1620860499106 + {chain: 2, addr: "00000000000000000000000066c0dded8433c9ea86c8cf91237b14e10b4d70b7", symbol: "Mars", coinGeckoId: "mars", decimals: 18, price: 0.00002784}, // Addr: 0x66c0dded8433c9ea86c8cf91237b14e10b4d70b7, Notional: 4.0763057252790045 + {chain: 2, addr: "0000000000000000000000006731827cb6879a2091ce3ab3423f7bf20539b579", symbol: "MPWR", coinGeckoId: "clubrare-empower", decimals: 18, price: 0.0000493}, // Addr: 0x6731827cb6879a2091ce3ab3423f7bf20539b579, Notional: 0.0000986 + {chain: 2, addr: "0000000000000000000000006781a0f84c7e9e846dcb84a9a5bd49333067b104", symbol: "ZAP", coinGeckoId: "zap", decimals: 18, price: 0.00228207}, // Addr: 0x6781a0f84c7e9e846dcb84a9a5bd49333067b104, Notional: 8.933986665432396 + {chain: 2, addr: "00000000000000000000000067f4c72a50f8df6487720261e188f2abe83f57d7", symbol: "wPOKT", coinGeckoId: "wrapped-pokt", decimals: 6, price: 0.03163311}, // Addr: 0x67f4c72a50f8df6487720261e188f2abe83f57d7, Notional: 0.66429531 + {chain: 2, addr: "00000000000000000000000068bbed6a47194eff1cf514b50ea91895597fc91e", symbol: "ANDY", coinGeckoId: "andy-the-wisguy", decimals: 18, price: 0.00017928}, // Addr: 0x68bbed6a47194eff1cf514b50ea91895597fc91e, Notional: 313.5853005799204 {chain: 2, addr: "0000000000000000000000006911f552842236bd9e8ea8ddbb3fb414e2c5fa9d", symbol: "SNP", coinGeckoId: "synapse-network", decimals: 18, price: 0.00531536}, // Addr: 0x6911f552842236bd9e8ea8ddbb3fb414e2c5fa9d, Notional: 21.5857098436341 - {chain: 2, addr: "0000000000000000000000006982508145454ce325ddbe47a25d4ec3d2311933", symbol: "PEPE", coinGeckoId: "pepe", decimals: 18, price: 0.00002001}, // Addr: 0x6982508145454ce325ddbe47a25d4ec3d2311933, Notional: 108185.46480588209 - {chain: 2, addr: "00000000000000000000000069a95185ee2a045cdc4bcd1b1df10710395e4e23", symbol: "POOLZ", coinGeckoId: "poolz-finance", decimals: 18, price: 0.01671}, // Addr: 0x69a95185ee2a045cdc4bcd1b1df10710395e4e23, Notional: 0.14708142 - {chain: 2, addr: "00000000000000000000000069b14e8d3cebfdd8196bfe530954a0c226e5008e", symbol: "SpacePi", coinGeckoId: "spacepi-token", decimals: 9, price: 1.662e-9}, // Addr: 0x69b14e8d3cebfdd8196bfe530954a0c226e5008e, Notional: 265.554017579537 - {chain: 2, addr: "0000000000000000000000006adb2e268de2aa1abf6578e4a8119b960e02928f", symbol: "ShibDoge", coinGeckoId: "shibadoge", decimals: 9, price: 3.2e-17}, // Addr: 0x6adb2e268de2aa1abf6578e4a8119b960e02928f, Notional: 7.534313200959999e-7 - {chain: 2, addr: "0000000000000000000000006b0b3a982b4634ac68dd83a4dbf02311ce324181", symbol: "ALI", coinGeckoId: "alethea-artificial-liquid-intelligence-token", decimals: 18, price: 0.01682653}, // Addr: 0x6b0b3a982b4634ac68dd83a4dbf02311ce324181, Notional: 499.72058898768387 - {chain: 2, addr: "0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f", symbol: "DAI", coinGeckoId: "dai", decimals: 18, price: 1}, // Addr: 0x6b175474e89094c44da98b954eedeac495271d0f, Notional: 2661996.28238984 - {chain: 2, addr: "0000000000000000000000006b3595068778dd592e39a122f4f5a5cf09c90fe2", symbol: "SUSHI", coinGeckoId: "sushi", decimals: 18, price: 1.35}, // Addr: 0x6b3595068778dd592e39a122f4f5a5cf09c90fe2, Notional: 54211.354135218004 - {chain: 2, addr: "0000000000000000000000006b4c7a5e3f0b99fcd83e9c089bddd6c7fce5c611", symbol: "MM", coinGeckoId: "million", decimals: 18, price: 1.13}, // Addr: 0x6b4c7a5e3f0b99fcd83e9c089bddd6c7fce5c611, Notional: 6752.169539563499 - {chain: 2, addr: "0000000000000000000000006b66ccd1340c479b07b390d326eadcbb84e726ba", symbol: "SEAM", coinGeckoId: "seamless-protocol", decimals: 18, price: 1.35}, // Addr: 0x6b66ccd1340c479b07b390d326eadcbb84e726ba, Notional: 13.5 - {chain: 2, addr: "0000000000000000000000006b89b97169a797d94f057f4a0b01e2ca303155e4", symbol: "CHAD", coinGeckoId: "chad-coin", decimals: 18, price: 0.00000953}, // Addr: 0x6b89b97169a797d94f057f4a0b01e2ca303155e4, Notional: 83825.2591888744 - {chain: 2, addr: "0000000000000000000000006c5ba91642f10282b576d91922ae6448c9d52f4e", symbol: "PHA", coinGeckoId: "pha", decimals: 18, price: 0.15976}, // Addr: 0x6c5ba91642f10282b576d91922ae6448c9d52f4e, Notional: 124117.98812689529 - {chain: 2, addr: "0000000000000000000000006de037ef9ad2725eb40118bb1702ebb27e4aeb24", symbol: "RNDR", coinGeckoId: "render-token", decimals: 18, price: 8.23}, // Addr: 0x6de037ef9ad2725eb40118bb1702ebb27e4aeb24, Notional: 2769396121.742868 - {chain: 2, addr: "0000000000000000000000006e9730ecffbed43fd876a264c982e254ef05a0de", symbol: "NORD", coinGeckoId: "nord-finance", decimals: 18, price: 0.03004349}, // Addr: 0x6e9730ecffbed43fd876a264c982e254ef05a0de, Notional: 0.3004349 - {chain: 2, addr: "0000000000000000000000006ec8a24cabdc339a06a172f8223ea557055adaa5", symbol: "GNX", coinGeckoId: "genaro-network", decimals: 9, price: 0.00042522}, // Addr: 0x6ec8a24cabdc339a06a172f8223ea557055adaa5, Notional: 0.7271262000000001 - {chain: 2, addr: "0000000000000000000000006fc13eace26590b80cccab1ba5d51890577d83b2", symbol: "UMB", coinGeckoId: "umbrella-network", decimals: 18, price: 0.01561949}, // Addr: 0x6fc13eace26590b80cccab1ba5d51890577d83b2, Notional: 2.0739706227812973 - {chain: 2, addr: "0000000000000000000000006fe2506d1ddd77c43a3eaf4c4e0f7aeb14f26765", symbol: "ORBT", coinGeckoId: "orbitt-pro", decimals: 18, price: 0.42139}, // Addr: 0x6fe2506d1ddd77c43a3eaf4c4e0f7aeb14f26765, Notional: 4.2139 - {chain: 2, addr: "00000000000000000000000070401dfd142a16dc7031c56e862fc88cb9537ce0", symbol: "BIRD", coinGeckoId: "bird-money", decimals: 18, price: 2.04}, // Addr: 0x70401dfd142a16dc7031c56e862fc88cb9537ce0, Notional: 22.44 - {chain: 2, addr: "00000000000000000000000070bef3bb2f001da2fddb207dae696cd9faff3f5d", symbol: "NST", coinGeckoId: "ninja-squad", decimals: 18, price: 7.39}, // Addr: 0x70bef3bb2f001da2fddb207dae696cd9faff3f5d, Notional: 33633702.12472741 - {chain: 2, addr: "00000000000000000000000070e8de73ce538da2beed35d14187f6959a8eca96", symbol: "XSGD", coinGeckoId: "xsgd", decimals: 6, price: 0.744945}, // Addr: 0x70e8de73ce538da2beed35d14187f6959a8eca96, Notional: 41.218309687875 - {chain: 2, addr: "00000000000000000000000071fc1f555a39e0b698653ab0b475488ec3c34d57", symbol: "RAIN", coinGeckoId: "rainmaker-games", decimals: 18, price: 0.0007762}, // Addr: 0x71fc1f555a39e0b698653ab0b475488ec3c34d57, Notional: 74.27438715187158 - {chain: 2, addr: "000000000000000000000000721a1b990699ee9d90b6327faad0a3e840ae8335", symbol: "LOOT", coinGeckoId: "loot", decimals: 18, price: 0.0165111}, // Addr: 0x721a1b990699ee9d90b6327faad0a3e840ae8335, Notional: 11.91275865 - {chain: 2, addr: "000000000000000000000000725c263e32c72ddc3a19bea12c5a0479a81ee688", symbol: "BMI", coinGeckoId: "bridge-mutual", decimals: 18, price: 0.00513065}, // Addr: 0x725c263e32c72ddc3a19bea12c5a0479a81ee688, Notional: 10157.750577893139 - {chain: 2, addr: "000000000000000000000000727f064a78dc734d33eec18d5370aef32ffd46e4", symbol: "ORION", coinGeckoId: "orion-money", decimals: 18, price: 0.00135035}, // Addr: 0x727f064a78dc734d33eec18d5370aef32ffd46e4, Notional: 110420.2529729792 - {chain: 2, addr: "00000000000000000000000072b886d09c117654ab7da13a14d603001de0b777", symbol: "XDEFI", coinGeckoId: "xdefi", decimals: 18, price: 0.08868}, // Addr: 0x72b886d09c117654ab7da13a14d603001de0b777, Notional: 243899.4396010366 - {chain: 2, addr: "00000000000000000000000072e364f2abdc788b7e918bc238b21f109cd634d7", symbol: "MVI", coinGeckoId: "metaverse-index", decimals: 18, price: 41.9}, // Addr: 0x72e364f2abdc788b7e918bc238b21f109cd634d7, Notional: 42.318907401 - {chain: 2, addr: "00000000000000000000000072e4f9f808c49a2a61de9c5896298920dc4eeea9", symbol: "BITCOIN", coinGeckoId: "harrypotterobamasonic10in", decimals: 8, price: 0.238414}, // Addr: 0x72e4f9f808c49a2a61de9c5896298920dc4eeea9, Notional: 1139795.814407942 - {chain: 2, addr: "00000000000000000000000072e5390edb7727e3d4e3436451dadaff675dbcc0", symbol: "HANU", coinGeckoId: "hanu-yokia", decimals: 12, price: 2.78793e-7}, // Addr: 0x72e5390edb7727e3d4e3436451dadaff675dbcc0, Notional: 50182.74 - {chain: 2, addr: "0000000000000000000000007495e5cc8f27e0bd5bd4cb86d17f0d841ca58ee4", symbol: "ARNC", coinGeckoId: "arnoya-classic", decimals: 18, price: 0.01054841}, // Addr: 0x7495e5cc8f27e0bd5bd4cb86d17f0d841ca58ee4, Notional: 2743.63089259 - {chain: 2, addr: "0000000000000000000000007616113782aadab041d7b10d474f8a0c04eff258", symbol: "VEE", coinGeckoId: "zeeverse", decimals: 18, price: 0.00052076}, // Addr: 0x7616113782aadab041d7b10d474f8a0c04eff258, Notional: 2.6038 - {chain: 2, addr: "000000000000000000000000761d38e5ddf6ccf6cf7c55759d5210750b5d60f3", symbol: "ELON", coinGeckoId: "dogelon-mars", decimals: 18, price: 2.12852e-7}, // Addr: 0x761d38e5ddf6ccf6cf7c55759d5210750b5d60f3, Notional: 38949.85137093235 + {chain: 2, addr: "0000000000000000000000006982508145454ce325ddbe47a25d4ec3d2311933", symbol: "PEPE", coinGeckoId: "pepe", decimals: 18, price: 0.00001994}, // Addr: 0x6982508145454ce325ddbe47a25d4ec3d2311933, Notional: 81312.56831371321 + {chain: 2, addr: "00000000000000000000000069a95185ee2a045cdc4bcd1b1df10710395e4e23", symbol: "POOLZ", coinGeckoId: "poolz-finance", decimals: 18, price: 0.0174019}, // Addr: 0x69a95185ee2a045cdc4bcd1b1df10710395e4e23, Notional: 0.15317152380000001 + {chain: 2, addr: "00000000000000000000000069b14e8d3cebfdd8196bfe530954a0c226e5008e", symbol: "SpacePi", coinGeckoId: "spacepi-token", decimals: 9, price: 1.351e-9}, // Addr: 0x69b14e8d3cebfdd8196bfe530954a0c226e5008e, Notional: 215.86250165460558 + {chain: 2, addr: "0000000000000000000000006adb2e268de2aa1abf6578e4a8119b960e02928f", symbol: "ShibDoge", coinGeckoId: "shibadoge", decimals: 9, price: 3e-17}, // Addr: 0x6adb2e268de2aa1abf6578e4a8119b960e02928f, Notional: 7.063418625899999e-7 + {chain: 2, addr: "0000000000000000000000006b0b3a982b4634ac68dd83a4dbf02311ce324181", symbol: "ALI", coinGeckoId: "alethea-artificial-liquid-intelligence-token", decimals: 18, price: 0.01044345}, // Addr: 0x6b0b3a982b4634ac68dd83a4dbf02311ce324181, Notional: 169398.8876827023 + {chain: 2, addr: "0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f", symbol: "DAI", coinGeckoId: "dai", decimals: 18, price: 0.99899}, // Addr: 0x6b175474e89094c44da98b954eedeac495271d0f, Notional: 2354115.936087805 + {chain: 2, addr: "0000000000000000000000006b3595068778dd592e39a122f4f5a5cf09c90fe2", symbol: "SUSHI", coinGeckoId: "sushi", decimals: 18, price: 1.36}, // Addr: 0x6b3595068778dd592e39a122f4f5a5cf09c90fe2, Notional: 54612.9197214048 + {chain: 2, addr: "0000000000000000000000006b4c7a5e3f0b99fcd83e9c089bddd6c7fce5c611", symbol: "MM", coinGeckoId: "million", decimals: 18, price: 0.995765}, // Addr: 0x6b4c7a5e3f0b99fcd83e9c089bddd6c7fce5c611, Notional: 5950.065576604821 + {chain: 2, addr: "0000000000000000000000006b66ccd1340c479b07b390d326eadcbb84e726ba", symbol: "SEAM", coinGeckoId: "seamless-protocol", decimals: 18, price: 0.860814}, // Addr: 0x6b66ccd1340c479b07b390d326eadcbb84e726ba, Notional: 8.608139999999999 + {chain: 2, addr: "0000000000000000000000006b89b97169a797d94f057f4a0b01e2ca303155e4", symbol: "CHAD", coinGeckoId: "chad-coin", decimals: 18, price: 0.00000729}, // Addr: 0x6b89b97169a797d94f057f4a0b01e2ca303155e4, Notional: 64122.365108803184 + {chain: 2, addr: "0000000000000000000000006c5ba91642f10282b576d91922ae6448c9d52f4e", symbol: "PHA", coinGeckoId: "pha", decimals: 18, price: 0.385115}, // Addr: 0x6c5ba91642f10282b576d91922ae6448c9d52f4e, Notional: 293913.9704275581 + {chain: 2, addr: "0000000000000000000000006de037ef9ad2725eb40118bb1702ebb27e4aeb24", symbol: "RNDR", coinGeckoId: "render-token", decimals: 18, price: 6.79}, // Addr: 0x6de037ef9ad2725eb40118bb1702ebb27e4aeb24, Notional: 2375011922.4032407 + {chain: 2, addr: "0000000000000000000000006e9730ecffbed43fd876a264c982e254ef05a0de", symbol: "NORD", coinGeckoId: "nord-finance", decimals: 18, price: 0.02612517}, // Addr: 0x6e9730ecffbed43fd876a264c982e254ef05a0de, Notional: 0.2612517 + {chain: 2, addr: "0000000000000000000000006ec8a24cabdc339a06a172f8223ea557055adaa5", symbol: "GNX", coinGeckoId: "genaro-network", decimals: 9, price: 0.00062015}, // Addr: 0x6ec8a24cabdc339a06a172f8223ea557055adaa5, Notional: 1.0604565 + {chain: 2, addr: "0000000000000000000000006fc13eace26590b80cccab1ba5d51890577d83b2", symbol: "UMB", coinGeckoId: "umbrella-network", decimals: 18, price: 0.01056118}, // Addr: 0x6fc13eace26590b80cccab1ba5d51890577d83b2, Notional: 1.4023234473024013 + {chain: 2, addr: "0000000000000000000000006fe2506d1ddd77c43a3eaf4c4e0f7aeb14f26765", symbol: "ORBT", coinGeckoId: "orbitt-pro", decimals: 18, price: 0.4663}, // Addr: 0x6fe2506d1ddd77c43a3eaf4c4e0f7aeb14f26765, Notional: 4.663 + {chain: 2, addr: "00000000000000000000000070401dfd142a16dc7031c56e862fc88cb9537ce0", symbol: "BIRD", coinGeckoId: "bird-money", decimals: 18, price: 0.856385}, // Addr: 0x70401dfd142a16dc7031c56e862fc88cb9537ce0, Notional: 9.420235 + {chain: 2, addr: "00000000000000000000000070bef3bb2f001da2fddb207dae696cd9faff3f5d", symbol: "NST", coinGeckoId: "ninja-squad", decimals: 18, price: 6.15}, // Addr: 0x70bef3bb2f001da2fddb207dae696cd9faff3f5d, Notional: 28342092.2409388 + {chain: 2, addr: "00000000000000000000000070e8de73ce538da2beed35d14187f6959a8eca96", symbol: "XSGD", coinGeckoId: "xsgd", decimals: 6, price: 0.732155}, // Addr: 0x70e8de73ce538da2beed35d14187f6959a8eca96, Notional: 40.510630354625 + {chain: 2, addr: "00000000000000000000000071fc1f555a39e0b698653ab0b475488ec3c34d57", symbol: "RAIN", coinGeckoId: "rainmaker-games", decimals: 18, price: 0.00134521}, // Addr: 0x71fc1f555a39e0b698653ab0b475488ec3c34d57, Notional: 128.72281414657195 + {chain: 2, addr: "000000000000000000000000721a1b990699ee9d90b6327faad0a3e840ae8335", symbol: "LOOT", coinGeckoId: "loot", decimals: 18, price: 0.01976477}, // Addr: 0x721a1b990699ee9d90b6327faad0a3e840ae8335, Notional: 14.260281555 + {chain: 2, addr: "000000000000000000000000725c263e32c72ddc3a19bea12c5a0479a81ee688", symbol: "BMI", coinGeckoId: "bridge-mutual", decimals: 18, price: 0.00262621}, // Addr: 0x725c263e32c72ddc3a19bea12c5a0479a81ee688, Notional: 5199.416476502733 + {chain: 2, addr: "000000000000000000000000727f064a78dc734d33eec18d5370aef32ffd46e4", symbol: "ORION", coinGeckoId: "orion-money", decimals: 18, price: 0.00118737}, // Addr: 0x727f064a78dc734d33eec18d5370aef32ffd46e4, Notional: 97439.42098691782 + {chain: 2, addr: "00000000000000000000000072b886d09c117654ab7da13a14d603001de0b777", symbol: "XDEFI", coinGeckoId: "xdefi", decimals: 18, price: 0.053981}, // Addr: 0x72b886d09c117654ab7da13a14d603001de0b777, Notional: 148465.67037780286 + {chain: 2, addr: "00000000000000000000000072e364f2abdc788b7e918bc238b21f109cd634d7", symbol: "MVI", coinGeckoId: "metaverse-index", decimals: 18, price: 34.07}, // Addr: 0x72e364f2abdc788b7e918bc238b21f109cd634d7, Notional: 34.410624705299995 + {chain: 2, addr: "00000000000000000000000072e4f9f808c49a2a61de9c5896298920dc4eeea9", symbol: "BITCOIN", coinGeckoId: "harrypotterobamasonic10in", decimals: 8, price: 0.158581}, // Addr: 0x72e4f9f808c49a2a61de9c5896298920dc4eeea9, Notional: 821441.4328301173 + {chain: 2, addr: "00000000000000000000000072e5390edb7727e3d4e3436451dadaff675dbcc0", symbol: "HANU", coinGeckoId: "hanu-yokia", decimals: 12, price: 2.26565e-7}, // Addr: 0x72e5390edb7727e3d4e3436451dadaff675dbcc0, Notional: 40781.7 + {chain: 2, addr: "0000000000000000000000007495e5cc8f27e0bd5bd4cb86d17f0d841ca58ee4", symbol: "ARNC", coinGeckoId: "arnoya-classic", decimals: 18, price: 0.01086905}, // Addr: 0x7495e5cc8f27e0bd5bd4cb86d17f0d841ca58ee4, Notional: 2827.02903595 + {chain: 2, addr: "0000000000000000000000007616113782aadab041d7b10d474f8a0c04eff258", symbol: "VEE", coinGeckoId: "zeeverse", decimals: 18, price: 0.00043972}, // Addr: 0x7616113782aadab041d7b10d474f8a0c04eff258, Notional: 2.1986 + {chain: 2, addr: "000000000000000000000000761d38e5ddf6ccf6cf7c55759d5210750b5d60f3", symbol: "ELON", coinGeckoId: "dogelon-mars", decimals: 18, price: 2.03255e-7}, // Addr: 0x761d38e5ddf6ccf6cf7c55759d5210750b5d60f3, Notional: 37193.6934602393 {chain: 2, addr: "000000000000000000000000762fcf5183ae366c0629d0bcd30b40f331496d0f", symbol: "DICE", coinGeckoId: "dice-bot", decimals: 18, price: 0.00007637}, // Addr: 0x762fcf5183ae366c0629d0bcd30b40f331496d0f, Notional: 0.07637000000000001 - {chain: 2, addr: "0000000000000000000000007659ce147d0e714454073a5dd7003544234b6aa0", symbol: "XCAD", coinGeckoId: "xcad-network", decimals: 18, price: 0.437693}, // Addr: 0x7659ce147d0e714454073a5dd7003544234b6aa0, Notional: 7280444.026615807 - {chain: 2, addr: "000000000000000000000000766d2fcece1e3eef32aae8711ab886ee95fd5b2a", symbol: "MVP", coinGeckoId: "maga-vp", decimals: 18, price: 0.0168212}, // Addr: 0x766d2fcece1e3eef32aae8711ab886ee95fd5b2a, Notional: 71511.14563594533 - {chain: 2, addr: "000000000000000000000000767fe9edc9e0df98e07454847909b5e959d7ca0e", symbol: "ILV", coinGeckoId: "illuvium", decimals: 18, price: 56.12}, // Addr: 0x767fe9edc9e0df98e07454847909b5e959d7ca0e, Notional: 5.612 - {chain: 2, addr: "0000000000000000000000007697b462a7c4ff5f8b55bdbc2f4076c2af9cf51a", symbol: "SARCO", coinGeckoId: "sarcophagus", decimals: 18, price: 0.00649969}, // Addr: 0x7697b462a7c4ff5f8b55bdbc2f4076c2af9cf51a, Notional: 0.31037545084249824 - {chain: 2, addr: "00000000000000000000000076e222b07c53d28b89b0bac18602810fc22b49a8", symbol: "JOE", coinGeckoId: "joe-coin", decimals: 18, price: 0.03707036}, // Addr: 0x76e222b07c53d28b89b0bac18602810fc22b49a8, Notional: 6581.715451486151 - {chain: 2, addr: "0000000000000000000000007777777777697cfeecf846a76326da79cc606517", symbol: "SIG", coinGeckoId: "xsigma", decimals: 18, price: 0.00471459}, // Addr: 0x7777777777697cfeecf846a76326da79cc606517, Notional: 0.471459 - {chain: 2, addr: "00000000000000000000000077e06c9eccf2e797fd462a92b6d7642ef85b0a44", symbol: "wTAO", coinGeckoId: "wrapped-tao", decimals: 9, price: 588.11}, // Addr: 0x77e06c9eccf2e797fd462a92b6d7642ef85b0a44, Notional: 10.3820646197 - {chain: 2, addr: "00000000000000000000000078a0a62fba6fb21a83fe8a3433d44c73a4017a6f", symbol: "OX", coinGeckoId: "open-exchange-token", decimals: 18, price: 0.00431491}, // Addr: 0x78a0a62fba6fb21a83fe8a3433d44c73a4017a6f, Notional: 279707.44492228003 - {chain: 2, addr: "0000000000000000000000007968bc6a03017ea2de509aaa816f163db0f35148", symbol: "HGET", coinGeckoId: "hedget", decimals: 6, price: 0.091928}, // Addr: 0x7968bc6a03017ea2de509aaa816f163db0f35148, Notional: 1487.999731168784 - {chain: 2, addr: "0000000000000000000000007a58c0be72be218b41c608b7fe7c5bb630736c71", symbol: "PEOPLE", coinGeckoId: "constitutiondao", decimals: 18, price: 0.06265}, // Addr: 0x7a58c0be72be218b41c608b7fe7c5bb630736c71, Notional: 42427.7273959803 - {chain: 2, addr: "0000000000000000000000007d1afa7b718fb893db30a3abc0cfc608aacfebb0", symbol: "MATIC", coinGeckoId: "matic-network", decimals: 18, price: 0.587051}, // Addr: 0x7d1afa7b718fb893db30a3abc0cfc608aacfebb0, Notional: 16328.300313827975 - {chain: 2, addr: "0000000000000000000000007ddc52c4de30e94be3a6a0a2b259b2850f421989", symbol: "GMT", coinGeckoId: "gmt-token", decimals: 18, price: 0.400034}, // Addr: 0x7ddc52c4de30e94be3a6a0a2b259b2850f421989, Notional: 577.2118790557183 + {chain: 2, addr: "0000000000000000000000007659ce147d0e714454073a5dd7003544234b6aa0", symbol: "XCAD", coinGeckoId: "xcad-network", decimals: 18, price: 0.247048}, // Addr: 0x7659ce147d0e714454073a5dd7003544234b6aa0, Notional: 4384028.851471653 + {chain: 2, addr: "000000000000000000000000766d2fcece1e3eef32aae8711ab886ee95fd5b2a", symbol: "MVP", coinGeckoId: "maga-vp", decimals: 18, price: 0.01239635}, // Addr: 0x766d2fcece1e3eef32aae8711ab886ee95fd5b2a, Notional: 54300.929462768465 + {chain: 2, addr: "000000000000000000000000767fe9edc9e0df98e07454847909b5e959d7ca0e", symbol: "ILV", coinGeckoId: "illuvium", decimals: 18, price: 37.61}, // Addr: 0x767fe9edc9e0df98e07454847909b5e959d7ca0e, Notional: 3.761 + {chain: 2, addr: "0000000000000000000000007697b462a7c4ff5f8b55bdbc2f4076c2af9cf51a", symbol: "SARCO", coinGeckoId: "sarcophagus", decimals: 18, price: 0.00083668}, // Addr: 0x7697b462a7c4ff5f8b55bdbc2f4076c2af9cf51a, Notional: 0.039953433503890405 + {chain: 2, addr: "00000000000000000000000076e222b07c53d28b89b0bac18602810fc22b49a8", symbol: "JOE", coinGeckoId: "joe-coin", decimals: 18, price: 0.02291562}, // Addr: 0x76e222b07c53d28b89b0bac18602810fc22b49a8, Notional: 4068.5898446733486 + {chain: 2, addr: "0000000000000000000000007777777777697cfeecf846a76326da79cc606517", symbol: "SIG", coinGeckoId: "xsigma", decimals: 18, price: 0.00420899}, // Addr: 0x7777777777697cfeecf846a76326da79cc606517, Notional: 0.420899 + {chain: 2, addr: "00000000000000000000000077e06c9eccf2e797fd462a92b6d7642ef85b0a44", symbol: "wTAO", coinGeckoId: "wrapped-tao", decimals: 9, price: 443.96}, // Addr: 0x77e06c9eccf2e797fd462a92b6d7642ef85b0a44, Notional: 7.837345749199999 + {chain: 2, addr: "00000000000000000000000078a0a62fba6fb21a83fe8a3433d44c73a4017a6f", symbol: "OX", coinGeckoId: "open-exchange-token", decimals: 18, price: 0.00540563}, // Addr: 0x78a0a62fba6fb21a83fe8a3433d44c73a4017a6f, Notional: 350411.7016334581 + {chain: 2, addr: "0000000000000000000000007968bc6a03017ea2de509aaa816f163db0f35148", symbol: "HGET", coinGeckoId: "hedget", decimals: 6, price: 0.08783}, // Addr: 0x7968bc6a03017ea2de509aaa816f163db0f35148, Notional: 1421.66713502474 + {chain: 2, addr: "0000000000000000000000007a58c0be72be218b41c608b7fe7c5bb630736c71", symbol: "PEOPLE", coinGeckoId: "constitutiondao", decimals: 18, price: 0.04591298}, // Addr: 0x7a58c0be72be218b41c608b7fe7c5bb630736c71, Notional: 29901.164034317142 + {chain: 2, addr: "0000000000000000000000007d1afa7b718fb893db30a3abc0cfc608aacfebb0", symbol: "MATIC", coinGeckoId: "matic-network", decimals: 18, price: 0.449834}, // Addr: 0x7d1afa7b718fb893db30a3abc0cfc608aacfebb0, Notional: 12511.731763288868 + {chain: 2, addr: "0000000000000000000000007ddc52c4de30e94be3a6a0a2b259b2850f421989", symbol: "GMT", coinGeckoId: "gmt-token", decimals: 18, price: 0.500553}, // Addr: 0x7ddc52c4de30e94be3a6a0a2b259b2850f421989, Notional: 722.2514528689486 {chain: 2, addr: "0000000000000000000000007e9c15c43f0d6c4a12e6bdff7c7d55d0f80e3e23", symbol: "ASTRADAO", coinGeckoId: "astra-dao", decimals: 18, price: 1.94569e-7}, // Addr: 0x7e9c15c43f0d6c4a12e6bdff7c7d55d0f80e3e23, Notional: 59.538077756201176 - {chain: 2, addr: "0000000000000000000000007f39c581f595b53c5cb19bd0b3f8da6c935e2ca0", symbol: "wstETH", coinGeckoId: "wrapped-steth", decimals: 18, price: 4258.57}, // Addr: 0x7f39c581f595b53c5cb19bd0b3f8da6c935e2ca0, Notional: 5710472.720286013 - {chain: 2, addr: "0000000000000000000000007fc66500c84a76ad7e9c93437bfc5ac33e2ddae9", symbol: "AAVE", coinGeckoId: "aave", decimals: 18, price: 221.33}, // Addr: 0x7fc66500c84a76ad7e9c93437bfc5ac33e2ddae9, Notional: 2397.2958298434005 - {chain: 2, addr: "0000000000000000000000007fd4d7737597e7b4ee22acbf8d94362343ae0a79", symbol: "WMC", coinGeckoId: "wrapped-mistcoin", decimals: 2, price: 7.99}, // Addr: 0x7fd4d7737597e7b4ee22acbf8d94362343ae0a79, Notional: 19.4157 - {chain: 2, addr: "000000000000000000000000808507121b80c02388fad14726482e061b8da827", symbol: "PENDLE", coinGeckoId: "pendle", decimals: 18, price: 5.52}, // Addr: 0x808507121b80c02388fad14726482e061b8da827, Notional: 15437445.343075607 - {chain: 2, addr: "00000000000000000000000080d55c03180349fff4a229102f62328220a96444", symbol: "OPUL", coinGeckoId: "opulous", decimals: 18, price: 0.103117}, // Addr: 0x80d55c03180349fff4a229102f62328220a96444, Notional: 10.94930386065383 - {chain: 2, addr: "000000000000000000000000814e0908b12a99fecf5bc101bb5d0b8b5cdf7d26", symbol: "MDT", coinGeckoId: "measurable-data-token", decimals: 18, price: 0.056482}, // Addr: 0x814e0908b12a99fecf5bc101bb5d0b8b5cdf7d26, Notional: 88654.2583746717 - {chain: 2, addr: "0000000000000000000000008287c7b963b405b7b8d467db9d79eec40625b13a", symbol: "SWINGBY", coinGeckoId: "swingby", decimals: 18, price: 0.00050987}, // Addr: 0x8287c7b963b405b7b8d467db9d79eec40625b13a, Notional: 5.7105440000000005 - {chain: 2, addr: "00000000000000000000000082f13ab56cc0d1b727e8253a943f0de75b048b0b", symbol: "PLAYFI", coinGeckoId: "playfi", decimals: 18, price: 0.02549284}, // Addr: 0x82f13ab56cc0d1b727e8253a943f0de75b048b0b, Notional: 6959.1007502972125 - {chain: 2, addr: "0000000000000000000000008353b92201f19b4812eee32efd325f7ede123718", symbol: "SCM", coinGeckoId: "scamfari", decimals: 18, price: 0.00000575}, // Addr: 0x8353b92201f19b4812eee32efd325f7ede123718, Notional: 115.06325 - {chain: 2, addr: "0000000000000000000000008390a1da07e376ef7add4be859ba74fb83aa02d5", symbol: "GROK", coinGeckoId: "grok-2", decimals: 9, price: 0.00765492}, // Addr: 0x8390a1da07e376ef7add4be859ba74fb83aa02d5, Notional: 240.43715050791312 - {chain: 2, addr: "00000000000000000000000083e6f1e41cdd28eaceb20cb649155049fac3d5aa", symbol: "POLS", coinGeckoId: "polkastarter", decimals: 18, price: 0.513654}, // Addr: 0x83e6f1e41cdd28eaceb20cb649155049fac3d5aa, Notional: 1.027308 - {chain: 2, addr: "0000000000000000000000008530b66ca3ddf50e0447eae8ad7ea7d5e62762ed", symbol: "METADOGE", coinGeckoId: "meta-doge", decimals: 18, price: 1.08984e-10}, // Addr: 0x8530b66ca3ddf50e0447eae8ad7ea7d5e62762ed, Notional: 2.7246 - {chain: 2, addr: "000000000000000000000000853d955acef822db058eb8505911ed77f175b99e", symbol: "FRAX", coinGeckoId: "frax", decimals: 18, price: 0.996303}, // Addr: 0x853d955acef822db058eb8505911ed77f175b99e, Notional: 59432.636267629394 - {chain: 2, addr: "00000000000000000000000085eee30c52b0b379b046fb0f85f4f3dc3009afec", symbol: "KEEP", coinGeckoId: "keep-network", decimals: 18, price: 0.153332}, // Addr: 0x85eee30c52b0b379b046fb0f85f4f3dc3009afec, Notional: 0.30716692896000003 - {chain: 2, addr: "000000000000000000000000875773784af8135ea0ef43b5a374aad105c5d39e", symbol: "IDLE", coinGeckoId: "idle", decimals: 18, price: 0.508981}, // Addr: 0x875773784af8135ea0ef43b5a374aad105c5d39e, Notional: 25.44905 + {chain: 2, addr: "0000000000000000000000007f39c581f595b53c5cb19bd0b3f8da6c935e2ca0", symbol: "wstETH", coinGeckoId: "wrapped-steth", decimals: 18, price: 3961.06}, // Addr: 0x7f39c581f595b53c5cb19bd0b3f8da6c935e2ca0, Notional: 5290984.376488038 + {chain: 2, addr: "0000000000000000000000007fc66500c84a76ad7e9c93437bfc5ac33e2ddae9", symbol: "AAVE", coinGeckoId: "aave", decimals: 18, price: 309.59}, // Addr: 0x7fc66500c84a76ad7e9c93437bfc5ac33e2ddae9, Notional: 3353.2680430182 + {chain: 2, addr: "0000000000000000000000007fd4d7737597e7b4ee22acbf8d94362343ae0a79", symbol: "WMC", coinGeckoId: "wrapped-mistcoin", decimals: 2, price: 25.57}, // Addr: 0x7fd4d7737597e7b4ee22acbf8d94362343ae0a79, Notional: 62.1351 + {chain: 2, addr: "000000000000000000000000808507121b80c02388fad14726482e061b8da827", symbol: "PENDLE", coinGeckoId: "pendle", decimals: 18, price: 4.86}, // Addr: 0x808507121b80c02388fad14726482e061b8da827, Notional: 13576489.898726301 + {chain: 2, addr: "00000000000000000000000080d55c03180349fff4a229102f62328220a96444", symbol: "OPUL", coinGeckoId: "opulous", decimals: 18, price: 0.07032}, // Addr: 0x80d55c03180349fff4a229102f62328220a96444, Notional: 7.466810006896799 + {chain: 2, addr: "000000000000000000000000814e0908b12a99fecf5bc101bb5d0b8b5cdf7d26", symbol: "MDT", coinGeckoId: "measurable-data-token", decimals: 18, price: 0.058865}, // Addr: 0x814e0908b12a99fecf5bc101bb5d0b8b5cdf7d26, Notional: 87665.40917950988 + {chain: 2, addr: "0000000000000000000000008287c7b963b405b7b8d467db9d79eec40625b13a", symbol: "SWINGBY", coinGeckoId: "swingby", decimals: 18, price: 0.00016313}, // Addr: 0x8287c7b963b405b7b8d467db9d79eec40625b13a, Notional: 1.827056 + {chain: 2, addr: "00000000000000000000000082f13ab56cc0d1b727e8253a943f0de75b048b0b", symbol: "PLAYFI", coinGeckoId: "playfi", decimals: 18, price: 0.02593259}, // Addr: 0x82f13ab56cc0d1b727e8253a943f0de75b048b0b, Notional: 7079.144831495823 + {chain: 2, addr: "0000000000000000000000008353b92201f19b4812eee32efd325f7ede123718", symbol: "SCM", coinGeckoId: "scamfari", decimals: 18, price: 0.00000556}, // Addr: 0x8353b92201f19b4812eee32efd325f7ede123718, Notional: 111.26116 + {chain: 2, addr: "0000000000000000000000008390a1da07e376ef7add4be859ba74fb83aa02d5", symbol: "GROK", coinGeckoId: "grok-2", decimals: 9, price: 0.00553327}, // Addr: 0x8390a1da07e376ef7add4be859ba74fb83aa02d5, Notional: 173.79720124977405 + {chain: 2, addr: "00000000000000000000000083e6f1e41cdd28eaceb20cb649155049fac3d5aa", symbol: "POLS", coinGeckoId: "polkastarter", decimals: 18, price: 0.38991}, // Addr: 0x83e6f1e41cdd28eaceb20cb649155049fac3d5aa, Notional: 0.77982 + {chain: 2, addr: "0000000000000000000000008457ca5040ad67fdebbcc8edce889a335bc0fbfb", symbol: "ALT", coinGeckoId: "altlayer", decimals: 18, price: 0.110069}, // Addr: 0x8457ca5040ad67fdebbcc8edce889a335bc0fbfb, Notional: 11.0179069 + {chain: 2, addr: "0000000000000000000000008530b66ca3ddf50e0447eae8ad7ea7d5e62762ed", symbol: "METADOGE", coinGeckoId: "meta-doge", decimals: 18, price: 1.69313e-10}, // Addr: 0x8530b66ca3ddf50e0447eae8ad7ea7d5e62762ed, Notional: 4.232825 + {chain: 2, addr: "000000000000000000000000853d955acef822db058eb8505911ed77f175b99e", symbol: "FRAX", coinGeckoId: "frax", decimals: 18, price: 0.993202}, // Addr: 0x853d955acef822db058eb8505911ed77f175b99e, Notional: 59247.65177489383 + {chain: 2, addr: "00000000000000000000000085eee30c52b0b379b046fb0f85f4f3dc3009afec", symbol: "KEEP", coinGeckoId: "keep-network", decimals: 18, price: 0.120333}, // Addr: 0x85eee30c52b0b379b046fb0f85f4f3dc3009afec, Notional: 0.24106069224 + {chain: 2, addr: "000000000000000000000000875773784af8135ea0ef43b5a374aad105c5d39e", symbol: "IDLE", coinGeckoId: "idle", decimals: 18, price: 0.612035}, // Addr: 0x875773784af8135ea0ef43b5a374aad105c5d39e, Notional: 30.60175 {chain: 2, addr: "0000000000000000000000008770b7dd89e5f759ee3b226e0c45e890f87ddc48", symbol: "MIRL", coinGeckoId: "made-in-real-life", decimals: 18, price: 0.0000265}, // Addr: 0x8770b7dd89e5f759ee3b226e0c45e890f87ddc48, Notional: 1916.9208993289617 - {chain: 2, addr: "00000000000000000000000087edffde3e14c7a66c9b9724747a1c5696b742e6", symbol: "SWAG", coinGeckoId: "swag-finance", decimals: 18, price: 0.00235386}, // Addr: 0x87edffde3e14c7a66c9b9724747a1c5696b742e6, Notional: 23.540953860000002 - {chain: 2, addr: "000000000000000000000000888888888889c00c67689029d7856aac1065ec11", symbol: "OPIUM", coinGeckoId: "opium", decimals: 18, price: 0.057015}, // Addr: 0x888888888889c00c67689029d7856aac1065ec11, Notional: 0.57015 - {chain: 2, addr: "0000000000000000000000008a854288a5976036a725879164ca3e91d30c6a1b", symbol: "GET", coinGeckoId: "get-token", decimals: 18, price: 1.48}, // Addr: 0x8a854288a5976036a725879164ca3e91d30c6a1b, Notional: 29.6 - {chain: 2, addr: "0000000000000000000000008a9c67fee641579deba04928c4bc45f66e26343a", symbol: "JRT", coinGeckoId: "jarvis-reward-token", decimals: 18, price: 0.00451893}, // Addr: 0x8a9c67fee641579deba04928c4bc45f66e26343a, Notional: 207660.20018473608 - {chain: 2, addr: "0000000000000000000000008ab7404063ec4dbcfd4598215992dc3f8ec853d7", symbol: "AKRO", coinGeckoId: "akropolis", decimals: 18, price: 0.00459367}, // Addr: 0x8ab7404063ec4dbcfd4598215992dc3f8ec853d7, Notional: 157.178906230774 - {chain: 2, addr: "0000000000000000000000008acee0fcee91cedad1c5013f031762c814740587", symbol: "SAUDIPEPE", coinGeckoId: "saudi-pepe", decimals: 18, price: 0.00000269}, // Addr: 0x8acee0fcee91cedad1c5013f031762c814740587, Notional: 12.190937664139751 - {chain: 2, addr: "0000000000000000000000008bc2bcb1b1896291942c36f3cca3c1afa0aaa7fd", symbol: "PACE", coinGeckoId: "3space-art", decimals: 18, price: 0.04376297}, // Addr: 0x8bc2bcb1b1896291942c36f3cca3c1afa0aaa7fd, Notional: 43.762969999999996 - {chain: 2, addr: "0000000000000000000000008c223a82e07fecb49d602150d7c2b3a4c9630310", symbol: "NFTE", coinGeckoId: "nftearth", decimals: 18, price: 0.00005538}, // Addr: 0x8c223a82e07fecb49d602150d7c2b3a4c9630310, Notional: 0.0393775797876318 + {chain: 2, addr: "00000000000000000000000087edffde3e14c7a66c9b9724747a1c5696b742e6", symbol: "SWAG", coinGeckoId: "swag-finance", decimals: 18, price: 0.00207921}, // Addr: 0x87edffde3e14c7a66c9b9724747a1c5696b742e6, Notional: 20.794179210000003 + {chain: 2, addr: "000000000000000000000000888888888889c00c67689029d7856aac1065ec11", symbol: "OPIUM", coinGeckoId: "opium", decimals: 18, price: 0.04704755}, // Addr: 0x888888888889c00c67689029d7856aac1065ec11, Notional: 0.4704755 + {chain: 2, addr: "0000000000000000000000008a854288a5976036a725879164ca3e91d30c6a1b", symbol: "GET", coinGeckoId: "get-token", decimals: 18, price: 0.736479}, // Addr: 0x8a854288a5976036a725879164ca3e91d30c6a1b, Notional: 14.72958 + {chain: 2, addr: "0000000000000000000000008a9c67fee641579deba04928c4bc45f66e26343a", symbol: "JRT", coinGeckoId: "jarvis-reward-token", decimals: 18, price: 0.00427984}, // Addr: 0x8a9c67fee641579deba04928c4bc45f66e26343a, Notional: 196673.2016558435 + {chain: 2, addr: "0000000000000000000000008ab7404063ec4dbcfd4598215992dc3f8ec853d7", symbol: "AKRO", coinGeckoId: "akropolis", decimals: 18, price: 0.00088488}, // Addr: 0x8ab7404063ec4dbcfd4598215992dc3f8ec853d7, Notional: 30.277418827536 + {chain: 2, addr: "0000000000000000000000008acee0fcee91cedad1c5013f031762c814740587", symbol: "SAUDIPEPE", coinGeckoId: "saudi-pepe", decimals: 18, price: 0.00000309}, // Addr: 0x8acee0fcee91cedad1c5013f031762c814740587, Notional: 14.003716498956072 + {chain: 2, addr: "0000000000000000000000008bc2bcb1b1896291942c36f3cca3c1afa0aaa7fd", symbol: "PACE", coinGeckoId: "3space-art", decimals: 18, price: 0.02484108}, // Addr: 0x8bc2bcb1b1896291942c36f3cca3c1afa0aaa7fd, Notional: 24.84108 + {chain: 2, addr: "0000000000000000000000008c223a82e07fecb49d602150d7c2b3a4c9630310", symbol: "NFTE", coinGeckoId: "nftearth", decimals: 18, price: 0.00001848}, // Addr: 0x8c223a82e07fecb49d602150d7c2b3a4c9630310, Notional: 0.0131400807958728 {chain: 2, addr: "0000000000000000000000008cb1d155a5a1d5d667611b7710920fd9d1cd727f", symbol: "AIRx", coinGeckoId: "aircoins", decimals: 8, price: 0.00000269}, // Addr: 0x8cb1d155a5a1d5d667611b7710920fd9d1cd727f, Notional: 0.00026900000000000003 - {chain: 2, addr: "0000000000000000000000008cc0f052fff7ead7f2edcccac895502e884a8a71", symbol: "ARTH", coinGeckoId: "arth", decimals: 18, price: 1.23}, // Addr: 0x8cc0f052fff7ead7f2edcccac895502e884a8a71, Notional: 6.15 - {chain: 2, addr: "0000000000000000000000008ce9137d39326ad0cd6491fb5cc0cba0e089b6a9", symbol: "SXP", coinGeckoId: "swipe", decimals: 18, price: 0.425851}, // Addr: 0x8ce9137d39326ad0cd6491fb5cc0cba0e089b6a9, Notional: 42667.85171062905 - {chain: 2, addr: "0000000000000000000000008db1d28ee0d822367af8d220c0dc7cb6fe9dc442", symbol: "ETHPAD", coinGeckoId: "ethpad", decimals: 18, price: 0.00209899}, // Addr: 0x8db1d28ee0d822367af8d220c0dc7cb6fe9dc442, Notional: 17.005660991295997 - {chain: 2, addr: "0000000000000000000000008ed97a637a790be1feff5e888d43629dc05408f6", symbol: "NPC", coinGeckoId: "non-playable-coin", decimals: 18, price: 0.034319}, // Addr: 0x8ed97a637a790be1feff5e888d43629dc05408f6, Notional: 10753241.007537989 - {chain: 2, addr: "0000000000000000000000008f006d1e1d9dc6c98996f50a4c810f17a47fbf19", symbol: "NSFW", coinGeckoId: "pleasure-coin", decimals: 18, price: 0.00002497}, // Addr: 0x8f006d1e1d9dc6c98996f50a4c810f17a47fbf19, Notional: 0.00018679294840690002 - {chain: 2, addr: "000000000000000000000000900db999074d9277c5da2a43f252d74366230da0", symbol: "GIV", coinGeckoId: "giveth", decimals: 18, price: 0.00751451}, // Addr: 0x900db999074d9277c5da2a43f252d74366230da0, Notional: 75.1451 - {chain: 2, addr: "0000000000000000000000009196e18bc349b1f64bc08784eae259525329a1ad", symbol: "PUSSY", coinGeckoId: "pussy-financial", decimals: 18, price: 0.00000739}, // Addr: 0x9196e18bc349b1f64bc08784eae259525329a1ad, Notional: 175.21740991000001 - {chain: 2, addr: "00000000000000000000000092d6c1e31e14520e676a687f0a93788b716beff5", symbol: "DYDX", coinGeckoId: "dydx", decimals: 18, price: 1.68}, // Addr: 0x92d6c1e31e14520e676a687f0a93788b716beff5, Notional: 73539.5971435104 - {chain: 2, addr: "000000000000000000000000949d48eca67b17269629c7194f4b727d4ef9e5d6", symbol: "MC", coinGeckoId: "merit-circle", decimals: 18, price: 0.23568}, // Addr: 0x949d48eca67b17269629c7194f4b727d4ef9e5d6, Notional: 15.107088 - {chain: 2, addr: "000000000000000000000000958a03181806cb8807bef40e864e55f89b3393d3", symbol: "UTX", coinGeckoId: "utix", decimals: 18, price: 0.01190289}, // Addr: 0x958a03181806cb8807bef40e864e55f89b3393d3, Notional: 4932.403820049654 - {chain: 2, addr: "00000000000000000000000095ad61b0a150d79219dcf64e1e6cc01f0b64c4ce", symbol: "SHIB", coinGeckoId: "shiba-inu", decimals: 18, price: 0.00002871}, // Addr: 0x95ad61b0a150d79219dcf64e1e6cc01f0b64c4ce, Notional: 191433.05284959066 - {chain: 2, addr: "0000000000000000000000009609b540e5dedddb147abbf9812ade06b1e61b2c", symbol: "MICKEY", coinGeckoId: "steamboat-willie", decimals: 18, price: 0.00069394}, // Addr: 0x9609b540e5dedddb147abbf9812ade06b1e61b2c, Notional: 82508.30521898175 - {chain: 2, addr: "0000000000000000000000009625ce7753ace1fa1865a47aae2c5c2ce4418569", symbol: "KAP", coinGeckoId: "kapital-dao", decimals: 18, price: 0.03001648}, // Addr: 0x9625ce7753ace1fa1865a47aae2c5c2ce4418569, Notional: 300.1648 - {chain: 2, addr: "00000000000000000000000096543ef8d2c75c26387c1a319ae69c0bee6f3fe7", symbol: "KUJI", coinGeckoId: "kujira", decimals: 6, price: 0.487545}, // Addr: 0x96543ef8d2c75c26387c1a319ae69c0bee6f3fe7, Notional: 0.487545 - {chain: 2, addr: "000000000000000000000000965697b4ef02f0de01384d0d4f9f782b1670c163", symbol: "OXY", coinGeckoId: "oxygen", decimals: 6, price: 0.04783756}, // Addr: 0x965697b4ef02f0de01384d0d4f9f782b1670c163, Notional: 7077.921818205464 - {chain: 2, addr: "000000000000000000000000965b85d4674f64422c4898c8f8083187f02b32c0", symbol: "SFIL", coinGeckoId: "filecoin-standard-full-hashrate", decimals: 8, price: 0.064663}, // Addr: 0x965b85d4674f64422c4898c8f8083187f02b32c0, Notional: 0.48234718219999995 - {chain: 2, addr: "000000000000000000000000967fb0d760ed3ce53afe2f0a071674cccae73550", symbol: "XETA", coinGeckoId: "xana", decimals: 18, price: 0.0032103}, // Addr: 0x967fb0d760ed3ce53afe2f0a071674cccae73550, Notional: 0.0032103 - {chain: 2, addr: "000000000000000000000000968cbe62c830a0ccf4381614662398505657a2a9", symbol: "TPY", coinGeckoId: "thrupenny", decimals: 8, price: 0.00802148}, // Addr: 0x968cbe62c830a0ccf4381614662398505657a2a9, Notional: 1909.6460395133172 - {chain: 2, addr: "000000000000000000000000968f6f898a6df937fc1859b323ac2f14643e3fed", symbol: "NWC", coinGeckoId: "newscrypto-coin", decimals: 18, price: 0.123294}, // Addr: 0x968f6f898a6df937fc1859b323ac2f14643e3fed, Notional: 0.123294 - {chain: 2, addr: "000000000000000000000000970b9bb2c0444f5e81e9d0efb84c8ccdcdcaf84d", symbol: "FUSE", coinGeckoId: "fuse-network-token", decimals: 18, price: 0.03470058}, // Addr: 0x970b9bb2c0444f5e81e9d0efb84c8ccdcdcaf84d, Notional: 0.6940116000000001 - {chain: 2, addr: "00000000000000000000000097a9bac06f90940bce9caec2b880ff17707519e4", symbol: "MNTO", coinGeckoId: "minato", decimals: 18, price: 1.21}, // Addr: 0x97a9bac06f90940bce9caec2b880ff17707519e4, Notional: 70.1233412055 - {chain: 2, addr: "00000000000000000000000098585dfc8d9e7d48f0b1ae47ce33332cf4237d96", symbol: "NEWO", coinGeckoId: "new-order", decimals: 18, price: 0.00456828}, // Addr: 0x98585dfc8d9e7d48f0b1ae47ce33332cf4237d96, Notional: 788938.8820079754 - {chain: 2, addr: "00000000000000000000000099d8a9c45b2eca8864373a26d1459e3dff1e17f3", symbol: "MIM", coinGeckoId: "magic-internet-money", decimals: 18, price: 0.99491}, // Addr: 0x99d8a9c45b2eca8864373a26d1459e3dff1e17f3, Notional: 470.98451216172367 - {chain: 2, addr: "0000000000000000000000009b83f827928abdf18cf1f7e67053572b9bceff3a", symbol: "ARTEM", coinGeckoId: "artem", decimals: 18, price: 0.00332612}, // Addr: 0x9b83f827928abdf18cf1f7e67053572b9bceff3a, Notional: 36471.44025736439 - {chain: 2, addr: "0000000000000000000000009be89d2a4cd102d8fecc6bf9da793be995c22541", symbol: "BBTC", coinGeckoId: "binance-wrapped-btc", decimals: 8, price: 93327}, // Addr: 0x9be89d2a4cd102d8fecc6bf9da793be995c22541, Notional: 1986.9364963500002 - {chain: 2, addr: "0000000000000000000000009d71ce49ab8a0e6d2a1e7bfb89374c9392fd6804", symbol: "Nvir", coinGeckoId: "nvirworld", decimals: 18, price: 0.00151328}, // Addr: 0x9d71ce49ab8a0e6d2a1e7bfb89374c9392fd6804, Notional: 7.566400000000001 - {chain: 2, addr: "0000000000000000000000009e20461bc2c4c980f62f1b279d71734207a6a356", symbol: "OMNI", coinGeckoId: "omnicat", decimals: 18, price: 0.00004722}, // Addr: 0x9e20461bc2c4c980f62f1b279d71734207a6a356, Notional: 511240.7425961646 - {chain: 2, addr: "0000000000000000000000009fa69536d1cda4a04cfb50688294de75b505a9ae", symbol: "DERC", coinGeckoId: "derace", decimals: 18, price: 0.10982}, // Addr: 0x9fa69536d1cda4a04cfb50688294de75b505a9ae, Notional: 10.982 - {chain: 2, addr: "0000000000000000000000009fda7ceec4c18008096c2fe2b85f05dc300f94d0", symbol: "GAJ", coinGeckoId: "gaj", decimals: 18, price: 0.00519906}, // Addr: 0x9fda7ceec4c18008096c2fe2b85f05dc300f94d0, Notional: 30.094846483412482 - {chain: 2, addr: "000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48", symbol: "USDC", coinGeckoId: "usd-coin", decimals: 6, price: 1}, // Addr: 0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48, Notional: 154010638.657905 - {chain: 2, addr: "000000000000000000000000a150db9b1fa65b44799d4dd949d922c0a33ee606", symbol: "DRC", coinGeckoId: "digital-reserve-currency", decimals: 0, price: 0.00020335}, // Addr: 0xa150db9b1fa65b44799d4dd949d922c0a33ee606, Notional: 6.22962725 - {chain: 2, addr: "000000000000000000000000a1d6df714f91debf4e0802a542e13067f31b8262", symbol: "RFOX", coinGeckoId: "redfox-labs-2", decimals: 18, price: 0.0012211}, // Addr: 0xa1d6df714f91debf4e0802a542e13067f31b8262, Notional: 67.1617211 - {chain: 2, addr: "000000000000000000000000a21af1050f7b26e0cff45ee51548254c41ed6b5c", symbol: "OSAK", coinGeckoId: "osaka-protocol", decimals: 18, price: 2.31317e-7}, // Addr: 0xa21af1050f7b26e0cff45ee51548254c41ed6b5c, Notional: 15154.15315275258 - {chain: 2, addr: "000000000000000000000000a2cd3d43c775978a96bdbf12d733d5a1ed94fb18", symbol: "XCN", coinGeckoId: "chain-2", decimals: 18, price: 0.00204894}, // Addr: 0xa2cd3d43c775978a96bdbf12d733d5a1ed94fb18, Notional: 938484.0982940868 - {chain: 2, addr: "000000000000000000000000a31b1767e09f842ecfd4bc471fe44f830e3891aa", symbol: "ROOBEE", coinGeckoId: "roobee", decimals: 18, price: 0.00046072}, // Addr: 0xa31b1767e09f842ecfd4bc471fe44f830e3891aa, Notional: 20.6652875994656 - {chain: 2, addr: "000000000000000000000000a35923162c49cf95e6bf26623385eb431ad920d3", symbol: "TURBO", coinGeckoId: "turbo", decimals: 18, price: 0.00714128}, // Addr: 0xa35923162c49cf95e6bf26623385eb431ad920d3, Notional: 801144.7006591785 + {chain: 2, addr: "0000000000000000000000008cc0f052fff7ead7f2edcccac895502e884a8a71", symbol: "ARTH", coinGeckoId: "arth", decimals: 18, price: 1.062}, // Addr: 0x8cc0f052fff7ead7f2edcccac895502e884a8a71, Notional: 5.3100000000000005 + {chain: 2, addr: "0000000000000000000000008ce9137d39326ad0cd6491fb5cc0cba0e089b6a9", symbol: "SXP", coinGeckoId: "swipe", decimals: 18, price: 0.32693}, // Addr: 0x8ce9137d39326ad0cd6491fb5cc0cba0e089b6a9, Notional: 32756.529301929444 + {chain: 2, addr: "0000000000000000000000008db1d28ee0d822367af8d220c0dc7cb6fe9dc442", symbol: "ETHPAD", coinGeckoId: "ethpad", decimals: 18, price: 0.0018564}, // Addr: 0x8db1d28ee0d822367af8d220c0dc7cb6fe9dc442, Notional: 15.04023795456 + {chain: 2, addr: "0000000000000000000000008ed97a637a790be1feff5e888d43629dc05408f6", symbol: "NPC", coinGeckoId: "non-playable-coin", decimals: 18, price: 0.0213007}, // Addr: 0x8ed97a637a790be1feff5e888d43629dc05408f6, Notional: 6887049.213435378 + {chain: 2, addr: "0000000000000000000000008f006d1e1d9dc6c98996f50a4c810f17a47fbf19", symbol: "NSFW", coinGeckoId: "pleasure-coin", decimals: 18, price: 0.00002127}, // Addr: 0x8f006d1e1d9dc6c98996f50a4c810f17a47fbf19, Notional: 0.00015911437775790002 + {chain: 2, addr: "000000000000000000000000900db999074d9277c5da2a43f252d74366230da0", symbol: "GIV", coinGeckoId: "giveth", decimals: 18, price: 0.00671915}, // Addr: 0x900db999074d9277c5da2a43f252d74366230da0, Notional: 67.1915 + {chain: 2, addr: "0000000000000000000000009196e18bc349b1f64bc08784eae259525329a1ad", symbol: "PUSSY", coinGeckoId: "pussy-financial", decimals: 18, price: 0.00000673}, // Addr: 0x9196e18bc349b1f64bc08784eae259525329a1ad, Notional: 7235.505516370645 + {chain: 2, addr: "00000000000000000000000092d6c1e31e14520e676a687f0a93788b716beff5", symbol: "DYDX", coinGeckoId: "dydx", decimals: 18, price: 1.42}, // Addr: 0x92d6c1e31e14520e676a687f0a93788b716beff5, Notional: 88783.18860701319 + {chain: 2, addr: "000000000000000000000000949d48eca67b17269629c7194f4b727d4ef9e5d6", symbol: "MC", coinGeckoId: "merit-circle", decimals: 18, price: 0.208234}, // Addr: 0x949d48eca67b17269629c7194f4b727d4ef9e5d6, Notional: 13.3477994 + {chain: 2, addr: "000000000000000000000000958a03181806cb8807bef40e864e55f89b3393d3", symbol: "UTX", coinGeckoId: "utix", decimals: 18, price: 0.01391177}, // Addr: 0x958a03181806cb8807bef40e864e55f89b3393d3, Notional: 5764.857735529118 + {chain: 2, addr: "00000000000000000000000095ad61b0a150d79219dcf64e1e6cc01f0b64c4ce", symbol: "SHIB", coinGeckoId: "shiba-inu", decimals: 18, price: 0.00002114}, // Addr: 0x95ad61b0a150d79219dcf64e1e6cc01f0b64c4ce, Notional: 138862.06545013882 + {chain: 2, addr: "0000000000000000000000009609b540e5dedddb147abbf9812ade06b1e61b2c", symbol: "MICKEY", coinGeckoId: "steamboat-willie", decimals: 18, price: 0.00052101}, // Addr: 0x9609b540e5dedddb147abbf9812ade06b1e61b2c, Notional: 61947.21748586576 + {chain: 2, addr: "0000000000000000000000009625ce7753ace1fa1865a47aae2c5c2ce4418569", symbol: "KAP", coinGeckoId: "kapital-dao", decimals: 18, price: 0.01978835}, // Addr: 0x9625ce7753ace1fa1865a47aae2c5c2ce4418569, Notional: 197.8835 + {chain: 2, addr: "00000000000000000000000096543ef8d2c75c26387c1a319ae69c0bee6f3fe7", symbol: "KUJI", coinGeckoId: "kujira", decimals: 6, price: 0.627629}, // Addr: 0x96543ef8d2c75c26387c1a319ae69c0bee6f3fe7, Notional: 0.627629 + {chain: 2, addr: "000000000000000000000000965697b4ef02f0de01384d0d4f9f782b1670c163", symbol: "OXY", coinGeckoId: "oxygen", decimals: 6, price: 0.0413812}, // Addr: 0x965697b4ef02f0de01384d0d4f9f782b1670c163, Notional: 6122.655468705426 + {chain: 2, addr: "000000000000000000000000965b85d4674f64422c4898c8f8083187f02b32c0", symbol: "SFIL", coinGeckoId: "filecoin-standard-full-hashrate", decimals: 8, price: 0.04804593}, // Addr: 0x965b85d4674f64422c4898c8f8083187f02b32c0, Notional: 0.358393810242 + {chain: 2, addr: "000000000000000000000000967fb0d760ed3ce53afe2f0a071674cccae73550", symbol: "XETA", coinGeckoId: "xana", decimals: 18, price: 0.00286157}, // Addr: 0x967fb0d760ed3ce53afe2f0a071674cccae73550, Notional: 0.00286157 + {chain: 2, addr: "000000000000000000000000968cbe62c830a0ccf4381614662398505657a2a9", symbol: "TPY", coinGeckoId: "thrupenny", decimals: 8, price: 0.00814424}, // Addr: 0x968cbe62c830a0ccf4381614662398505657a2a9, Notional: 1938.8710887324958 + {chain: 2, addr: "000000000000000000000000968f6f898a6df937fc1859b323ac2f14643e3fed", symbol: "NWC", coinGeckoId: "newscrypto-coin", decimals: 18, price: 0.079639}, // Addr: 0x968f6f898a6df937fc1859b323ac2f14643e3fed, Notional: 0.079639 + {chain: 2, addr: "000000000000000000000000970b9bb2c0444f5e81e9d0efb84c8ccdcdcaf84d", symbol: "FUSE", coinGeckoId: "fuse-network-token", decimals: 18, price: 0.02914856}, // Addr: 0x970b9bb2c0444f5e81e9d0efb84c8ccdcdcaf84d, Notional: 0.5829712 + {chain: 2, addr: "00000000000000000000000097a9bac06f90940bce9caec2b880ff17707519e4", symbol: "MNTO", coinGeckoId: "minato", decimals: 18, price: 0.799733}, // Addr: 0x97a9bac06f90940bce9caec2b880ff17707519e4, Notional: 46.34706614239515 + {chain: 2, addr: "00000000000000000000000098585dfc8d9e7d48f0b1ae47ce33332cf4237d96", symbol: "NEWO", coinGeckoId: "new-order", decimals: 18, price: 0.00384881}, // Addr: 0x98585dfc8d9e7d48f0b1ae47ce33332cf4237d96, Notional: 694318.2930035287 + {chain: 2, addr: "00000000000000000000000099d8a9c45b2eca8864373a26d1459e3dff1e17f3", symbol: "MIM", coinGeckoId: "magic-internet-money", decimals: 18, price: 0.994109}, // Addr: 0x99d8a9c45b2eca8864373a26d1459e3dff1e17f3, Notional: 470.60532349717965 + {chain: 2, addr: "0000000000000000000000009b83f827928abdf18cf1f7e67053572b9bceff3a", symbol: "ARTEM", coinGeckoId: "artem", decimals: 18, price: 0.00353644}, // Addr: 0x9b83f827928abdf18cf1f7e67053572b9bceff3a, Notional: 38777.63285261919 + {chain: 2, addr: "0000000000000000000000009be89d2a4cd102d8fecc6bf9da793be995c22541", symbol: "BBTC", coinGeckoId: "binance-wrapped-btc", decimals: 8, price: 92512}, // Addr: 0x9be89d2a4cd102d8fecc6bf9da793be995c22541, Notional: 1969.5851056000001 + {chain: 2, addr: "0000000000000000000000009d71ce49ab8a0e6d2a1e7bfb89374c9392fd6804", symbol: "Nvir", coinGeckoId: "nvirworld", decimals: 18, price: 0.00082302}, // Addr: 0x9d71ce49ab8a0e6d2a1e7bfb89374c9392fd6804, Notional: 4.1151 + {chain: 2, addr: "0000000000000000000000009dfad1b7102d46b1b197b90095b5c4e9f5845bba", symbol: "BOTTO", coinGeckoId: "botto", decimals: 18, price: 0.662803}, // Addr: 0x9dfad1b7102d46b1b197b90095b5c4e9f5845bba, Notional: 74.896739 + {chain: 2, addr: "0000000000000000000000009e20461bc2c4c980f62f1b279d71734207a6a356", symbol: "OMNI", coinGeckoId: "omnicat", decimals: 18, price: 0.00002616}, // Addr: 0x9e20461bc2c4c980f62f1b279d71734207a6a356, Notional: 299857.45950686594 + {chain: 2, addr: "0000000000000000000000009f52c8ecbee10e00d9faaac5ee9ba0ff6550f511", symbol: "SIPHER", coinGeckoId: "sipher", decimals: 18, price: 0.165237}, // Addr: 0x9f52c8ecbee10e00d9faaac5ee9ba0ff6550f511, Notional: 16.523699999999998 + {chain: 2, addr: "0000000000000000000000009fa69536d1cda4a04cfb50688294de75b505a9ae", symbol: "DERC", coinGeckoId: "derace", decimals: 18, price: 0.117109}, // Addr: 0x9fa69536d1cda4a04cfb50688294de75b505a9ae, Notional: 11.7109 + {chain: 2, addr: "0000000000000000000000009fda7ceec4c18008096c2fe2b85f05dc300f94d0", symbol: "GAJ", coinGeckoId: "gaj", decimals: 18, price: 0.00458522}, // Addr: 0x9fda7ceec4c18008096c2fe2b85f05dc300f94d0, Notional: 26.54162329203213 + {chain: 2, addr: "000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48", symbol: "USDC", coinGeckoId: "usd-coin", decimals: 6, price: 0.999339}, // Addr: 0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48, Notional: 115335167.18715532 + {chain: 2, addr: "000000000000000000000000a150db9b1fa65b44799d4dd949d922c0a33ee606", symbol: "DRC", coinGeckoId: "digital-reserve-currency", decimals: 0, price: 0.00023645}, // Addr: 0xa150db9b1fa65b44799d4dd949d922c0a33ee606, Notional: 7.24364575 + {chain: 2, addr: "000000000000000000000000a1d6df714f91debf4e0802a542e13067f31b8262", symbol: "RFOX", coinGeckoId: "redfox-labs-2", decimals: 18, price: 0.00084134}, // Addr: 0xa1d6df714f91debf4e0802a542e13067f31b8262, Notional: 46.27454134 + {chain: 2, addr: "000000000000000000000000a21af1050f7b26e0cff45ee51548254c41ed6b5c", symbol: "OSAK", coinGeckoId: "osaka-protocol", decimals: 18, price: 1.73011e-7}, // Addr: 0xa21af1050f7b26e0cff45ee51548254c41ed6b5c, Notional: 11334.38178391937 + {chain: 2, addr: "000000000000000000000000a2cd3d43c775978a96bdbf12d733d5a1ed94fb18", symbol: "XCN", coinGeckoId: "chain-2", decimals: 18, price: 0.00237335}, // Addr: 0xa2cd3d43c775978a96bdbf12d733d5a1ed94fb18, Notional: 1087074.8946705472 + {chain: 2, addr: "000000000000000000000000a31b1767e09f842ecfd4bc471fe44f830e3891aa", symbol: "ROOBEE", coinGeckoId: "roobee", decimals: 18, price: 0.00046531}, // Addr: 0xa31b1767e09f842ecfd4bc471fe44f830e3891aa, Notional: 20.8711689809588 + {chain: 2, addr: "000000000000000000000000a35923162c49cf95e6bf26623385eb431ad920d3", symbol: "TURBO", coinGeckoId: "turbo", decimals: 18, price: 0.00901428}, // Addr: 0xa35923162c49cf95e6bf26623385eb431ad920d3, Notional: 1130664.9159019175 {chain: 2, addr: "000000000000000000000000a3a80559bbc1989654e6b8385f5001fa1333332f", symbol: "RZR", coinGeckoId: "raiser-token", decimals: 18, price: 0.00212146}, // Addr: 0xa3a80559bbc1989654e6b8385f5001fa1333332f, Notional: 0.015112128620498799 {chain: 2, addr: "000000000000000000000000a406844323f1603701e6ad95adc8a082213a68ce", symbol: "PBT", coinGeckoId: "polybet", decimals: 18, price: 0.00086603}, // Addr: 0xa406844323f1603701e6ad95adc8a082213a68ce, Notional: 12.028194367464 - {chain: 2, addr: "000000000000000000000000a462bde22d98335e18a21555b6752db93a937cff", symbol: "BOBBY", coinGeckoId: "independence-token", decimals: 18, price: 0.00000347}, // Addr: 0xa462bde22d98335e18a21555b6752db93a937cff, Notional: 16089.673465026057 - {chain: 2, addr: "000000000000000000000000a47c8bf37f92abed4a126bda807a7b7498661acd", symbol: "UST", coinGeckoId: "wrapped-ust", decimals: 18, price: 0.02485643}, // Addr: 0xa47c8bf37f92abed4a126bda807a7b7498661acd, Notional: 8.531354064550003 - {chain: 2, addr: "000000000000000000000000a5ef74068d04ba0809b7379dd76af5ce34ab7c57", symbol: "LUCHOW", coinGeckoId: "lunachow", decimals: 18, price: 3.2925e-7}, // Addr: 0xa5ef74068d04ba0809b7379dd76af5ce34ab7c57, Notional: 503.5868714972409 - {chain: 2, addr: "000000000000000000000000a9e8acf069c58aec8825542845fd754e41a9489a", symbol: "pepecoin", coinGeckoId: "pepecoin-2", decimals: 18, price: 3.5}, // Addr: 0xa9e8acf069c58aec8825542845fd754e41a9489a, Notional: 261679.37360733002 - {chain: 2, addr: "000000000000000000000000aa2ce7ae64066175e0b90497ce7d9c190c315db4", symbol: "Suter", coinGeckoId: "suterusu", decimals: 18, price: 0.00004452}, // Addr: 0xaa2ce7ae64066175e0b90497ce7d9c190c315db4, Notional: 3.62534411442 - {chain: 2, addr: "000000000000000000000000aa7a9ca87d3694b5755f213b5d04094b8d0f0a6f", symbol: "TRAC", coinGeckoId: "origintrail", decimals: 18, price: 0.948725}, // Addr: 0xaa7a9ca87d3694b5755f213b5d04094b8d0f0a6f, Notional: 79272.86710640378 - {chain: 2, addr: "000000000000000000000000aaaebe6fe48e54f431b0c390cfaf0b017d09d42d", symbol: "CEL", coinGeckoId: "celsius-degree-token", decimals: 4, price: 0.234894}, // Addr: 0xaaaebe6fe48e54f431b0c390cfaf0b017d09d42d, Notional: 7395.2158613124 - {chain: 2, addr: "000000000000000000000000aaee1a9723aadb7afa2810263653a34ba2c21c7a", symbol: "Mog", coinGeckoId: "mog-coin", decimals: 18, price: 0.0000022}, // Addr: 0xaaee1a9723aadb7afa2810263653a34ba2c21c7a, Notional: 1897.9091080744845 - {chain: 2, addr: "000000000000000000000000ab2a7b5876d707e0126b3a75ef7781c77c8877ee", symbol: "QUAD", coinGeckoId: "quadency", decimals: 18, price: 0.00552266}, // Addr: 0xab2a7b5876d707e0126b3a75ef7781c77c8877ee, Notional: 8692.789399387919 - {chain: 2, addr: "000000000000000000000000ac51066d7bec65dc4589368da368b212745d63e8", symbol: "ALICE", coinGeckoId: "my-neighbor-alice", decimals: 6, price: 1.48}, // Addr: 0xac51066d7bec65dc4589368da368b212745d63e8, Notional: 2.96 - {chain: 2, addr: "000000000000000000000000ac57de9c1a09fec648e93eb98875b212db0d460b", symbol: "BabyDoge", coinGeckoId: "baby-doge-coin", decimals: 9, price: 2.327e-9}, // Addr: 0xac57de9c1a09fec648e93eb98875b212db0d460b, Notional: 355.6878476313836 - {chain: 2, addr: "000000000000000000000000ac6db8954b73ebf10e84278ac8b9b22a781615d9", symbol: "BWB", coinGeckoId: "bitget-wallet-token", decimals: 18, price: 0.28596}, // Addr: 0xac6db8954b73ebf10e84278ac8b9b22a781615d9, Notional: 27144950.374543335 - {chain: 2, addr: "000000000000000000000000ae1eaae3f627aaca434127644371b67b18444051", symbol: "YOP", coinGeckoId: "yield-optimization-platform", decimals: 8, price: 0.00006712}, // Addr: 0xae1eaae3f627aaca434127644371b67b18444051, Notional: 0.005033999999999999 - {chain: 2, addr: "000000000000000000000000ae6e307c3fe9e922e5674dbd7f830ed49c014c6b", symbol: "CREDI", coinGeckoId: "credefi", decimals: 18, price: 0.01816184}, // Addr: 0xae6e307c3fe9e922e5674dbd7f830ed49c014c6b, Notional: 136279.59551906073 - {chain: 2, addr: "000000000000000000000000ae78736cd615f374d3085123a210448e74fc6393", symbol: "rETH", coinGeckoId: "rocket-pool-eth", decimals: 18, price: 4009.78}, // Addr: 0xae78736cd615f374d3085123a210448e74fc6393, Notional: 1403.423 - {chain: 2, addr: "000000000000000000000000ae7ab96520de3a18e5e111b5eaab095312d7fe84", symbol: "stETH", coinGeckoId: "staked-ether", decimals: 18, price: 3593.89}, // Addr: 0xae7ab96520de3a18e5e111b5eaab095312d7fe84, Notional: 8126.3581560659995 - {chain: 2, addr: "000000000000000000000000aee433adebe0fbb88daa47ef0c1a513caa52ef02", symbol: "TOON", coinGeckoId: "pontoon", decimals: 18, price: 0.0000218}, // Addr: 0xaee433adebe0fbb88daa47ef0c1a513caa52ef02, Notional: 0.44453221807283405 - {chain: 2, addr: "000000000000000000000000b0ffa8000886e57f86dd5264b9582b2ad87b2b91", symbol: "W", coinGeckoId: "wormhole", decimals: 18, price: 0.318945}, // Addr: 0xb0ffa8000886e57f86dd5264b9582b2ad87b2b91, Notional: 0.6378966978449999 - {chain: 2, addr: "000000000000000000000000b131f337c45d386ceec234e194b2663d5c3d9dcf", symbol: "ICOM", coinGeckoId: "icommunity", decimals: 18, price: 0.01032648}, // Addr: 0xb131f337c45d386ceec234e194b2663d5c3d9dcf, Notional: 93845.2970989561 - {chain: 2, addr: "000000000000000000000000b19dd661f076998e3b0456935092a233e12c2280", symbol: "UM", coinGeckoId: "continuum-world", decimals: 18, price: 0.00036343}, // Addr: 0xb19dd661f076998e3b0456935092a233e12c2280, Notional: 0.9722983034075386 + {chain: 2, addr: "000000000000000000000000a462bde22d98335e18a21555b6752db93a937cff", symbol: "BOBBY", coinGeckoId: "independence-token", decimals: 18, price: 0.00000264}, // Addr: 0xa462bde22d98335e18a21555b6752db93a937cff, Notional: 12473.333964677773 + {chain: 2, addr: "000000000000000000000000a47c8bf37f92abed4a126bda807a7b7498661acd", symbol: "UST", coinGeckoId: "wrapped-ust", decimals: 18, price: 0.01958015}, // Addr: 0xa47c8bf37f92abed4a126bda807a7b7498661acd, Notional: 6.720401613868072 + {chain: 2, addr: "000000000000000000000000a5ef74068d04ba0809b7379dd76af5ce34ab7c57", symbol: "LUCHOW", coinGeckoId: "lunachow", decimals: 18, price: 3.45527e-7}, // Addr: 0xa5ef74068d04ba0809b7379dd76af5ce34ab7c57, Notional: 528.4824933874781 + {chain: 2, addr: "000000000000000000000000a9e8acf069c58aec8825542845fd754e41a9489a", symbol: "pepecoin", coinGeckoId: "pepecoin-2", decimals: 18, price: 1.87}, // Addr: 0xa9e8acf069c58aec8825542845fd754e41a9489a, Notional: 252803.5679825128 + {chain: 2, addr: "000000000000000000000000aa2ce7ae64066175e0b90497ce7d9c190c315db4", symbol: "Suter", coinGeckoId: "suterusu", decimals: 18, price: 0.00002117}, // Addr: 0xaa2ce7ae64066175e0b90497ce7d9c190c315db4, Notional: 1.723911385945 + {chain: 2, addr: "000000000000000000000000aa7a9ca87d3694b5755f213b5d04094b8d0f0a6f", symbol: "TRAC", coinGeckoId: "origintrail", decimals: 18, price: 0.844197}, // Addr: 0xaa7a9ca87d3694b5755f213b5d04094b8d0f0a6f, Notional: 70538.79321470895 + {chain: 2, addr: "000000000000000000000000aaaebe6fe48e54f431b0c390cfaf0b017d09d42d", symbol: "CEL", coinGeckoId: "celsius-degree-token", decimals: 4, price: 0.193008}, // Addr: 0xaaaebe6fe48e54f431b0c390cfaf0b017d09d42d, Notional: 6076.510353436801 + {chain: 2, addr: "000000000000000000000000aaee1a9723aadb7afa2810263653a34ba2c21c7a", symbol: "Mog", coinGeckoId: "mog-coin", decimals: 18, price: 0.00000202}, // Addr: 0xaaee1a9723aadb7afa2810263653a34ba2c21c7a, Notional: 1742.6256355956632 + {chain: 2, addr: "000000000000000000000000ab2a7b5876d707e0126b3a75ef7781c77c8877ee", symbol: "QUAD", coinGeckoId: "quadency", decimals: 18, price: 0.00372442}, // Addr: 0xab2a7b5876d707e0126b3a75ef7781c77c8877ee, Notional: 7538.836239029705 + {chain: 2, addr: "000000000000000000000000ac51066d7bec65dc4589368da368b212745d63e8", symbol: "ALICE", coinGeckoId: "my-neighbor-alice", decimals: 6, price: 1.1}, // Addr: 0xac51066d7bec65dc4589368da368b212745d63e8, Notional: 2.2 + {chain: 2, addr: "000000000000000000000000ac57de9c1a09fec648e93eb98875b212db0d460b", symbol: "BabyDoge", coinGeckoId: "baby-doge-coin", decimals: 9, price: 3.077e-9}, // Addr: 0xac57de9c1a09fec648e93eb98875b212db0d460b, Notional: 470.34263345800053 + {chain: 2, addr: "000000000000000000000000ac6db8954b73ebf10e84278ac8b9b22a781615d9", symbol: "BWB", coinGeckoId: "bitget-wallet-token", decimals: 18, price: 0.47239}, // Addr: 0xac6db8954b73ebf10e84278ac8b9b22a781615d9, Notional: 44842562.37317527 + {chain: 2, addr: "000000000000000000000000ae1eaae3f627aaca434127644371b67b18444051", symbol: "YOP", coinGeckoId: "yield-optimization-platform", decimals: 8, price: 0.00009227}, // Addr: 0xae1eaae3f627aaca434127644371b67b18444051, Notional: 0.006920249999999999 + {chain: 2, addr: "000000000000000000000000ae6e307c3fe9e922e5674dbd7f830ed49c014c6b", symbol: "CREDI", coinGeckoId: "credefi", decimals: 18, price: 0.01493437}, // Addr: 0xae6e307c3fe9e922e5674dbd7f830ed49c014c6b, Notional: 112061.87825308424 + {chain: 2, addr: "000000000000000000000000ae78736cd615f374d3085123a210448e74fc6393", symbol: "rETH", coinGeckoId: "rocket-pool-eth", decimals: 18, price: 3740.91}, // Addr: 0xae78736cd615f374d3085123a210448e74fc6393, Notional: 1309.3184999999999 + {chain: 2, addr: "000000000000000000000000ae7ab96520de3a18e5e111b5eaab095312d7fe84", symbol: "stETH", coinGeckoId: "staked-ether", decimals: 18, price: 3325.94}, // Addr: 0xae7ab96520de3a18e5e111b5eaab095312d7fe84, Notional: 7520.480494836 + {chain: 2, addr: "000000000000000000000000aee433adebe0fbb88daa47ef0c1a513caa52ef02", symbol: "TOON", coinGeckoId: "pontoon", decimals: 18, price: 0.00002096}, // Addr: 0xaee433adebe0fbb88daa47ef0c1a513caa52ef02, Notional: 0.42740345370672483 + {chain: 2, addr: "000000000000000000000000b0ffa8000886e57f86dd5264b9582b2ad87b2b91", symbol: "W", coinGeckoId: "wormhole", decimals: 18, price: 0.284654}, // Addr: 0xb0ffa8000886e57f86dd5264b9582b2ad87b2b91, Notional: 0.5693139777339999 + {chain: 2, addr: "000000000000000000000000b131f337c45d386ceec234e194b2663d5c3d9dcf", symbol: "ICOM", coinGeckoId: "icommunity", decimals: 18, price: 0.0031347}, // Addr: 0xb131f337c45d386ceec234e194b2663d5c3d9dcf, Notional: 28487.62141756897 + {chain: 2, addr: "000000000000000000000000b19dd661f076998e3b0456935092a233e12c2280", symbol: "UM", coinGeckoId: "continuum-world", decimals: 18, price: 0.00027779}, // Addr: 0xb19dd661f076998e3b0456935092a233e12c2280, Notional: 0.7431823066438658 {chain: 2, addr: "000000000000000000000000b1f66997a5760428d3a87d68b90bfe0ae64121cc", symbol: "LUA", coinGeckoId: "lua-token", decimals: 18, price: 0.03879681}, // Addr: 0xb1f66997a5760428d3a87d68b90bfe0ae64121cc, Notional: 99555.87339204 - {chain: 2, addr: "000000000000000000000000b2617246d0c6c0087f18703d576831899ca94f01", symbol: "ZIG", coinGeckoId: "zignaly", decimals: 18, price: 0.14653}, // Addr: 0xb2617246d0c6c0087f18703d576831899ca94f01, Notional: 159245.6124403271 - {chain: 2, addr: "000000000000000000000000b369daca21ee035312176eb8cf9d88ce97e0aa95", symbol: "SKOL", coinGeckoId: "skol", decimals: 18, price: 0.257771}, // Addr: 0xb369daca21ee035312176eb8cf9d88ce97e0aa95, Notional: 261248.9267589157 - {chain: 2, addr: "000000000000000000000000b50721bcf8d664c30412cfbc6cf7a15145234ad1", symbol: "ARB", coinGeckoId: "arbitrum", decimals: 18, price: 0.915552}, // Addr: 0xb50721bcf8d664c30412cfbc6cf7a15145234ad1, Notional: 246.05155942434146 - {chain: 2, addr: "000000000000000000000000b5ce43fe2fcffffb2eece95ec413d08def28046f", symbol: "PELO", coinGeckoId: "pepelon-token", decimals: 18, price: 3.08011e-10}, // Addr: 0xb5ce43fe2fcffffb2eece95ec413d08def28046f, Notional: 3.0801100000000003 - {chain: 2, addr: "000000000000000000000000b62e24b747eaa41454857cf6011832117df59cb8", symbol: "EPIKO", coinGeckoId: "epiko", decimals: 18, price: 0.00250341}, // Addr: 0xb62e24b747eaa41454857cf6011832117df59cb8, Notional: 48855.16188138179 - {chain: 2, addr: "000000000000000000000000b69753c06bb5c366be51e73bfc0cc2e3dc07e371", symbol: "POOH", coinGeckoId: "pooh", decimals: 18, price: 1.7664e-8}, // Addr: 0xb69753c06bb5c366be51e73bfc0cc2e3dc07e371, Notional: 1810.90180876154 + {chain: 2, addr: "000000000000000000000000b2617246d0c6c0087f18703d576831899ca94f01", symbol: "ZIG", coinGeckoId: "zignaly", decimals: 18, price: 0.112528}, // Addr: 0xb2617246d0c6c0087f18703d576831899ca94f01, Notional: 127919.97068152865 + {chain: 2, addr: "000000000000000000000000b369daca21ee035312176eb8cf9d88ce97e0aa95", symbol: "SKOL", coinGeckoId: "skol", decimals: 18, price: 0.423787}, // Addr: 0xb369daca21ee035312176eb8cf9d88ce97e0aa95, Notional: 469588.69600586273 + {chain: 2, addr: "000000000000000000000000b50721bcf8d664c30412cfbc6cf7a15145234ad1", symbol: "ARB", coinGeckoId: "arbitrum", decimals: 18, price: 0.721497}, // Addr: 0xb50721bcf8d664c30412cfbc6cf7a15145234ad1, Notional: 193.8999226368181 + {chain: 2, addr: "000000000000000000000000b5ce43fe2fcffffb2eece95ec413d08def28046f", symbol: "PELO", coinGeckoId: "pepelon-token", decimals: 18, price: 1.99527e-10}, // Addr: 0xb5ce43fe2fcffffb2eece95ec413d08def28046f, Notional: 1.99527 + {chain: 2, addr: "000000000000000000000000b62e24b747eaa41454857cf6011832117df59cb8", symbol: "EPIKO", coinGeckoId: "epiko", decimals: 18, price: 0.00207316}, // Addr: 0xb62e24b747eaa41454857cf6011832117df59cb8, Notional: 42582.72529590308 + {chain: 2, addr: "000000000000000000000000b69753c06bb5c366be51e73bfc0cc2e3dc07e371", symbol: "POOH", coinGeckoId: "pooh", decimals: 18, price: 1.2798e-8}, // Addr: 0xb69753c06bb5c366be51e73bfc0cc2e3dc07e371, Notional: 1386.134601993318 {chain: 2, addr: "000000000000000000000000b7cfe05915ef0c040c6dde2007c9ddab26259e04", symbol: "MOLLY", coinGeckoId: "molly-gateway", decimals: 18, price: 0.00027056}, // Addr: 0xb7cfe05915ef0c040c6dde2007c9ddab26259e04, Notional: 0.0000680744814816 - {chain: 2, addr: "000000000000000000000000b8c77482e45f1f44de1745f52c74426c631bdd52", symbol: "BNB", coinGeckoId: "binancecoin", decimals: 18, price: 632.81}, // Addr: 0xb8c77482e45f1f44de1745f52c74426c631bdd52, Notional: 18323.4680784387 + {chain: 2, addr: "000000000000000000000000b8c77482e45f1f44de1745f52c74426c631bdd52", symbol: "BNB", coinGeckoId: "binancecoin", decimals: 18, price: 699.31}, // Addr: 0xb8c77482e45f1f44de1745f52c74426c631bdd52, Notional: 20249.023343393696 {chain: 2, addr: "000000000000000000000000b8e2e2101ed11e9138803cd3e06e16dd19910647", symbol: "ARDX", coinGeckoId: "ardcoin", decimals: 2, price: 0.00379947}, // Addr: 0xb8e2e2101ed11e9138803cd3e06e16dd19910647, Notional: 4563.9993534000005 - {chain: 2, addr: "000000000000000000000000b9f599ce614feb2e1bbe58f180f370d05b39344e", symbol: "PORK", coinGeckoId: "pepefork", decimals: 18, price: 1.16461e-7}, // Addr: 0xb9f599ce614feb2e1bbe58f180f370d05b39344e, Notional: 170.16563244189112 - {chain: 2, addr: "000000000000000000000000ba100000625a3754423978a60c9317c58a424e3d", symbol: "BAL", coinGeckoId: "balancer", decimals: 18, price: 2.86}, // Addr: 0xba100000625a3754423978a60c9317c58a424e3d, Notional: 31.448854808799997 - {chain: 2, addr: "000000000000000000000000ba25b2281214300e4e649fead9a6d6acd25f1c0a", symbol: "TREE", coinGeckoId: "tree-capital", decimals: 18, price: 0.262491}, // Addr: 0xba25b2281214300e4e649fead9a6d6acd25f1c0a, Notional: 2220280.0159745514 - {chain: 2, addr: "000000000000000000000000ba386a4ca26b85fd057ab1ef86e3dc7bdeb5ce70", symbol: "JESUS", coinGeckoId: "jesus-coin", decimals: 18, price: 1.18502e-7}, // Addr: 0xba386a4ca26b85fd057ab1ef86e3dc7bdeb5ce70, Notional: 5554.568828919045 - {chain: 2, addr: "000000000000000000000000ba5bde662c17e2adff1075610382b9b691296350", symbol: "RARE", coinGeckoId: "superrare", decimals: 18, price: 0.145051}, // Addr: 0xba5bde662c17e2adff1075610382b9b691296350, Notional: 399.58216768208337 - {chain: 2, addr: "000000000000000000000000baac2b4491727d78d2b78815144570b9f2fe8899", symbol: "DOG", coinGeckoId: "the-doge-nft", decimals: 18, price: 0.00464939}, // Addr: 0xbaac2b4491727d78d2b78815144570b9f2fe8899, Notional: 1754956.7738431627 - {chain: 2, addr: "000000000000000000000000bb0e17ef65f82ab018d8edd776e8dd940327b28b", symbol: "AXS", coinGeckoId: "axie-infinity", decimals: 18, price: 7.74}, // Addr: 0xbb0e17ef65f82ab018d8edd776e8dd940327b28b, Notional: 8862.4878922152 - {chain: 2, addr: "000000000000000000000000bba39fd2935d5769116ce38d46a71bde9cf03099", symbol: "CHO", coinGeckoId: "choise", decimals: 18, price: 0.03323392}, // Addr: 0xbba39fd2935d5769116ce38d46a71bde9cf03099, Notional: 376660.2288084441 - {chain: 2, addr: "000000000000000000000000bc396689893d065f41bc2c6ecbee5e0085233447", symbol: "PERP", coinGeckoId: "perpetual-protocol", decimals: 18, price: 0.920039}, // Addr: 0xbc396689893d065f41bc2c6ecbee5e0085233447, Notional: 16210.415039850312 - {chain: 2, addr: "000000000000000000000000bcca60bb61934080951369a648fb03df4f96263c", symbol: "aUSDC", coinGeckoId: "aave-usdc", decimals: 6, price: 1}, // Addr: 0xbcca60bb61934080951369a648fb03df4f96263c, Notional: 7.008437 + {chain: 2, addr: "000000000000000000000000b9f599ce614feb2e1bbe58f180f370d05b39344e", symbol: "PORK", coinGeckoId: "pepefork", decimals: 18, price: 8.4442e-8}, // Addr: 0xb9f599ce614feb2e1bbe58f180f370d05b39344e, Notional: 124.40927189497972 + {chain: 2, addr: "000000000000000000000000ba100000625a3754423978a60c9317c58a424e3d", symbol: "BAL", coinGeckoId: "balancer", decimals: 18, price: 2.49}, // Addr: 0xba100000625a3754423978a60c9317c58a424e3d, Notional: 27.3802966692 + {chain: 2, addr: "000000000000000000000000ba25b2281214300e4e649fead9a6d6acd25f1c0a", symbol: "TREE", coinGeckoId: "tree-capital", decimals: 18, price: 0.215539}, // Addr: 0xba25b2281214300e4e649fead9a6d6acd25f1c0a, Notional: 1881988.7570121326 + {chain: 2, addr: "000000000000000000000000ba386a4ca26b85fd057ab1ef86e3dc7bdeb5ce70", symbol: "JESUS", coinGeckoId: "jesus-coin", decimals: 18, price: 7.3393e-8}, // Addr: 0xba386a4ca26b85fd057ab1ef86e3dc7bdeb5ce70, Notional: 3440.1653141791317 + {chain: 2, addr: "000000000000000000000000ba5bde662c17e2adff1075610382b9b691296350", symbol: "RARE", coinGeckoId: "superrare", decimals: 18, price: 0.111418}, // Addr: 0xba5bde662c17e2adff1075610382b9b691296350, Notional: 306.9309826116494 + {chain: 2, addr: "000000000000000000000000baac2b4491727d78d2b78815144570b9f2fe8899", symbol: "DOG", coinGeckoId: "the-doge-nft", decimals: 18, price: 0.00399146}, // Addr: 0xbaac2b4491727d78d2b78815144570b9f2fe8899, Notional: 1613233.659671147 + {chain: 2, addr: "000000000000000000000000bb0e17ef65f82ab018d8edd776e8dd940327b28b", symbol: "AXS", coinGeckoId: "axie-infinity", decimals: 18, price: 6.18}, // Addr: 0xbb0e17ef65f82ab018d8edd776e8dd940327b28b, Notional: 7460.5482032016 + {chain: 2, addr: "000000000000000000000000bba39fd2935d5769116ce38d46a71bde9cf03099", symbol: "CHO", coinGeckoId: "choise", decimals: 18, price: 0.02047489}, // Addr: 0xbba39fd2935d5769116ce38d46a71bde9cf03099, Notional: 251303.41104405242 + {chain: 2, addr: "000000000000000000000000bc396689893d065f41bc2c6ecbee5e0085233447", symbol: "PERP", coinGeckoId: "perpetual-protocol", decimals: 18, price: 0.778595}, // Addr: 0xbc396689893d065f41bc2c6ecbee5e0085233447, Notional: 13718.275092634392 + {chain: 2, addr: "000000000000000000000000bcca60bb61934080951369a648fb03df4f96263c", symbol: "aUSDC", coinGeckoId: "aave-usdc", decimals: 6, price: 0.99928}, // Addr: 0xbcca60bb61934080951369a648fb03df4f96263c, Notional: 7.00339092536 {chain: 2, addr: "000000000000000000000000bd2f0cd039e0bfcf88901c98c0bfac5ab27566e3", symbol: "DSD", coinGeckoId: "dynamic-set-dollar", decimals: 18, price: 3.531e-8}, // Addr: 0xbd2f0cd039e0bfcf88901c98c0bfac5ab27566e3, Notional: 13.453689879628266 - {chain: 2, addr: "000000000000000000000000bd6323a83b613f668687014e8a5852079494fb68", symbol: "BTC", coinGeckoId: "blackrocktradingcurrency", decimals: 18, price: 0.02342877}, // Addr: 0xbd6323a83b613f668687014e8a5852079494fb68, Notional: 0.11714384976571231 - {chain: 2, addr: "000000000000000000000000bd8fdda057de7e0162b7a386bec253844b5e07a5", symbol: "JARVIS", coinGeckoId: "jarvis-2", decimals: 18, price: 0.059505}, // Addr: 0xbd8fdda057de7e0162b7a386bec253844b5e07a5, Notional: 1417205.8644227257 + {chain: 2, addr: "000000000000000000000000bd6323a83b613f668687014e8a5852079494fb68", symbol: "BTC", coinGeckoId: "blackrocktradingcurrency", decimals: 18, price: 0.04901075}, // Addr: 0xbd6323a83b613f668687014e8a5852079494fb68, Notional: 0.2450537495098925 + {chain: 2, addr: "000000000000000000000000bd8fdda057de7e0162b7a386bec253844b5e07a5", symbol: "JARVIS", coinGeckoId: "jarvis-2", decimals: 18, price: 0.058978}, // Addr: 0xbd8fdda057de7e0162b7a386bec253844b5e07a5, Notional: 1351454.7874069777 {chain: 2, addr: "000000000000000000000000be33f57f41a20b2f00dec91dcc1169597f36221f", symbol: "RUG", coinGeckoId: "rug-rugged-art", decimals: 18, price: 9.68}, // Addr: 0xbe33f57f41a20b2f00dec91dcc1169597f36221f, Notional: 25670.7855885096 - {chain: 2, addr: "000000000000000000000000bededdf2ef49e87037c4fb2ca34d1ff3d3992a11", symbol: "FEG", coinGeckoId: "feg-token-2", decimals: 18, price: 0.00036373}, // Addr: 0xbededdf2ef49e87037c4fb2ca34d1ff3d3992a11, Notional: 79.44573654049005 - {chain: 2, addr: "000000000000000000000000beef01060047522408756e0000a90ce195a70000", symbol: "APTR", coinGeckoId: "aperture-finance", decimals: 6, price: 0.01055903}, // Addr: 0xbeef01060047522408756e0000a90ce195a70000, Notional: 2669405.4478613907 - {chain: 2, addr: "000000000000000000000000c00e94cb662c3520282e6f5717214004a7f26888", symbol: "COMP", coinGeckoId: "compound-governance-token", decimals: 18, price: 75.42}, // Addr: 0xc00e94cb662c3520282e6f5717214004a7f26888, Notional: 375806.0890369386 - {chain: 2, addr: "000000000000000000000000c011a73ee8576fb46f5e1c5751ca3b9fe0af2a6f", symbol: "SNX", coinGeckoId: "havven", decimals: 18, price: 2.45}, // Addr: 0xc011a73ee8576fb46f5e1c5751ca3b9fe0af2a6f, Notional: 300.25831417750004 - {chain: 2, addr: "000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2", symbol: "WETH", coinGeckoId: "weth", decimals: 18, price: 3594.89}, // Addr: 0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2, Notional: 301028138.0855552 - {chain: 2, addr: "000000000000000000000000c0a4df35568f116c370e6a6a6022ceb908eeddac", symbol: "UMEE", coinGeckoId: "umee", decimals: 6, price: 0.00147932}, // Addr: 0xc0a4df35568f116c370e6a6a6022ceb908eeddac, Notional: 1.47932 - {chain: 2, addr: "000000000000000000000000c18360217d8f7ab5e7c516566761ea12ce7f9d72", symbol: "ENS", coinGeckoId: "ethereum-name-service", decimals: 18, price: 41.34}, // Addr: 0xc18360217d8f7ab5e7c516566761ea12ce7f9d72, Notional: 1005.4588014354001 - {chain: 2, addr: "000000000000000000000000c28eb2250d1ae32c7e74cfb6d6b86afc9beb6509", symbol: "OPN", coinGeckoId: "open-ticketing-ecosystem", decimals: 18, price: 0.0014495}, // Addr: 0xc28eb2250d1ae32c7e74cfb6d6b86afc9beb6509, Notional: 799299.2740642416 - {chain: 2, addr: "000000000000000000000000c4170fd71eced3c80badca77f4e12e8aac1e3436", symbol: "KMON", coinGeckoId: "kryptomon", decimals: 18, price: 0.00090534}, // Addr: 0xc4170fd71eced3c80badca77f4e12e8aac1e3436, Notional: 144235.71465028034 - {chain: 2, addr: "000000000000000000000000c477d038d5420c6a9e0b031712f61c5120090de9", symbol: "BOSON", coinGeckoId: "boson-protocol", decimals: 18, price: 0.349845}, // Addr: 0xc477d038d5420c6a9e0b031712f61c5120090de9, Notional: 346.57600438296646 - {chain: 2, addr: "000000000000000000000000c4c2614e694cf534d407ee49f8e44d125e4681c4", symbol: "CHAIN", coinGeckoId: "chain-games", decimals: 18, price: 0.03065139}, // Addr: 0xc4c2614e694cf534d407ee49f8e44d125e4681c4, Notional: 132.6342020608521 - {chain: 2, addr: "000000000000000000000000c5102fe9359fd9a28f877a67e36b0f050d81a3cc", symbol: "HOP", coinGeckoId: "hop-protocol", decimals: 18, price: 0.01973637}, // Addr: 0xc5102fe9359fd9a28f877a67e36b0f050d81a3cc, Notional: 0.5920911 - {chain: 2, addr: "000000000000000000000000c5ba042bf8832999b17c9036e8212f49dce0501a", symbol: "YOURAI", coinGeckoId: "your-ai", decimals: 18, price: 0.01193018}, // Addr: 0xc5ba042bf8832999b17c9036e8212f49dce0501a, Notional: 1186069.417475634 - {chain: 2, addr: "000000000000000000000000c6c9448a86882d73164a984fa52285ab51c823bc", symbol: "RPILL", coinGeckoId: "red-pill-2", decimals: 18, price: 9.35549e-7}, // Addr: 0xc6c9448a86882d73164a984fa52285ab51c823bc, Notional: 6287.309068107678 - {chain: 2, addr: "000000000000000000000000c8168d5665f4418353728ac970713e09c0b7c20e", symbol: "MONKE", coinGeckoId: "monke-coin", decimals: 18, price: 5.1058e-8}, // Addr: 0xc8168d5665f4418353728ac970713e09c0b7c20e, Notional: 5167.012774158788 - {chain: 2, addr: "000000000000000000000000c86d054809623432210c107af2e3f619dcfbf652", symbol: "UPP", coinGeckoId: "sentinel-protocol", decimals: 18, price: 0.084246}, // Addr: 0xc86d054809623432210c107af2e3f619dcfbf652, Notional: 0.84246 - {chain: 2, addr: "000000000000000000000000c944e90c64b2c07662a292be6244bdf05cda44a7", symbol: "GRT", coinGeckoId: "the-graph", decimals: 18, price: 0.272962}, // Addr: 0xc944e90c64b2c07662a292be6244bdf05cda44a7, Notional: 642.878465446886 - {chain: 2, addr: "000000000000000000000000c97d6c52f3add91fa1c5287a453d7444aecbca83", symbol: "DZOO", coinGeckoId: "degen-zoo", decimals: 18, price: 0.00444105}, // Addr: 0xc97d6c52f3add91fa1c5287a453d7444aecbca83, Notional: 1304.066645532848 - {chain: 2, addr: "000000000000000000000000caabcaa4ca42e1d86de1a201c818639def0ba7a7", symbol: "TALK", coinGeckoId: "talken", decimals: 18, price: 0.03226545}, // Addr: 0xcaabcaa4ca42e1d86de1a201c818639def0ba7a7, Notional: 32789.04526804187 - {chain: 2, addr: "000000000000000000000000cafe001067cdef266afb7eb5a286dcfd277f3de5", symbol: "PSP", coinGeckoId: "paraswap", decimals: 18, price: 0.02058788}, // Addr: 0xcafe001067cdef266afb7eb5a286dcfd277f3de5, Notional: 0.0186089425043376 - {chain: 2, addr: "000000000000000000000000cb84d72e61e383767c4dfeb2d8ff7f4fb89abc6e", symbol: "VEGA", coinGeckoId: "vega-protocol", decimals: 18, price: 0.01352286}, // Addr: 0xcb84d72e61e383767c4dfeb2d8ff7f4fb89abc6e, Notional: 0.39216293999999996 - {chain: 2, addr: "000000000000000000000000cb8fb2438a805664cd8c3e640b85ac473da5be87", symbol: "CTI", coinGeckoId: "clintex-cti", decimals: 18, price: 0.02058715}, // Addr: 0xcb8fb2438a805664cd8c3e640b85ac473da5be87, Notional: 217081.38120283623 - {chain: 2, addr: "000000000000000000000000cbd55d4ffc43467142761a764763652b48b969ff", symbol: "ASTRO", coinGeckoId: "astrotools", decimals: 18, price: 0.078474}, // Addr: 0xcbd55d4ffc43467142761a764763652b48b969ff, Notional: 11.78990043837012 + {chain: 2, addr: "000000000000000000000000bededdf2ef49e87037c4fb2ca34d1ff3d3992a11", symbol: "FEG", coinGeckoId: "feg-token-2", decimals: 18, price: 0.00014948}, // Addr: 0xbededdf2ef49e87037c4fb2ca34d1ff3d3992a11, Notional: 32.6493517116335 + {chain: 2, addr: "000000000000000000000000beef01060047522408756e0000a90ce195a70000", symbol: "APTR", coinGeckoId: "aperture-finance", decimals: 6, price: 0.00713039}, // Addr: 0xbeef01060047522408756e0000a90ce195a70000, Notional: 2016530.1139429833 + {chain: 2, addr: "000000000000000000000000c00e94cb662c3520282e6f5717214004a7f26888", symbol: "COMP", coinGeckoId: "compound-governance-token", decimals: 18, price: 72.9}, // Addr: 0xc00e94cb662c3520282e6f5717214004a7f26888, Notional: 363249.32233880705 + {chain: 2, addr: "000000000000000000000000c011a73ee8576fb46f5e1c5751ca3b9fe0af2a6f", symbol: "SNX", coinGeckoId: "havven", decimals: 18, price: 1.9}, // Addr: 0xc011a73ee8576fb46f5e1c5751ca3b9fe0af2a6f, Notional: 232.85338650499997 + {chain: 2, addr: "000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2", symbol: "WETH", coinGeckoId: "weth", decimals: 18, price: 3332.06}, // Addr: 0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2, Notional: 315917716.4886076 + {chain: 2, addr: "000000000000000000000000c0a4df35568f116c370e6a6a6022ceb908eeddac", symbol: "UMEE", coinGeckoId: "umee", decimals: 6, price: 0.00067391}, // Addr: 0xc0a4df35568f116c370e6a6a6022ceb908eeddac, Notional: 0.67391 + {chain: 2, addr: "000000000000000000000000c18360217d8f7ab5e7c516566761ea12ce7f9d72", symbol: "ENS", coinGeckoId: "ethereum-name-service", decimals: 18, price: 32.97}, // Addr: 0xc18360217d8f7ab5e7c516566761ea12ce7f9d72, Notional: 801.8862284307 + {chain: 2, addr: "000000000000000000000000c28eb2250d1ae32c7e74cfb6d6b86afc9beb6509", symbol: "OPN", coinGeckoId: "open-ticketing-ecosystem", decimals: 18, price: 0.00071188}, // Addr: 0xc28eb2250d1ae32c7e74cfb6d6b86afc9beb6509, Notional: 391645.2359656218 + {chain: 2, addr: "000000000000000000000000c4170fd71eced3c80badca77f4e12e8aac1e3436", symbol: "KMON", coinGeckoId: "kryptomon", decimals: 18, price: 0.00105321}, // Addr: 0xc4170fd71eced3c80badca77f4e12e8aac1e3436, Notional: 159593.9239017623 + {chain: 2, addr: "000000000000000000000000c477d038d5420c6a9e0b031712f61c5120090de9", symbol: "BOSON", coinGeckoId: "boson-protocol", decimals: 18, price: 0.280829}, // Addr: 0xc477d038d5420c6a9e0b031712f61c5120090de9, Notional: 278.2048985546859 + {chain: 2, addr: "000000000000000000000000c4c2614e694cf534d407ee49f8e44d125e4681c4", symbol: "CHAIN", coinGeckoId: "chain-games", decimals: 18, price: 0.01618985}, // Addr: 0xc4c2614e694cf534d407ee49f8e44d125e4681c4, Notional: 70.05645865439988 + {chain: 2, addr: "000000000000000000000000c5102fe9359fd9a28f877a67e36b0f050d81a3cc", symbol: "HOP", coinGeckoId: "hop-protocol", decimals: 18, price: 0.01492362}, // Addr: 0xc5102fe9359fd9a28f877a67e36b0f050d81a3cc, Notional: 0.4477086 + {chain: 2, addr: "000000000000000000000000c5ba042bf8832999b17c9036e8212f49dce0501a", symbol: "YOURAI", coinGeckoId: "your-ai", decimals: 18, price: 0.0076004}, // Addr: 0xc5ba042bf8832999b17c9036e8212f49dce0501a, Notional: 739094.5732593215 + {chain: 2, addr: "000000000000000000000000c6c9448a86882d73164a984fa52285ab51c823bc", symbol: "RPILL", coinGeckoId: "red-pill-2", decimals: 18, price: 0.00000137}, // Addr: 0xc6c9448a86882d73164a984fa52285ab51c823bc, Notional: 9207.014729648068 + {chain: 2, addr: "000000000000000000000000c8168d5665f4418353728ac970713e09c0b7c20e", symbol: "MONKE", coinGeckoId: "monke-coin", decimals: 18, price: 3.7714e-8}, // Addr: 0xc8168d5665f4418353728ac970713e09c0b7c20e, Notional: 4010.2389221128888 + {chain: 2, addr: "000000000000000000000000c86d054809623432210c107af2e3f619dcfbf652", symbol: "UPP", coinGeckoId: "sentinel-protocol", decimals: 18, price: 0.061684}, // Addr: 0xc86d054809623432210c107af2e3f619dcfbf652, Notional: 0.61684 + {chain: 2, addr: "000000000000000000000000c944e90c64b2c07662a292be6244bdf05cda44a7", symbol: "GRT", coinGeckoId: "the-graph", decimals: 18, price: 0.199064}, // Addr: 0xc944e90c64b2c07662a292be6244bdf05cda44a7, Notional: 468.834339013192 + {chain: 2, addr: "000000000000000000000000c97d6c52f3add91fa1c5287a453d7444aecbca83", symbol: "DZOO", coinGeckoId: "degen-zoo", decimals: 18, price: 0.002038}, // Addr: 0xc97d6c52f3add91fa1c5287a453d7444aecbca83, Notional: 598.436816427634 + {chain: 2, addr: "000000000000000000000000caabcaa4ca42e1d86de1a201c818639def0ba7a7", symbol: "TALK", coinGeckoId: "talken", decimals: 18, price: 0.02134574}, // Addr: 0xcaabcaa4ca42e1d86de1a201c818639def0ba7a7, Notional: 21487.403948553783 + {chain: 2, addr: "000000000000000000000000cafe001067cdef266afb7eb5a286dcfd277f3de5", symbol: "PSP", coinGeckoId: "paraswap", decimals: 18, price: 0.02347798}, // Addr: 0xcafe001067cdef266afb7eb5a286dcfd277f3de5, Notional: 0.0212212418149896 + {chain: 2, addr: "000000000000000000000000cb84d72e61e383767c4dfeb2d8ff7f4fb89abc6e", symbol: "VEGA", coinGeckoId: "vega-protocol", decimals: 18, price: 0.01987589}, // Addr: 0xcb84d72e61e383767c4dfeb2d8ff7f4fb89abc6e, Notional: 0.57640081 + {chain: 2, addr: "000000000000000000000000cb8fb2438a805664cd8c3e640b85ac473da5be87", symbol: "CTI", coinGeckoId: "clintex-cti", decimals: 18, price: 0.01949918}, // Addr: 0xcb8fb2438a805664cd8c3e640b85ac473da5be87, Notional: 209974.08378582695 + {chain: 2, addr: "000000000000000000000000cbd55d4ffc43467142761a764763652b48b969ff", symbol: "ASTRO", coinGeckoId: "astrotools", decimals: 18, price: 0.06719}, // Addr: 0xcbd55d4ffc43467142761a764763652b48b969ff, Notional: 10.0945970697822 {chain: 2, addr: "000000000000000000000000cc503242b574bc01145da7e2a743b43fb395ec91", symbol: "ROVI", coinGeckoId: "rovi-protocol", decimals: 18, price: 0.02260218}, // Addr: 0xcc503242b574bc01145da7e2a743b43fb395ec91, Notional: 3.4127031582000003 - {chain: 2, addr: "000000000000000000000000cc8fa225d80b9c7d42f96e9570156c65d6caaa25", symbol: "SLP", coinGeckoId: "smooth-love-potion", decimals: 0, price: 0.0039712}, // Addr: 0xcc8fa225d80b9c7d42f96e9570156c65d6caaa25, Notional: 7983.5058912 - {chain: 2, addr: "000000000000000000000000ccdb064a41afcd432bcea6f6d0d1e7c371d0b002", symbol: "QR", coinGeckoId: "qrolli", decimals: 9, price: 0.00015793}, // Addr: 0xccdb064a41afcd432bcea6f6d0d1e7c371d0b002, Notional: 0.00031586 - {chain: 2, addr: "000000000000000000000000cd1faff6e578fa5cac469d2418c95671ba1a62fe", symbol: "XTM", coinGeckoId: "torum", decimals: 18, price: 0.01534214}, // Addr: 0xcd1faff6e578fa5cac469d2418c95671ba1a62fe, Notional: 0.767107 - {chain: 2, addr: "000000000000000000000000cd5fe23c85820f7b72d0926fc9b05b43e359b7ee", symbol: "weETH", coinGeckoId: "wrapped-eeth", decimals: 18, price: 3782.81}, // Addr: 0xcd5fe23c85820f7b72d0926fc9b05b43e359b7ee, Notional: 27228.75716744 - {chain: 2, addr: "000000000000000000000000cdf7028ceab81fa0c6971208e83fa7872994bee5", symbol: "T", coinGeckoId: "threshold-network-token", decimals: 18, price: 0.03165473}, // Addr: 0xcdf7028ceab81fa0c6971208e83fa7872994bee5, Notional: 3347.566777870688 - {chain: 2, addr: "000000000000000000000000ce246eea10988c495b4a90a905ee9237a0f91543", symbol: "VCX", coinGeckoId: "vaultcraft", decimals: 18, price: 0.03852542}, // Addr: 0xce246eea10988c495b4a90a905ee9237a0f91543, Notional: 3.8525419999999997 - {chain: 2, addr: "000000000000000000000000cf0c122c6b73ff809c693db761e7baebe62b6a2e", symbol: "FLOKI", coinGeckoId: "floki", decimals: 9, price: 0.00022274}, // Addr: 0xcf0c122c6b73ff809c693db761e7baebe62b6a2e, Notional: 34256.81240338265 - {chain: 2, addr: "000000000000000000000000cfa0885131f602d11d4da248d2c65a62063567a9", symbol: "TORG", coinGeckoId: "torg", decimals: 18, price: 2.7513e-8}, // Addr: 0xcfa0885131f602d11d4da248d2c65a62063567a9, Notional: 1.100522613735 - {chain: 2, addr: "000000000000000000000000cfd16933cb1579eee9fe6031686534e87353b148", symbol: "AIMR", coinGeckoId: "meromai", decimals: 18, price: 0.00150137}, // Addr: 0xcfd16933cb1579eee9fe6031686534e87353b148, Notional: 81223.0943401824 - {chain: 2, addr: "000000000000000000000000d084b83c305dafd76ae3e1b4e1f1fe2ecccb3988", symbol: "TVK", coinGeckoId: "the-virtua-kolect", decimals: 18, price: 0.141203}, // Addr: 0xd084b83c305dafd76ae3e1b4e1f1fe2ecccb3988, Notional: 0.7114510740428699 - {chain: 2, addr: "000000000000000000000000d0d56273290d339aaf1417d9bfa1bb8cfe8a0933", symbol: "FOOM", coinGeckoId: "foom", decimals: 18, price: 6.0647e-8}, // Addr: 0xd0d56273290d339aaf1417d9bfa1bb8cfe8a0933, Notional: 7701.045685880053 - {chain: 2, addr: "000000000000000000000000d13cfd3133239a3c73a9e535a5c4dadee36b395c", symbol: "VAI", coinGeckoId: "vaiot", decimals: 18, price: 0.10873}, // Addr: 0xd13cfd3133239a3c73a9e535a5c4dadee36b395c, Notional: 57.300709999999995 - {chain: 2, addr: "000000000000000000000000d1ba9bac957322d6e8c07a160a3a8da11a0d2867", symbol: "HMT", coinGeckoId: "human-protocol", decimals: 18, price: 0.076483}, // Addr: 0xd1ba9bac957322d6e8c07a160a3a8da11a0d2867, Notional: 91.856083 - {chain: 2, addr: "000000000000000000000000d2877702675e6ceb975b4a1dff9fb7baf4c91ea9", symbol: "LUNA", coinGeckoId: "wrapped-terra", decimals: 18, price: 0.00004969}, // Addr: 0xd2877702675e6ceb975b4a1dff9fb7baf4c91ea9, Notional: 1.448867892052465 - {chain: 2, addr: "000000000000000000000000d2be3722b17b616c51ed9b8944a227d1ce579c24", symbol: "DTUBE", coinGeckoId: "dtube-coin", decimals: 2, price: 0.02909918}, // Addr: 0xd2be3722b17b616c51ed9b8944a227d1ce579c24, Notional: 0.02909918 - {chain: 2, addr: "000000000000000000000000d373576a9e738f37dc6882328358ff69c4caf4c6", symbol: "ZAM", coinGeckoId: "zam-io", decimals: 18, price: 0.00027013}, // Addr: 0xd373576a9e738f37dc6882328358ff69c4caf4c6, Notional: 0.0027013 + {chain: 2, addr: "000000000000000000000000cc8fa225d80b9c7d42f96e9570156c65d6caaa25", symbol: "SLP", coinGeckoId: "smooth-love-potion", decimals: 0, price: 0.0037835}, // Addr: 0xcc8fa225d80b9c7d42f96e9570156c65d6caaa25, Notional: 7606.1630085 + {chain: 2, addr: "000000000000000000000000ccdb064a41afcd432bcea6f6d0d1e7c371d0b002", symbol: "QR", coinGeckoId: "qrolli", decimals: 9, price: 0.0002139}, // Addr: 0xccdb064a41afcd432bcea6f6d0d1e7c371d0b002, Notional: 0.0004278 + {chain: 2, addr: "000000000000000000000000cd1faff6e578fa5cac469d2418c95671ba1a62fe", symbol: "XTM", coinGeckoId: "torum", decimals: 18, price: 0.01447987}, // Addr: 0xcd1faff6e578fa5cac469d2418c95671ba1a62fe, Notional: 0.7239935000000001 + {chain: 2, addr: "000000000000000000000000cd5fe23c85820f7b72d0926fc9b05b43e359b7ee", symbol: "weETH", coinGeckoId: "wrapped-eeth", decimals: 18, price: 3512.35}, // Addr: 0xcd5fe23c85820f7b72d0926fc9b05b43e359b7ee, Notional: 25281.9795964 + {chain: 2, addr: "000000000000000000000000cdf7028ceab81fa0c6971208e83fa7872994bee5", symbol: "T", coinGeckoId: "threshold-network-token", decimals: 18, price: 0.02675673}, // Addr: 0xcdf7028ceab81fa0c6971208e83fa7872994bee5, Notional: 2829.5910416059774 + {chain: 2, addr: "000000000000000000000000ce246eea10988c495b4a90a905ee9237a0f91543", symbol: "VCX", coinGeckoId: "vaultcraft", decimals: 18, price: 0.01686005}, // Addr: 0xce246eea10988c495b4a90a905ee9237a0f91543, Notional: 1.6860050000000002 + {chain: 2, addr: "000000000000000000000000cf0c122c6b73ff809c693db761e7baebe62b6a2e", symbol: "FLOKI", coinGeckoId: "floki", decimals: 9, price: 0.00017721}, // Addr: 0xcf0c122c6b73ff809c693db761e7baebe62b6a2e, Notional: 27254.420966164318 + {chain: 2, addr: "000000000000000000000000cfa0885131f602d11d4da248d2c65a62063567a9", symbol: "TORG", coinGeckoId: "torg", decimals: 18, price: 5.3253e-8}, // Addr: 0xcfa0885131f602d11d4da248d2c65a62063567a9, Notional: 2.130125059035 + {chain: 2, addr: "000000000000000000000000cfd16933cb1579eee9fe6031686534e87353b148", symbol: "AIMR", coinGeckoId: "meromai", decimals: 18, price: 0.00134176}, // Addr: 0xcfd16933cb1579eee9fe6031686534e87353b148, Notional: 72588.30205870848 + {chain: 2, addr: "000000000000000000000000d084b83c305dafd76ae3e1b4e1f1fe2ecccb3988", symbol: "TVK", coinGeckoId: "the-virtua-kolect", decimals: 18, price: 0.105716}, // Addr: 0xd084b83c305dafd76ae3e1b4e1f1fe2ecccb3988, Notional: 0.5326498852256399 + {chain: 2, addr: "000000000000000000000000d0d56273290d339aaf1417d9bfa1bb8cfe8a0933", symbol: "FOOM", coinGeckoId: "foom", decimals: 18, price: 9.2826e-8}, // Addr: 0xd0d56273290d339aaf1417d9bfa1bb8cfe8a0933, Notional: 8076.103098133027 + {chain: 2, addr: "000000000000000000000000d13cfd3133239a3c73a9e535a5c4dadee36b395c", symbol: "VAI", coinGeckoId: "vaiot", decimals: 18, price: 0.070032}, // Addr: 0xd13cfd3133239a3c73a9e535a5c4dadee36b395c, Notional: 36.906864 + {chain: 2, addr: "000000000000000000000000d1ba9bac957322d6e8c07a160a3a8da11a0d2867", symbol: "HMT", coinGeckoId: "human-protocol", decimals: 18, price: 0.04814007}, // Addr: 0xd1ba9bac957322d6e8c07a160a3a8da11a0d2867, Notional: 57.81622407 + {chain: 2, addr: "000000000000000000000000d2877702675e6ceb975b4a1dff9fb7baf4c91ea9", symbol: "LUNA", coinGeckoId: "wrapped-terra", decimals: 18, price: 0.00004537}, // Addr: 0xd2877702675e6ceb975b4a1dff9fb7baf4c91ea9, Notional: 1.322904734602945 + {chain: 2, addr: "000000000000000000000000d2be3722b17b616c51ed9b8944a227d1ce579c24", symbol: "DTUBE", coinGeckoId: "dtube-coin", decimals: 2, price: 0.03219714}, // Addr: 0xd2be3722b17b616c51ed9b8944a227d1ce579c24, Notional: 0.03219714 + {chain: 2, addr: "000000000000000000000000d373576a9e738f37dc6882328358ff69c4caf4c6", symbol: "ZAM", coinGeckoId: "zam-io", decimals: 18, price: 0.0002279}, // Addr: 0xd373576a9e738f37dc6882328358ff69c4caf4c6, Notional: 0.002279 {chain: 2, addr: "000000000000000000000000d38e031f4529a07996aab977d2b79f0e00656c56", symbol: "wTBT", coinGeckoId: "wtbt", decimals: 18, price: 1.18}, // Addr: 0xd38e031f4529a07996aab977d2b79f0e00656c56, Notional: 475.495094923 - {chain: 2, addr: "000000000000000000000000d3e4ba569045546d09cf021ecc5dfe42b1d7f6e4", symbol: "MNW", coinGeckoId: "morpheus-network", decimals: 18, price: 0.494743}, // Addr: 0xd3e4ba569045546d09cf021ecc5dfe42b1d7f6e4, Notional: 14.84229 - {chain: 2, addr: "000000000000000000000000d3fb8597d260efb2e693efd500d62a330a00f1eb", symbol: "TRUMP INU", coinGeckoId: "t-inu", decimals: 18, price: 0.00000105}, // Addr: 0xd3fb8597d260efb2e693efd500d62a330a00f1eb, Notional: 2049.2218080620232 - {chain: 2, addr: "000000000000000000000000d417144312dbf50465b1c641d016962017ef6240", symbol: "CQT", coinGeckoId: "covalent", decimals: 18, price: 0.00677551}, // Addr: 0xd417144312dbf50465b1c641d016962017ef6240, Notional: 38916.66443819302 - {chain: 2, addr: "000000000000000000000000d46ba6d942050d489dbd938a2c909a5d5039a161", symbol: "AMPL", coinGeckoId: "ampleforth", decimals: 9, price: 1.3}, // Addr: 0xd46ba6d942050d489dbd938a2c909a5d5039a161, Notional: 12.943962460000002 - {chain: 2, addr: "000000000000000000000000d49efa7bc0d339d74f487959c573d518ba3f8437", symbol: "COLI", coinGeckoId: "shield-finance", decimals: 18, price: 0.00070398}, // Addr: 0xd49efa7bc0d339d74f487959c573d518ba3f8437, Notional: 121484.11674245117 - {chain: 2, addr: "000000000000000000000000d4c435f5b09f855c3317c8524cb1f586e42795fa", symbol: "CND", coinGeckoId: "cindicator", decimals: 18, price: 0.00038293}, // Addr: 0xd4c435f5b09f855c3317c8524cb1f586e42795fa, Notional: 0.00153172 - {chain: 2, addr: "000000000000000000000000d533a949740bb3306d119cc777fa900ba034cd52", symbol: "CRV", coinGeckoId: "curve-dao-token", decimals: 18, price: 0.716043}, // Addr: 0xd533a949740bb3306d119cc777fa900ba034cd52, Notional: 27296.85448483018 - {chain: 2, addr: "000000000000000000000000d69f306549e9d96f183b1aeca30b8f4353c2ecc3", symbol: "MCHC", coinGeckoId: "mch-coin", decimals: 18, price: 0.057176}, // Addr: 0xd69f306549e9d96f183b1aeca30b8f4353c2ecc3, Notional: 480.4989749147207 - {chain: 2, addr: "000000000000000000000000d6c7bb8531295e88d364ea67d5d1acc7d3f87454", symbol: "FTR", coinGeckoId: "fautor", decimals: 18, price: 0.0114964}, // Addr: 0xd6c7bb8531295e88d364ea67d5d1acc7d3f87454, Notional: 0.0114964 - {chain: 2, addr: "000000000000000000000000d7c302fc3ac829c7e896a32c4bd126f3e8bd0a1f", symbol: "B2M", coinGeckoId: "bit2me", decimals: 18, price: 0.01672051}, // Addr: 0xd7c302fc3ac829c7e896a32c4bd126f3e8bd0a1f, Notional: 0.0087874829246763 - {chain: 2, addr: "000000000000000000000000d7dcd9b99787c619b4d57979521258d1a7267ad7", symbol: "EVRY", coinGeckoId: "evrynet", decimals: 18, price: 0.01942959}, // Addr: 0xd7dcd9b99787c619b4d57979521258d1a7267ad7, Notional: 2.48698752 - {chain: 2, addr: "000000000000000000000000d96e84ddbc7cbe1d73c55b6fe8c64f3a6550deea", symbol: "GMAC", coinGeckoId: "gemach", decimals: 18, price: 0.00223046}, // Addr: 0xd96e84ddbc7cbe1d73c55b6fe8c64f3a6550deea, Notional: 66976.89629026027 - {chain: 2, addr: "000000000000000000000000d979c468a68062e7bdff4ba6df7842dfd3492e0f", symbol: "BBL", coinGeckoId: "beoble", decimals: 18, price: 0.0063969}, // Addr: 0xd979c468a68062e7bdff4ba6df7842dfd3492e0f, Notional: 40031.99941984019 - {chain: 2, addr: "000000000000000000000000d9c2d319cd7e6177336b0a9c93c21cb48d84fb54", symbol: "HAPI", coinGeckoId: "hapi", decimals: 18, price: 12.88}, // Addr: 0xd9c2d319cd7e6177336b0a9c93c21cb48d84fb54, Notional: 12.88 - {chain: 2, addr: "000000000000000000000000da31d0d1bc934fc34f7189e38a413ca0a5e8b44f", symbol: "BSSB", coinGeckoId: "bitstable-finance", decimals: 18, price: 0.134229}, // Addr: 0xda31d0d1bc934fc34f7189e38a413ca0a5e8b44f, Notional: 1.3422899999999998 - {chain: 2, addr: "000000000000000000000000da9fdab21bc4a5811134a6e0ba6ca06624e67c07", symbol: "QUIDD", coinGeckoId: "quidd", decimals: 18, price: 0.00291998}, // Addr: 0xda9fdab21bc4a5811134a6e0ba6ca06624e67c07, Notional: 127.79876466 - {chain: 2, addr: "000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec7", symbol: "USDT", coinGeckoId: "tether", decimals: 6, price: 1}, // Addr: 0xdac17f958d2ee523a2206206994597c13d831ec7, Notional: 81473381.381512 - {chain: 2, addr: "000000000000000000000000db0170e2d0c1cc1b2e7a90313d9b9afa4f250289", symbol: "ADAPAD", coinGeckoId: "adapad", decimals: 18, price: 0.00856956}, // Addr: 0xdb0170e2d0c1cc1b2e7a90313d9b9afa4f250289, Notional: 22.207725276373974 - {chain: 2, addr: "000000000000000000000000db726152680ece3c9291f1016f1d36f3995f6941", symbol: "MEDIA", coinGeckoId: "media-network", decimals: 6, price: 15.82}, // Addr: 0xdb726152680ece3c9291f1016f1d36f3995f6941, Notional: 15.82 - {chain: 2, addr: "000000000000000000000000db82c0d91e057e05600c8f8dc836beb41da6df14", symbol: "SLN", coinGeckoId: "smart-layer-network", decimals: 18, price: 0.302279}, // Addr: 0xdb82c0d91e057e05600c8f8dc836beb41da6df14, Notional: 71233.75662721004 - {chain: 2, addr: "000000000000000000000000dbdb4d16eda451d0503b854cf79d55697f90c8df", symbol: "ALCX", coinGeckoId: "alchemix", decimals: 18, price: 21.05}, // Addr: 0xdbdb4d16eda451d0503b854cf79d55697f90c8df, Notional: 0.021050000000000003 - {chain: 2, addr: "000000000000000000000000dd69db25f6d620a7bad3023c5d32761d353d3de9", symbol: "GETH", coinGeckoId: "goerli-eth", decimals: 18, price: 0.02048946}, // Addr: 0xdd69db25f6d620a7bad3023c5d32761d353d3de9, Notional: 1.5367095000000002 - {chain: 2, addr: "000000000000000000000000de30da39c46104798bb5aa3fe8b9e0e1f348163f", symbol: "GTC", coinGeckoId: "gitcoin", decimals: 18, price: 1.18}, // Addr: 0xde30da39c46104798bb5aa3fe8b9e0e1f348163f, Notional: 24.779999999999998 - {chain: 2, addr: "000000000000000000000000de342a3e269056fc3305f9e315f4c40d917ba521", symbol: "BYTE", coinGeckoId: "byte", decimals: 9, price: 0.00001164}, // Addr: 0xde342a3e269056fc3305f9e315f4c40d917ba521, Notional: 353926.4495979772 - {chain: 2, addr: "000000000000000000000000de4ee8057785a7e8e800db58f9784845a5c2cbd6", symbol: "DEXE", coinGeckoId: "dexe", decimals: 18, price: 9.22}, // Addr: 0xde4ee8057785a7e8e800db58f9784845a5c2cbd6, Notional: 214812690.9888368 + {chain: 2, addr: "000000000000000000000000d3e4ba569045546d09cf021ecc5dfe42b1d7f6e4", symbol: "MNW", coinGeckoId: "morpheus-network", decimals: 18, price: 0.346864}, // Addr: 0xd3e4ba569045546d09cf021ecc5dfe42b1d7f6e4, Notional: 10.40592 + {chain: 2, addr: "000000000000000000000000d3fb8597d260efb2e693efd500d62a330a00f1eb", symbol: "TRUMP INU", coinGeckoId: "t-inu", decimals: 18, price: 0.00000103}, // Addr: 0xd3fb8597d260efb2e693efd500d62a330a00f1eb, Notional: 1877.8931734892537 + {chain: 2, addr: "000000000000000000000000d417144312dbf50465b1c641d016962017ef6240", symbol: "CQT", coinGeckoId: "covalent", decimals: 18, price: 0.00487494}, // Addr: 0xd417144312dbf50465b1c641d016962017ef6240, Notional: 27621.15066348041 + {chain: 2, addr: "000000000000000000000000d46ba6d942050d489dbd938a2c909a5d5039a161", symbol: "AMPL", coinGeckoId: "ampleforth", decimals: 9, price: 1.15}, // Addr: 0xd46ba6d942050d489dbd938a2c909a5d5039a161, Notional: 11.45042833 + {chain: 2, addr: "000000000000000000000000d49efa7bc0d339d74f487959c573d518ba3f8437", symbol: "COLI", coinGeckoId: "shield-finance", decimals: 18, price: 0.00069694}, // Addr: 0xd49efa7bc0d339d74f487959c573d518ba3f8437, Notional: 120269.24106151298 + {chain: 2, addr: "000000000000000000000000d4c435f5b09f855c3317c8524cb1f586e42795fa", symbol: "CND", coinGeckoId: "cindicator", decimals: 18, price: 0.00030315}, // Addr: 0xd4c435f5b09f855c3317c8524cb1f586e42795fa, Notional: 0.0012126 + {chain: 2, addr: "000000000000000000000000d533a949740bb3306d119cc777fa900ba034cd52", symbol: "CRV", coinGeckoId: "curve-dao-token", decimals: 18, price: 0.891931}, // Addr: 0xd533a949740bb3306d119cc777fa900ba034cd52, Notional: 34002.02322696971 + {chain: 2, addr: "000000000000000000000000d69f306549e9d96f183b1aeca30b8f4353c2ecc3", symbol: "MCHC", coinGeckoId: "mch-coin", decimals: 18, price: 0.04931065}, // Addr: 0xd69f306549e9d96f183b1aeca30b8f4353c2ecc3, Notional: 414.39969178289095 + {chain: 2, addr: "000000000000000000000000d6c7bb8531295e88d364ea67d5d1acc7d3f87454", symbol: "FTR", coinGeckoId: "fautor", decimals: 18, price: 0.01763813}, // Addr: 0xd6c7bb8531295e88d364ea67d5d1acc7d3f87454, Notional: 0.01763813 + {chain: 2, addr: "000000000000000000000000d7c302fc3ac829c7e896a32c4bd126f3e8bd0a1f", symbol: "B2M", coinGeckoId: "bit2me", decimals: 18, price: 0.01785051}, // Addr: 0xd7c302fc3ac829c7e896a32c4bd126f3e8bd0a1f, Notional: 0.0093813557015763 + {chain: 2, addr: "000000000000000000000000d7dcd9b99787c619b4d57979521258d1a7267ad7", symbol: "EVRY", coinGeckoId: "evrynet", decimals: 18, price: 0.01319301}, // Addr: 0xd7dcd9b99787c619b4d57979521258d1a7267ad7, Notional: 1.68870528 + {chain: 2, addr: "000000000000000000000000d96e84ddbc7cbe1d73c55b6fe8c64f3a6550deea", symbol: "GMAC", coinGeckoId: "gemach", decimals: 18, price: 0.00431376}, // Addr: 0xd96e84ddbc7cbe1d73c55b6fe8c64f3a6550deea, Notional: 113640.46874333065 + {chain: 2, addr: "000000000000000000000000d979c468a68062e7bdff4ba6df7842dfd3492e0f", symbol: "BBL", coinGeckoId: "beoble", decimals: 18, price: 0.00473646}, // Addr: 0xd979c468a68062e7bdff4ba6df7842dfd3492e0f, Notional: 29540.17914670226 + {chain: 2, addr: "000000000000000000000000d9c2d319cd7e6177336b0a9c93c21cb48d84fb54", symbol: "HAPI", coinGeckoId: "hapi", decimals: 18, price: 9.68}, // Addr: 0xd9c2d319cd7e6177336b0a9c93c21cb48d84fb54, Notional: 9.68 + {chain: 2, addr: "000000000000000000000000da31d0d1bc934fc34f7189e38a413ca0a5e8b44f", symbol: "BSSB", coinGeckoId: "bitstable-finance", decimals: 18, price: 0.132841}, // Addr: 0xda31d0d1bc934fc34f7189e38a413ca0a5e8b44f, Notional: 1.3284099999999999 + {chain: 2, addr: "000000000000000000000000da9fdab21bc4a5811134a6e0ba6ca06624e67c07", symbol: "QUIDD", coinGeckoId: "quidd", decimals: 18, price: 0.00282854}, // Addr: 0xda9fdab21bc4a5811134a6e0ba6ca06624e67c07, Notional: 152.08211018 + {chain: 2, addr: "000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec7", symbol: "USDT", coinGeckoId: "tether", decimals: 6, price: 0.99789}, // Addr: 0xdac17f958d2ee523a2206206994597c13d831ec7, Notional: 68712114.64196616 + {chain: 2, addr: "000000000000000000000000db0170e2d0c1cc1b2e7a90313d9b9afa4f250289", symbol: "ADAPAD", coinGeckoId: "adapad", decimals: 18, price: 0.00645377}, // Addr: 0xdb0170e2d0c1cc1b2e7a90313d9b9afa4f250289, Notional: 16.724726958782487 + {chain: 2, addr: "000000000000000000000000db726152680ece3c9291f1016f1d36f3995f6941", symbol: "MEDIA", coinGeckoId: "media-network", decimals: 6, price: 14.89}, // Addr: 0xdb726152680ece3c9291f1016f1d36f3995f6941, Notional: 14.89 + {chain: 2, addr: "000000000000000000000000db82c0d91e057e05600c8f8dc836beb41da6df14", symbol: "SLN", coinGeckoId: "smart-layer-network", decimals: 18, price: 0.179913}, // Addr: 0xdb82c0d91e057e05600c8f8dc836beb41da6df14, Notional: 41423.6473184144 + {chain: 2, addr: "000000000000000000000000dbdb4d16eda451d0503b854cf79d55697f90c8df", symbol: "ALCX", coinGeckoId: "alchemix", decimals: 18, price: 18.44}, // Addr: 0xdbdb4d16eda451d0503b854cf79d55697f90c8df, Notional: 0.01844 + {chain: 2, addr: "000000000000000000000000dd69db25f6d620a7bad3023c5d32761d353d3de9", symbol: "GETH", coinGeckoId: "goerli-eth", decimals: 18, price: 0.00671868}, // Addr: 0xdd69db25f6d620a7bad3023c5d32761d353d3de9, Notional: 0.503901 + {chain: 2, addr: "000000000000000000000000de30da39c46104798bb5aa3fe8b9e0e1f348163f", symbol: "GTC", coinGeckoId: "gitcoin", decimals: 18, price: 0.742838}, // Addr: 0xde30da39c46104798bb5aa3fe8b9e0e1f348163f, Notional: 15.599598 + {chain: 2, addr: "000000000000000000000000de342a3e269056fc3305f9e315f4c40d917ba521", symbol: "BYTE", coinGeckoId: "byte", decimals: 9, price: 0.00000631}, // Addr: 0xde342a3e269056fc3305f9e315f4c40d917ba521, Notional: 193496.66776046663 + {chain: 2, addr: "000000000000000000000000de4ee8057785a7e8e800db58f9784845a5c2cbd6", symbol: "DEXE", coinGeckoId: "dexe", decimals: 18, price: 14.67}, // Addr: 0xde4ee8057785a7e8e800db58f9784845a5c2cbd6, Notional: 341854816.4768129 {chain: 2, addr: "000000000000000000000000de5ea375ffbdc8b25a80fe13d631e8ba0ab4bb02", symbol: "GERA", coinGeckoId: "gera-coin", decimals: 18, price: 0.00004492}, // Addr: 0xde5ea375ffbdc8b25a80fe13d631e8ba0ab4bb02, Notional: 0.19918391196151078 - {chain: 2, addr: "000000000000000000000000defb0b264032e4e128b00d02b3fd0aa00331237b", symbol: "Buddha", coinGeckoId: "buddha", decimals: 18, price: 0.00000141}, // Addr: 0xdefb0b264032e4e128b00d02b3fd0aa00331237b, Notional: 6040.081345767608 - {chain: 2, addr: "000000000000000000000000df09a216fac5adc3e640db418c0b956076509503", symbol: "PKN", coinGeckoId: "poken", decimals: 18, price: 0.00015725}, // Addr: 0xdf09a216fac5adc3e640db418c0b956076509503, Notional: 11.24382159 - {chain: 2, addr: "000000000000000000000000df3ac4f479375802a821f7b7b46cd7eb5e4262cc", symbol: "eUSD", coinGeckoId: "eusd-new", decimals: 18, price: 0.98041}, // Addr: 0xdf3ac4f479375802a821f7b7b46cd7eb5e4262cc, Notional: 4.9020499901959 - {chain: 2, addr: "000000000000000000000000df574c24545e5ffecb9a659c229253d4111d87e1", symbol: "HUSD", coinGeckoId: "husd", decimals: 8, price: 0.02802148}, // Addr: 0xdf574c24545e5ffecb9a659c229253d4111d87e1, Notional: 216.0913511433598 - {chain: 2, addr: "000000000000000000000000dfdb7f72c1f195c5951a234e8db9806eb0635346", symbol: "NFD", coinGeckoId: "feisty-doge-nft", decimals: 18, price: 0.00030757}, // Addr: 0xdfdb7f72c1f195c5951a234e8db9806eb0635346, Notional: 235064.5074790236 - {chain: 2, addr: "000000000000000000000000e020b01b6fbd83066aa2e8ee0ccd1eb8d9cc70bf", symbol: "ARCD", coinGeckoId: "arcade-protocol", decimals: 18, price: 0.02887222}, // Addr: 0xe020b01b6fbd83066aa2e8ee0ccd1eb8d9cc70bf, Notional: 43308.33 - {chain: 2, addr: "000000000000000000000000e0b9a2c3e9f40cf74b2c7f591b2b0cca055c3112", symbol: "GS", coinGeckoId: "genesis-shards", decimals: 18, price: 0.00926234}, // Addr: 0xe0b9a2c3e9f40cf74b2c7f591b2b0cca055c3112, Notional: 0.8611547331024396 - {chain: 2, addr: "000000000000000000000000e0f63a424a4439cbe457d80e4f4b51ad25b2c56c", symbol: "SPX", coinGeckoId: "spx6900", decimals: 8, price: 0.603644}, // Addr: 0xe0f63a424a4439cbe457d80e4f4b51ad25b2c56c, Notional: 95023293.44596146 - {chain: 2, addr: "000000000000000000000000e1c7e30c42c24582888c758984f6e382096786bd", symbol: "XCUR", coinGeckoId: "curate", decimals: 8, price: 0.00494438}, // Addr: 0xe1c7e30c42c24582888c758984f6e382096786bd, Notional: 0.00988876 - {chain: 2, addr: "000000000000000000000000e28b3b32b6c345a34ff64674606124dd5aceca30", symbol: "INJ", coinGeckoId: "injective-protocol", decimals: 18, price: 28.5}, // Addr: 0xe28b3b32b6c345a34ff64674606124dd5aceca30, Notional: 245417.79847431 - {chain: 2, addr: "000000000000000000000000e3818504c1b32bf1557b16c238b2e01fd3149c17", symbol: "PLR", coinGeckoId: "pillar", decimals: 18, price: 0.00490309}, // Addr: 0xe3818504c1b32bf1557b16c238b2e01fd3149c17, Notional: 5.28793281663084 - {chain: 2, addr: "000000000000000000000000e3c408bd53c31c085a1746af401a4042954ff740", symbol: "GMT", coinGeckoId: "stepn", decimals: 8, price: 0.207966}, // Addr: 0xe3c408bd53c31c085a1746af401a4042954ff740, Notional: 22.97455631322654 - {chain: 2, addr: "000000000000000000000000e4ab0be415e277d82c38625b72bd7dea232c2e7d", symbol: "XRP20", coinGeckoId: "xrp20", decimals: 18, price: 0.00001634}, // Addr: 0xe4ab0be415e277d82c38625b72bd7dea232c2e7d, Notional: 0.6574793716567838 - {chain: 2, addr: "000000000000000000000000e4cfe9eaa8cdb0942a80b7bc68fd8ab0f6d44903", symbol: "XEND", coinGeckoId: "xend-finance", decimals: 18, price: 0.04258841}, // Addr: 0xe4cfe9eaa8cdb0942a80b7bc68fd8ab0f6d44903, Notional: 246.5831143660015 - {chain: 2, addr: "000000000000000000000000e516d78d784c77d479977be58905b3f2b1111126", symbol: "SPWN", coinGeckoId: "bitspawn", decimals: 18, price: 0.00004114}, // Addr: 0xe516d78d784c77d479977be58905b3f2b1111126, Notional: 57.966600680100974 + {chain: 2, addr: "000000000000000000000000defb0b264032e4e128b00d02b3fd0aa00331237b", symbol: "Buddha", coinGeckoId: "buddha", decimals: 18, price: 7.54113e-7}, // Addr: 0xdefb0b264032e4e128b00d02b3fd0aa00331237b, Notional: 3415.2838631711584 + {chain: 2, addr: "000000000000000000000000df09a216fac5adc3e640db418c0b956076509503", symbol: "PKN", coinGeckoId: "poken", decimals: 18, price: 0.00009148}, // Addr: 0xdf09a216fac5adc3e640db418c0b956076509503, Notional: 6.5410798032 + {chain: 2, addr: "000000000000000000000000df3ac4f479375802a821f7b7b46cd7eb5e4262cc", symbol: "eUSD", coinGeckoId: "eusd-new", decimals: 18, price: 0.93634}, // Addr: 0xdf3ac4f479375802a821f7b7b46cd7eb5e4262cc, Notional: 4.6816999906365995 + {chain: 2, addr: "000000000000000000000000df574c24545e5ffecb9a659c229253d4111d87e1", symbol: "HUSD", coinGeckoId: "husd", decimals: 8, price: 0.02807749}, // Addr: 0xdf574c24545e5ffecb9a659c229253d4111d87e1, Notional: 216.52327967024485 + {chain: 2, addr: "000000000000000000000000dfdb7f72c1f195c5951a234e8db9806eb0635346", symbol: "NFD", coinGeckoId: "feisty-doge-nft", decimals: 18, price: 0.00014718}, // Addr: 0xdfdb7f72c1f195c5951a234e8db9806eb0635346, Notional: 137967.10611908088 + {chain: 2, addr: "000000000000000000000000e020b01b6fbd83066aa2e8ee0ccd1eb8d9cc70bf", symbol: "ARCD", coinGeckoId: "arcade-protocol", decimals: 18, price: 0.01346495}, // Addr: 0xe020b01b6fbd83066aa2e8ee0ccd1eb8d9cc70bf, Notional: 20197.425 + {chain: 2, addr: "000000000000000000000000e0b9a2c3e9f40cf74b2c7f591b2b0cca055c3112", symbol: "GS", coinGeckoId: "genesis-shards", decimals: 18, price: 0.00752986}, // Addr: 0xe0b9a2c3e9f40cf74b2c7f591b2b0cca055c3112, Notional: 0.7000795240294284 + {chain: 2, addr: "000000000000000000000000e0f63a424a4439cbe457d80e4f4b51ad25b2c56c", symbol: "SPX", coinGeckoId: "spx6900", decimals: 8, price: 0.866615}, // Addr: 0xe0f63a424a4439cbe457d80e4f4b51ad25b2c56c, Notional: 132051729.6486059 + {chain: 2, addr: "000000000000000000000000e1c7e30c42c24582888c758984f6e382096786bd", symbol: "XCUR", coinGeckoId: "curate", decimals: 8, price: 0.00245587}, // Addr: 0xe1c7e30c42c24582888c758984f6e382096786bd, Notional: 0.00491174 + {chain: 2, addr: "000000000000000000000000e28b3b32b6c345a34ff64674606124dd5aceca30", symbol: "INJ", coinGeckoId: "injective-protocol", decimals: 18, price: 19.64}, // Addr: 0xe28b3b32b6c345a34ff64674606124dd5aceca30, Notional: 169123.0021766824 + {chain: 2, addr: "000000000000000000000000e3818504c1b32bf1557b16c238b2e01fd3149c17", symbol: "PLR", coinGeckoId: "pillar", decimals: 18, price: 0.00476142}, // Addr: 0xe3818504c1b32bf1557b16c238b2e01fd3149c17, Notional: 5.135143159061411 + {chain: 2, addr: "000000000000000000000000e3c408bd53c31c085a1746af401a4042954ff740", symbol: "GMT", coinGeckoId: "stepn", decimals: 8, price: 0.151428}, // Addr: 0xe3c408bd53c31c085a1746af401a4042954ff740, Notional: 16.728653305825322 + {chain: 2, addr: "000000000000000000000000e4ab0be415e277d82c38625b72bd7dea232c2e7d", symbol: "XRP20", coinGeckoId: "xrp20", decimals: 18, price: 0.00001536}, // Addr: 0xe4ab0be415e277d82c38625b72bd7dea232c2e7d, Notional: 0.6180467043236352 + {chain: 2, addr: "000000000000000000000000e4cfe9eaa8cdb0942a80b7bc68fd8ab0f6d44903", symbol: "XEND", coinGeckoId: "xend-finance", decimals: 18, price: 0.053298}, // Addr: 0xe4cfe9eaa8cdb0942a80b7bc68fd8ab0f6d44903, Notional: 308.5906900370112 + {chain: 2, addr: "000000000000000000000000e516d78d784c77d479977be58905b3f2b1111126", symbol: "SPWN", coinGeckoId: "bitspawn", decimals: 18, price: 0.00001587}, // Addr: 0xe516d78d784c77d479977be58905b3f2b1111126, Notional: 22.36096141937779 {chain: 2, addr: "000000000000000000000000e53ec727dbdeb9e2d5456c3be40cff031ab40a55", symbol: "SUPER", coinGeckoId: "superfarm", decimals: 18, price: 1.35}, // Addr: 0xe53ec727dbdeb9e2d5456c3be40cff031ab40a55, Notional: 135 - {chain: 2, addr: "000000000000000000000000e6f47303032a09c8c0f8ebb713c00e6ed345e8c3", symbol: "RISITA", coinGeckoId: "risitas", decimals: 18, price: 0.00000241}, // Addr: 0xe6f47303032a09c8c0f8ebb713c00e6ed345e8c3, Notional: 0.3989172926000549 - {chain: 2, addr: "000000000000000000000000e74dc43867e0cbeb208f1a012fc60dcbbf0e3044", symbol: "CWAP", coinGeckoId: "defire", decimals: 18, price: 0.00903989}, // Addr: 0xe74dc43867e0cbeb208f1a012fc60dcbbf0e3044, Notional: 0.01807978 - {chain: 2, addr: "000000000000000000000000e7f72bc0252ca7b16dbb72eeee1afcdb2429f2dd", symbol: "NFTL", coinGeckoId: "nftlaunch", decimals: 18, price: 0.00198894}, // Addr: 0xe7f72bc0252ca7b16dbb72eeee1afcdb2429f2dd, Notional: 2.0088293999999998 - {chain: 2, addr: "000000000000000000000000e831f96a7a1dce1aa2eb760b1e296c6a74caa9d5", symbol: "NEXM", coinGeckoId: "nexum", decimals: 8, price: 0.01291013}, // Addr: 0xe831f96a7a1dce1aa2eb760b1e296c6a74caa9d5, Notional: 8289.132337018056 - {chain: 2, addr: "000000000000000000000000e939f011a3d8fc0aa874c97e8156053a903d7176", symbol: "DOLZ", coinGeckoId: "dolz-io", decimals: 18, price: 0.00677041}, // Addr: 0xe939f011a3d8fc0aa874c97e8156053a903d7176, Notional: 242.0775858356375 + {chain: 2, addr: "000000000000000000000000e6f47303032a09c8c0f8ebb713c00e6ed345e8c3", symbol: "RISITA", coinGeckoId: "risitas", decimals: 18, price: 0.0000023}, // Addr: 0xe6f47303032a09c8c0f8ebb713c00e6ed345e8c3, Notional: 0.38070944936934703 + {chain: 2, addr: "000000000000000000000000e74dc43867e0cbeb208f1a012fc60dcbbf0e3044", symbol: "CWAP", coinGeckoId: "defire", decimals: 18, price: 0.00772247}, // Addr: 0xe74dc43867e0cbeb208f1a012fc60dcbbf0e3044, Notional: 0.01544494 + {chain: 2, addr: "000000000000000000000000e7f72bc0252ca7b16dbb72eeee1afcdb2429f2dd", symbol: "NFTL", coinGeckoId: "nftlaunch", decimals: 18, price: 0.00165198}, // Addr: 0xe7f72bc0252ca7b16dbb72eeee1afcdb2429f2dd, Notional: 1.6684998 + {chain: 2, addr: "000000000000000000000000e831f96a7a1dce1aa2eb760b1e296c6a74caa9d5", symbol: "NEXM", coinGeckoId: "nexum", decimals: 8, price: 0.01550832}, // Addr: 0xe831f96a7a1dce1aa2eb760b1e296c6a74caa9d5, Notional: 9957.337130208904 + {chain: 2, addr: "000000000000000000000000e939f011a3d8fc0aa874c97e8156053a903d7176", symbol: "DOLZ", coinGeckoId: "dolz-io", decimals: 18, price: 0.00629545}, // Addr: 0xe939f011a3d8fc0aa874c97e8156053a903d7176, Notional: 225.0952804555358 {chain: 2, addr: "000000000000000000000000e9b7b5d5e8d2bcc78884f9f9099bfa42a9e5c1a5", symbol: "ZENF", coinGeckoId: "zenland", decimals: 18, price: 0.00268076}, // Addr: 0xe9b7b5d5e8d2bcc78884f9f9099bfa42a9e5c1a5, Notional: 35207.59223486586 - {chain: 2, addr: "000000000000000000000000ea068fba19ce95f12d252ad8cb2939225c4ea02d", symbol: "FIEF", coinGeckoId: "fief", decimals: 18, price: 0.00075166}, // Addr: 0xea068fba19ce95f12d252ad8cb2939225c4ea02d, Notional: 5916.181371223685 - {chain: 2, addr: "000000000000000000000000eaa63125dd63f10874f99cdbbb18410e7fc79dd3", symbol: "HEMULE", coinGeckoId: "hemule", decimals: 18, price: 0.00722595}, // Addr: 0xeaa63125dd63f10874f99cdbbb18410e7fc79dd3, Notional: 16046.085796030313 - {chain: 2, addr: "000000000000000000000000eb4c2781e4eba804ce9a9803c67d0893436bb27d", symbol: "renBTC", coinGeckoId: "renbtc", decimals: 8, price: 91170}, // Addr: 0xeb4c2781e4eba804ce9a9803c67d0893436bb27d, Notional: 91.17 - {chain: 2, addr: "000000000000000000000000ebd9d99a3982d547c5bb4db7e3b1f9f14b67eb83", symbol: "ID", coinGeckoId: "everid", decimals: 18, price: 0.03980289}, // Addr: 0xebd9d99a3982d547c5bb4db7e3b1f9f14b67eb83, Notional: 1031.474600558302 - {chain: 2, addr: "000000000000000000000000ed35af169af46a02ee13b9d79eb57d6d68c1749e", symbol: "OMI", coinGeckoId: "ecomi", decimals: 18, price: 0.00032838}, // Addr: 0xed35af169af46a02ee13b9d79eb57d6d68c1749e, Notional: 6.5676000000000005 - {chain: 2, addr: "000000000000000000000000f0d33beda4d734c72684b5f9abbebf715d0a7935", symbol: "NTX", coinGeckoId: "nunet", decimals: 6, price: 0.04946086}, // Addr: 0xf0d33beda4d734c72684b5f9abbebf715d0a7935, Notional: 11.6297320118 - {chain: 2, addr: "000000000000000000000000f1182229b71e79e504b1d2bf076c15a277311e05", symbol: "LBR", coinGeckoId: "lybra-finance", decimals: 18, price: 0.09612}, // Addr: 0xf1182229b71e79e504b1d2bf076c15a277311e05, Notional: 0.009612 - {chain: 2, addr: "000000000000000000000000f16e81dce15b08f326220742020379b855b87df9", symbol: "ICE", coinGeckoId: "ice-token", decimals: 18, price: 0.485954}, // Addr: 0xf16e81dce15b08f326220742020379b855b87df9, Notional: 360.3169316854937 - {chain: 2, addr: "000000000000000000000000f17a3fe536f8f7847f1385ec1bc967b2ca9cae8d", symbol: "AMKT", coinGeckoId: "alongside-crypto-market-index", decimals: 18, price: 253.98}, // Addr: 0xf17a3fe536f8f7847f1385ec1bc967b2ca9cae8d, Notional: 25.398 - {chain: 2, addr: "000000000000000000000000f17e65822b568b3903685a7c9f496cf7656cc6c2", symbol: "BICO", coinGeckoId: "biconomy", decimals: 18, price: 0.379259}, // Addr: 0xf17e65822b568b3903685a7c9f496cf7656cc6c2, Notional: 325562.83379057905 - {chain: 2, addr: "000000000000000000000000f19308f923582a6f7c465e5ce7a9dc1bec6665b1", symbol: "TITANX", coinGeckoId: "titanx", decimals: 18, price: 6.73436e-7}, // Addr: 0xf19308f923582a6f7c465e5ce7a9dc1bec6665b1, Notional: 1176.1637956243248 - {chain: 2, addr: "000000000000000000000000f1f955016ecbcd7321c7266bccfb96c68ea5e49b", symbol: "RLY", coinGeckoId: "rally-2", decimals: 18, price: 0.00218109}, // Addr: 0xf1f955016ecbcd7321c7266bccfb96c68ea5e49b, Notional: 87745.7992475055 - {chain: 2, addr: "000000000000000000000000f21661d0d1d76d3ecb8e1b9f1c923dbfffae4097", symbol: "RIO", coinGeckoId: "realio-network", decimals: 18, price: 1.2}, // Addr: 0xf21661d0d1d76d3ecb8e1b9f1c923dbfffae4097, Notional: 19.126761204 - {chain: 2, addr: "000000000000000000000000f2fdd9c25d7bc8002ce89716d1be484b2d976944", symbol: "𝕏PAY", coinGeckoId: "payments", decimals: 18, price: 0.00269228}, // Addr: 0xf2fdd9c25d7bc8002ce89716d1be484b2d976944, Notional: 67.307 - {chain: 2, addr: "000000000000000000000000f3ae5d769e153ef72b4e3591ac004e89f48107a1", symbol: "DPR", coinGeckoId: "deeper-network", decimals: 18, price: 0.00244667}, // Addr: 0xf3ae5d769e153ef72b4e3591ac004e89f48107a1, Notional: 46.50959372544318 - {chain: 2, addr: "000000000000000000000000f418588522d5dd018b425e472991e52ebbeeeeee", symbol: "PUSH", coinGeckoId: "ethereum-push-notification-service", decimals: 18, price: 0.107348}, // Addr: 0xf418588522d5dd018b425e472991e52ebbeeeeee, Notional: 0.107348 - {chain: 2, addr: "000000000000000000000000f629cbd94d3791c9250152bd8dfbdf380e2a3b9c", symbol: "ENJ", coinGeckoId: "enjincoin", decimals: 18, price: 0.303326}, // Addr: 0xf629cbd94d3791c9250152bd8dfbdf380e2a3b9c, Notional: 577.62193340942 - {chain: 2, addr: "000000000000000000000000f64265e65c4529879a7abf467e00d39e39c0b0da", symbol: "RFKJ", coinGeckoId: "independence-token", decimals: 18, price: 0.00000347}, // Addr: 0xf64265e65c4529879a7abf467e00d39e39c0b0da, Notional: 5578.681875395122 - {chain: 2, addr: "000000000000000000000000f6e06b54855eff198a2d9a8686113665499a6134", symbol: "Celt", coinGeckoId: "celestial", decimals: 18, price: 0.00004027}, // Addr: 0xf6e06b54855eff198a2d9a8686113665499a6134, Notional: 0.06052581 - {chain: 2, addr: "000000000000000000000000f70ce9ee486106882d3dc43ddbd84e0fa71ac2a5", symbol: "DUCKER", coinGeckoId: "ducker", decimals: 18, price: 0.00000155}, // Addr: 0xf70ce9ee486106882d3dc43ddbd84e0fa71ac2a5, Notional: 780.8102834919749 - {chain: 2, addr: "000000000000000000000000f7413489c474ca4399eee604716c72879eea3615", symbol: "APYS", coinGeckoId: "apyswap", decimals: 18, price: 0.00636373}, // Addr: 0xf7413489c474ca4399eee604716c72879eea3615, Notional: 0.979232024215047 - {chain: 2, addr: "000000000000000000000000f819d9cb1c2a819fd991781a822de3ca8607c3c9", symbol: "UNIBOT", coinGeckoId: "unibot", decimals: 18, price: 8.43}, // Addr: 0xf819d9cb1c2a819fd991781a822de3ca8607c3c9, Notional: 825.0229670859 - {chain: 2, addr: "000000000000000000000000f831938caf837cd505de196bbb408d81a06376ab", symbol: "JEFF", coinGeckoId: "jeff", decimals: 18, price: 0.00674164}, // Addr: 0xf831938caf837cd505de196bbb408d81a06376ab, Notional: 6285.043099924452 - {chain: 2, addr: "000000000000000000000000f8c3527cc04340b208c854e985240c02f7b7793f", symbol: "FRONT", coinGeckoId: "frontier-token", decimals: 18, price: 0.50088}, // Addr: 0xf8c3527cc04340b208c854e985240c02f7b7793f, Notional: 1860.7493134912368 - {chain: 2, addr: "000000000000000000000000f99d58e463a2e07e5692127302c20a191861b4d6", symbol: "ANY", coinGeckoId: "anyswap", decimals: 18, price: 1.81}, // Addr: 0xf99d58e463a2e07e5692127302c20a191861b4d6, Notional: 10.6765951435 - {chain: 2, addr: "000000000000000000000000fa3e941d1f6b7b10ed84a0c211bfa8aee907965e", symbol: "HAY", coinGeckoId: "haycoin", decimals: 18, price: 367699}, // Addr: 0xfa3e941d1f6b7b10ed84a0c211bfa8aee907965e, Notional: 38551.33179219 - {chain: 2, addr: "000000000000000000000000faba6f8e4a5e8ab82f62fe7c39859fa577269be3", symbol: "ONDO", coinGeckoId: "ondo-finance", decimals: 18, price: 1.2}, // Addr: 0xfaba6f8e4a5e8ab82f62fe7c39859fa577269be3, Notional: 857656.7999999999 - {chain: 2, addr: "000000000000000000000000fad45e47083e4607302aa43c65fb3106f1cd7607", symbol: "HOGE", coinGeckoId: "hoge-finance", decimals: 9, price: 0.00003441}, // Addr: 0xfad45e47083e4607302aa43c65fb3106f1cd7607, Notional: 25443.498503257302 - {chain: 2, addr: "000000000000000000000000fb5c6815ca3ac72ce9f5006869ae67f18bf77006", symbol: "PSTAKE", coinGeckoId: "pstake-finance", decimals: 18, price: 0.055779}, // Addr: 0xfb5c6815ca3ac72ce9f5006869ae67f18bf77006, Notional: 9554.11850239143 - {chain: 2, addr: "000000000000000000000000fc05987bd2be489accf0f509e44b0145d68240f7", symbol: "ESS", coinGeckoId: "essentia", decimals: 18, price: 0.00029221}, // Addr: 0xfc05987bd2be489accf0f509e44b0145d68240f7, Notional: 0.00029221 - {chain: 2, addr: "000000000000000000000000fc5e4ed56153b57aa8ef769eba3e79e58e19be93", symbol: "SOLAV", coinGeckoId: "solav", decimals: 18, price: 0.00003453}, // Addr: 0xfc5e4ed56153b57aa8ef769eba3e79e58e19be93, Notional: 0.03470265 - {chain: 2, addr: "000000000000000000000000fcaf0e4498e78d65526a507360f755178b804ba8", symbol: "SHIB", coinGeckoId: "niccagewaluigielmo42069inu", decimals: 18, price: 0.00007749}, // Addr: 0xfcaf0e4498e78d65526a507360f755178b804ba8, Notional: 17.80986086481747 - {chain: 2, addr: "000000000000000000000000fd09911130e6930bf87f2b0554c44f400bd80d3e", symbol: "ETHIX", coinGeckoId: "ethichub", decimals: 18, price: 0.185046}, // Addr: 0xfd09911130e6930bf87f2b0554c44f400bd80d3e, Notional: 2135883.055173261 - {chain: 2, addr: "000000000000000000000000fe80d611c6403f70e5b1b9b722d2b3510b740b2b", symbol: "EQB", coinGeckoId: "equilibria-finance", decimals: 18, price: 0.386239}, // Addr: 0xfe80d611c6403f70e5b1b9b722d2b3510b740b2b, Notional: 388463.5879443348 - {chain: 2, addr: "000000000000000000000000ff56cc6b1e6ded347aa0b7676c85ab0b3d08b0fa", symbol: "ORBS", coinGeckoId: "orbs", decimals: 18, price: 0.03402288}, // Addr: 0xff56cc6b1e6ded347aa0b7676c85ab0b3d08b0fa, Notional: 12967.774333232084 - {chain: 2, addr: "000000000000000000000000ff836a5821e69066c87e268bc51b849fab94240c", symbol: "шайлушай", coinGeckoId: "real-smurf-cat", decimals: 18, price: 0.00009265}, // Addr: 0xff836a5821e69066c87e268bc51b849fab94240c, Notional: 150396.49793259593 - {chain: 2, addr: "000000000000000000000000ffbf315f70e458e49229654dea4ce192d26f9b25", symbol: "VOLT", coinGeckoId: "voltage", decimals: 18, price: 0.00170657}, // Addr: 0xffbf315f70e458e49229654dea4ce192d26f9b25, Notional: 0.170657 - {chain: 3, addr: "0000000000000000000000002c71557d2edfedd8330e52be500058a014d329e7", symbol: "BTL", coinGeckoId: "bitlocus", decimals: 6, price: 0.00066229}, // Addr: terra193c42lfwmlkasvcw22l9qqzc5q2dx208tkd7wl, Notional: 327732.6444386612 - {chain: 3, addr: "00000000000000000000000034aa51100370594b15479392149157eeb479b9a8", symbol: "ASTRO", coinGeckoId: "astroport", decimals: 6, price: 0.00144144}, // Addr: terra1xj49zyqrwpv5k928jwfpfy2ha668nwdgkwlrg3, Notional: 1.00041736066272 - {chain: 3, addr: "0000000000000000000000005b7d58fe96a636927960029ea47996db5808d015", symbol: "XRUNE", coinGeckoId: "thorstarter", decimals: 6, price: 0.01122788}, // Addr: terra1td743l5k5cmfy7tqq202g7vkmdvq35q48u2jfm, Notional: 86.25468108290988 - {chain: 3, addr: "0000000000000000000000008f5cd460d57ac54e111646fc569179144c7f0c28", symbol: "PLY", coinGeckoId: "playnity", decimals: 6, price: 0.00121698}, // Addr: terra13awdgcx40tz5uygkgm79dytez3x87rpg4uhnvu, Notional: 110772.31218518177 - {chain: 3, addr: "000000000000000000000000a21d626429c68c8c768ba0b2913895571703fd5b", symbol: "MIR", coinGeckoId: "mirror-protocol", decimals: 6, price: 0.0324267}, // Addr: terra15gwkyepfc6xgca5t5zefzwy42uts8l2m4g40k6, Notional: 729.6706963375021 - {chain: 3, addr: "000000000000000000000000a8a9afbd2157e093e8448dd6450abec8ad79aeeb", symbol: "ANC", coinGeckoId: "anchor-protocol", decimals: 6, price: 0.00880249}, // Addr: terra14z56l0fp2lsf86zy3hty2z47ezkhnthtr9yq76, Notional: 622.3589508728533 + {chain: 2, addr: "000000000000000000000000ea068fba19ce95f12d252ad8cb2939225c4ea02d", symbol: "FIEF", coinGeckoId: "fief", decimals: 18, price: 0.00081851}, // Addr: 0xea068fba19ce95f12d252ad8cb2939225c4ea02d, Notional: 6442.345760264347 + {chain: 2, addr: "000000000000000000000000eaa63125dd63f10874f99cdbbb18410e7fc79dd3", symbol: "HEMULE", coinGeckoId: "hemule", decimals: 18, price: 0.00401006}, // Addr: 0xeaa63125dd63f10874f99cdbbb18410e7fc79dd3, Notional: 8882.028660553198 + {chain: 2, addr: "000000000000000000000000eb4c2781e4eba804ce9a9803c67d0893436bb27d", symbol: "renBTC", coinGeckoId: "renbtc", decimals: 8, price: 33929}, // Addr: 0xeb4c2781e4eba804ce9a9803c67d0893436bb27d, Notional: 33.929 + {chain: 2, addr: "000000000000000000000000ebd9d99a3982d547c5bb4db7e3b1f9f14b67eb83", symbol: "ID", coinGeckoId: "everid", decimals: 18, price: 0.0326617}, // Addr: 0xebd9d99a3982d547c5bb4db7e3b1f9f14b67eb83, Notional: 846.4137644541663 + {chain: 2, addr: "000000000000000000000000ed35af169af46a02ee13b9d79eb57d6d68c1749e", symbol: "OMI", coinGeckoId: "ecomi", decimals: 18, price: 0.00043002}, // Addr: 0xed35af169af46a02ee13b9d79eb57d6d68c1749e, Notional: 8.600399999999999 + {chain: 2, addr: "000000000000000000000000f0d33beda4d734c72684b5f9abbebf715d0a7935", symbol: "NTX", coinGeckoId: "nunet", decimals: 6, price: 0.03625764}, // Addr: 0xf0d33beda4d734c72684b5f9abbebf715d0a7935, Notional: 8.5252588932 + {chain: 2, addr: "000000000000000000000000f1182229b71e79e504b1d2bf076c15a277311e05", symbol: "LBR", coinGeckoId: "lybra-finance", decimals: 18, price: 0.08636}, // Addr: 0xf1182229b71e79e504b1d2bf076c15a277311e05, Notional: 0.008636000000000001 + {chain: 2, addr: "000000000000000000000000f16e81dce15b08f326220742020379b855b87df9", symbol: "ICE", coinGeckoId: "ice-token", decimals: 18, price: 0.302589}, // Addr: 0xf16e81dce15b08f326220742020379b855b87df9, Notional: 224.35856077279303 + {chain: 2, addr: "000000000000000000000000f17a3fe536f8f7847f1385ec1bc967b2ca9cae8d", symbol: "AMKT", coinGeckoId: "alongside-crypto-market-index", decimals: 18, price: 267.16}, // Addr: 0xf17a3fe536f8f7847f1385ec1bc967b2ca9cae8d, Notional: 26.716000000000005 + {chain: 2, addr: "000000000000000000000000f17e65822b568b3903685a7c9f496cf7656cc6c2", symbol: "BICO", coinGeckoId: "biconomy", decimals: 18, price: 0.298805}, // Addr: 0xf17e65822b568b3903685a7c9f496cf7656cc6c2, Notional: 32240.510214940816 + {chain: 2, addr: "000000000000000000000000f19308f923582a6f7c465e5ce7a9dc1bec6665b1", symbol: "TITANX", coinGeckoId: "titanx", decimals: 18, price: 4.97439e-7}, // Addr: 0xf19308f923582a6f7c465e5ce7a9dc1bec6665b1, Notional: 868.7829910066711 + {chain: 2, addr: "000000000000000000000000f1f955016ecbcd7321c7266bccfb96c68ea5e49b", symbol: "RLY", coinGeckoId: "rally-2", decimals: 18, price: 0.00184774}, // Addr: 0xf1f955016ecbcd7321c7266bccfb96c68ea5e49b, Notional: 74641.3494385723 + {chain: 2, addr: "000000000000000000000000f21661d0d1d76d3ecb8e1b9f1c923dbfffae4097", symbol: "RIO", coinGeckoId: "realio-network", decimals: 18, price: 0.852965}, // Addr: 0xf21661d0d1d76d3ecb8e1b9f1c923dbfffae4097, Notional: 13.59538155864155 + {chain: 2, addr: "000000000000000000000000f2fdd9c25d7bc8002ce89716d1be484b2d976944", symbol: "𝕏PAY", coinGeckoId: "payments", decimals: 18, price: 0.00037109}, // Addr: 0xf2fdd9c25d7bc8002ce89716d1be484b2d976944, Notional: 9.27725 + {chain: 2, addr: "000000000000000000000000f3ae5d769e153ef72b4e3591ac004e89f48107a1", symbol: "DPR", coinGeckoId: "deeper-network", decimals: 18, price: 0.0028785}, // Addr: 0xf3ae5d769e153ef72b4e3591ac004e89f48107a1, Notional: 54.718399105187125 + {chain: 2, addr: "000000000000000000000000f418588522d5dd018b425e472991e52ebbeeeeee", symbol: "PUSH", coinGeckoId: "ethereum-push-notification-service", decimals: 18, price: 0.108227}, // Addr: 0xf418588522d5dd018b425e472991e52ebbeeeeee, Notional: 0.108227 + {chain: 2, addr: "000000000000000000000000f629cbd94d3791c9250152bd8dfbdf380e2a3b9c", symbol: "ENJ", coinGeckoId: "enjincoin", decimals: 18, price: 0.208486}, // Addr: 0xf629cbd94d3791c9250152bd8dfbdf380e2a3b9c, Notional: 397.01867432662 + {chain: 2, addr: "000000000000000000000000f64265e65c4529879a7abf467e00d39e39c0b0da", symbol: "RFKJ", coinGeckoId: "independence-token", decimals: 18, price: 0.00000264}, // Addr: 0xf64265e65c4529879a7abf467e00d39e39c0b0da, Notional: 4244.29975534384 + {chain: 2, addr: "000000000000000000000000f6e06b54855eff198a2d9a8686113665499a6134", symbol: "Celt", coinGeckoId: "celestial", decimals: 18, price: 0.00004315}, // Addr: 0xf6e06b54855eff198a2d9a8686113665499a6134, Notional: 0.06485445 + {chain: 2, addr: "000000000000000000000000f70ce9ee486106882d3dc43ddbd84e0fa71ac2a5", symbol: "DUCKER", coinGeckoId: "ducker", decimals: 18, price: 0.00000118}, // Addr: 0xf70ce9ee486106882d3dc43ddbd84e0fa71ac2a5, Notional: 593.9284048790003 + {chain: 2, addr: "000000000000000000000000f7413489c474ca4399eee604716c72879eea3615", symbol: "APYS", coinGeckoId: "apyswap", decimals: 18, price: 0.00334385}, // Addr: 0xf7413489c474ca4399eee604716c72879eea3615, Notional: 0.514541786683515 + {chain: 2, addr: "000000000000000000000000f819d9cb1c2a819fd991781a822de3ca8607c3c9", symbol: "UNIBOT", coinGeckoId: "unibot", decimals: 18, price: 6.34}, // Addr: 0xf819d9cb1c2a819fd991781a822de3ca8607c3c9, Notional: 620.4799064442 + {chain: 2, addr: "000000000000000000000000f831938caf837cd505de196bbb408d81a06376ab", symbol: "JEFF", coinGeckoId: "jeff", decimals: 18, price: 0.00476871}, // Addr: 0xf831938caf837cd505de196bbb408d81a06376ab, Notional: 4322.969771142324 + {chain: 2, addr: "000000000000000000000000f8c3527cc04340b208c854e985240c02f7b7793f", symbol: "FRONT", coinGeckoId: "frontier-token", decimals: 18, price: 0.518809}, // Addr: 0xf8c3527cc04340b208c854e985240c02f7b7793f, Notional: 1927.3548366536397 + {chain: 2, addr: "000000000000000000000000f99d58e463a2e07e5692127302c20a191861b4d6", symbol: "ANY", coinGeckoId: "anyswap", decimals: 18, price: 4.03}, // Addr: 0xf99d58e463a2e07e5692127302c20a191861b4d6, Notional: 23.7716455405 + {chain: 2, addr: "000000000000000000000000fa3e941d1f6b7b10ed84a0c211bfa8aee907965e", symbol: "HAY", coinGeckoId: "haycoin", decimals: 18, price: 232791}, // Addr: 0xfa3e941d1f6b7b10ed84a0c211bfa8aee907965e, Notional: 24818.81692056 + {chain: 2, addr: "000000000000000000000000faba6f8e4a5e8ab82f62fe7c39859fa577269be3", symbol: "ONDO", coinGeckoId: "ondo-finance", decimals: 18, price: 1.35}, // Addr: 0xfaba6f8e4a5e8ab82f62fe7c39859fa577269be3, Notional: 964863.9 + {chain: 2, addr: "000000000000000000000000fad45e47083e4607302aa43c65fb3106f1cd7607", symbol: "HOGE", coinGeckoId: "hoge-finance", decimals: 9, price: 0.00001908}, // Addr: 0xfad45e47083e4607302aa43c65fb3106f1cd7607, Notional: 17296.20285523624 + {chain: 2, addr: "000000000000000000000000fb5c6815ca3ac72ce9f5006869ae67f18bf77006", symbol: "PSTAKE", coinGeckoId: "pstake-finance", decimals: 18, price: 0.051389}, // Addr: 0xfb5c6815ca3ac72ce9f5006869ae67f18bf77006, Notional: 890.4680817180216 + {chain: 2, addr: "000000000000000000000000fc05987bd2be489accf0f509e44b0145d68240f7", symbol: "ESS", coinGeckoId: "essentia", decimals: 18, price: 0.00019839}, // Addr: 0xfc05987bd2be489accf0f509e44b0145d68240f7, Notional: 0.00019839 + {chain: 2, addr: "000000000000000000000000fc5e4ed56153b57aa8ef769eba3e79e58e19be93", symbol: "SOLAV", coinGeckoId: "solav", decimals: 18, price: 0.00002482}, // Addr: 0xfc5e4ed56153b57aa8ef769eba3e79e58e19be93, Notional: 0.0249441 + {chain: 2, addr: "000000000000000000000000fcaf0e4498e78d65526a507360f755178b804ba8", symbol: "SHIB", coinGeckoId: "niccagewaluigielmo42069inu", decimals: 18, price: 0.00005413}, // Addr: 0xfcaf0e4498e78d65526a507360f755178b804ba8, Notional: 12.440931328075488 + {chain: 2, addr: "000000000000000000000000fd09911130e6930bf87f2b0554c44f400bd80d3e", symbol: "ETHIX", coinGeckoId: "ethichub", decimals: 18, price: 0.163032}, // Addr: 0xfd09911130e6930bf87f2b0554c44f400bd80d3e, Notional: 1879773.3754216512 + {chain: 2, addr: "000000000000000000000000fe80d611c6403f70e5b1b9b722d2b3510b740b2b", symbol: "EQB", coinGeckoId: "equilibria-finance", decimals: 18, price: 0.356325}, // Addr: 0xfe80d611c6403f70e5b1b9b722d2b3510b740b2b, Notional: 352870.980721958 + {chain: 2, addr: "000000000000000000000000ff56cc6b1e6ded347aa0b7676c85ab0b3d08b0fa", symbol: "ORBS", coinGeckoId: "orbs", decimals: 18, price: 0.02720284}, // Addr: 0xff56cc6b1e6ded347aa0b7676c85ab0b3d08b0fa, Notional: 10321.438359177711 + {chain: 2, addr: "000000000000000000000000ff836a5821e69066c87e268bc51b849fab94240c", symbol: "шайлушай", coinGeckoId: "real-smurf-cat", decimals: 18, price: 0.00006857}, // Addr: 0xff836a5821e69066c87e268bc51b849fab94240c, Notional: 121419.65802544028 + {chain: 2, addr: "000000000000000000000000ffbf315f70e458e49229654dea4ce192d26f9b25", symbol: "VOLT", coinGeckoId: "voltage", decimals: 18, price: 0.00161053}, // Addr: 0xffbf315f70e458e49229654dea4ce192d26f9b25, Notional: 0.161053 + {chain: 3, addr: "0000000000000000000000002c71557d2edfedd8330e52be500058a014d329e7", symbol: "BTL", coinGeckoId: "bitlocus", decimals: 6, price: 0.00060038}, // Addr: terra193c42lfwmlkasvcw22l9qqzc5q2dx208tkd7wl, Notional: 297096.6269581051 + {chain: 3, addr: "00000000000000000000000034aa51100370594b15479392149157eeb479b9a8", symbol: "ASTRO", coinGeckoId: "astroport", decimals: 6, price: 0.00020221}, // Addr: terra1xj49zyqrwpv5k928jwfpfy2ha668nwdgkwlrg3, Notional: 0.14135292652598 + {chain: 3, addr: "0000000000000000000000005b7d58fe96a636927960029ea47996db5808d015", symbol: "XRUNE", coinGeckoId: "thorstarter", decimals: 6, price: 0.0068581}, // Addr: terra1td743l5k5cmfy7tqq202g7vkmdvq35q48u2jfm, Notional: 52.6852111293231 + {chain: 3, addr: "0000000000000000000000008f5cd460d57ac54e111646fc569179144c7f0c28", symbol: "PLY", coinGeckoId: "playnity", decimals: 6, price: 0.00112983}, // Addr: terra13awdgcx40tz5uygkgm79dytez3x87rpg4uhnvu, Notional: 103038.27677351997 + {chain: 3, addr: "000000000000000000000000a21d626429c68c8c768ba0b2913895571703fd5b", symbol: "MIR", coinGeckoId: "mirror-protocol", decimals: 6, price: 0.02541862}, // Addr: terra15gwkyepfc6xgca5t5zefzwy42uts8l2m4g40k6, Notional: 571.9737794884572 + {chain: 3, addr: "000000000000000000000000a8a9afbd2157e093e8448dd6450abec8ad79aeeb", symbol: "ANC", coinGeckoId: "anchor-protocol", decimals: 6, price: 0.00954159}, // Addr: terra14z56l0fp2lsf86zy3hty2z47ezkhnthtr9yq76, Notional: 674.6152443296054 {chain: 3, addr: "000000000000000000000000ab05561fadecc41babc73132847ff55a5cef2f37", symbol: "TNS", coinGeckoId: "terra-name-service", decimals: 6, price: 0.0010459}, // Addr: terra14vz4v8adanzph278xyeggll4tfww7teh0xtw2y, Notional: 0.826261 - {chain: 3, addr: "0100000000000000000000000000000000000000000000000000000075757364", symbol: "UST", coinGeckoId: "terrausd", decimals: 6, price: 0.02456593}, // Addr: uusd, Notional: 3473100.073681803 - {chain: 3, addr: "010000000000000000000000000000000000000000000000000000756c756e61", symbol: "LUNA", coinGeckoId: "terra-luna", decimals: 6, price: 0.00012716}, // Addr: uluna, Notional: 10480465.24246386 - {chain: 4, addr: "0000000000000000000000000231f91e02debd20345ae8ab7d71a41f8e140ce7", symbol: "bwJUP", coinGeckoId: "jupiter", decimals: 18, price: 0.0007861}, // Addr: 0x0231f91e02debd20345ae8ab7d71a41f8e140ce7, Notional: 21.488403946793355 - {chain: 4, addr: "000000000000000000000000027a9d301fb747cd972cfb29a63f3bda551dfc5c", symbol: "mWOM", coinGeckoId: "magpie-wom", decimals: 18, price: 0.00992145}, // Addr: 0x027a9d301fb747cd972cfb29a63f3bda551dfc5c, Notional: 4.833314924018773 - {chain: 4, addr: "000000000000000000000000039cb485212f996a9dbb85a9a75d898f94d38da6", symbol: "DEXE", coinGeckoId: "dexe", decimals: 18, price: 9.22}, // Addr: 0x039cb485212f996a9dbb85a9a75d898f94d38da6, Notional: 19.362000000000002 - {chain: 4, addr: "00000000000000000000000003ff0ff224f904be3118461335064bb48df47938", symbol: "ONE", coinGeckoId: "wrapped-one", decimals: 18, price: 0.02774578}, // Addr: 0x03ff0ff224f904be3118461335064bb48df47938, Notional: 1.0571142180000002 - {chain: 4, addr: "0000000000000000000000000782b6d8c4551b9760e74c0545a9bcd90bdc41e5", symbol: "HAY", coinGeckoId: "helio-protocol-hay", decimals: 18, price: 0.999175}, // Addr: 0x0782b6d8c4551b9760e74c0545a9bcd90bdc41e5, Notional: 17.47310911252775 - {chain: 4, addr: "00000000000000000000000008b450e4a48c04cdf6db2bd4cf24057f7b9563ff", symbol: "QUO", coinGeckoId: "quo", decimals: 18, price: 0.00434909}, // Addr: 0x08b450e4a48c04cdf6db2bd4cf24057f7b9563ff, Notional: 132268.1081838705 - {chain: 4, addr: "0000000000000000000000000a356f512f6fce740111ee04ab1699017a908680", symbol: "UFARM", coinGeckoId: "unifarm", decimals: 18, price: 0.00016965}, // Addr: 0x0a356f512f6fce740111ee04ab1699017a908680, Notional: 0.115510087176237 - {chain: 4, addr: "0000000000000000000000000b15ddf19d47e6a86a56148fb4afffc6929bcb89", symbol: "IDIA", coinGeckoId: "idia", decimals: 18, price: 0.04861188}, // Addr: 0x0b15ddf19d47e6a86a56148fb4afffc6929bcb89, Notional: 6448431.477095349 - {chain: 4, addr: "0000000000000000000000000b33542240d6fa323c796749f6d6869fdb7f13ca", symbol: "ETHM", coinGeckoId: "ethereum-meta", decimals: 18, price: 4.73007e-13}, // Addr: 0x0b33542240d6fa323c796749f6d6869fdb7f13ca, Notional: 0.01001316660112288 - {chain: 4, addr: "0000000000000000000000000c7d31befe4945089a3b8f835d6e8c1d4df6d952", symbol: "POKO", coinGeckoId: "poko", decimals: 9, price: 0.00000941}, // Addr: 0x0c7d31befe4945089a3b8f835d6e8c1d4df6d952, Notional: 1428.899468147889 - {chain: 4, addr: "0000000000000000000000000cf8e180350253271f4b917ccfb0accc4862f262", symbol: "BTCBR", coinGeckoId: "bitcoin-br", decimals: 18, price: 1.6153e-14}, // Addr: 0x0cf8e180350253271f4b917ccfb0accc4862f262, Notional: 0.0008238031615299999 - {chain: 4, addr: "0000000000000000000000000d8ce2a99bb6e3b7db580ed848240e4a0f9ae153", symbol: "FIL", coinGeckoId: "binance-peg-filecoin", decimals: 18, price: 6.8}, // Addr: 0x0d8ce2a99bb6e3b7db580ed848240e4a0f9ae153, Notional: 483.888 - {chain: 4, addr: "0000000000000000000000000e09fabb73bd3ade0a17ecc321fd13a19e81ce82", symbol: "Cake", coinGeckoId: "pancakeswap-token", decimals: 18, price: 2.94}, // Addr: 0x0e09fabb73bd3ade0a17ecc321fd13a19e81ce82, Notional: 511.0222266072 - {chain: 4, addr: "0000000000000000000000000eb3a705fc54725037cc9e008bdede697f62f335", symbol: "ATOM", coinGeckoId: "cosmos", decimals: 18, price: 8.48}, // Addr: 0x0eb3a705fc54725037cc9e008bdede697f62f335, Notional: 243.0713626992 - {chain: 4, addr: "0000000000000000000000000ebd9537a25f56713e34c45b38f421a1e7191469", symbol: "MOOV", coinGeckoId: "dotmoovs", decimals: 18, price: 0.00260596}, // Addr: 0x0ebd9537a25f56713e34c45b38f421a1e7191469, Notional: 581.9519188045117 - {chain: 4, addr: "00000000000000000000000010c9524dbf934b3b625dce3bdc0efdc367f4e84b", symbol: "MVX", coinGeckoId: "mavaverse-token", decimals: 8, price: 2.1996e-7}, // Addr: 0x10c9524dbf934b3b625dce3bdc0efdc367f4e84b, Notional: 0.03504811353893058 + {chain: 3, addr: "0100000000000000000000000000000000000000000000000000000075757364", symbol: "UST", coinGeckoId: "terrausd", decimals: 6, price: 0.01939717}, // Addr: uusd, Notional: 2739663.357803941 + {chain: 3, addr: "010000000000000000000000000000000000000000000000000000756c756e61", symbol: "LUNA", coinGeckoId: "terra-luna", decimals: 6, price: 0.00010742}, // Addr: uluna, Notional: 8673546.298886565 + {chain: 4, addr: "0000000000000000000000000231f91e02debd20345ae8ab7d71a41f8e140ce7", symbol: "bwJUP", coinGeckoId: "jupiter", decimals: 18, price: 0.00073986}, // Addr: 0x0231f91e02debd20345ae8ab7d71a41f8e140ce7, Notional: 20.224412344580244 + {chain: 4, addr: "000000000000000000000000027a9d301fb747cd972cfb29a63f3bda551dfc5c", symbol: "mWOM", coinGeckoId: "magpie-wom", decimals: 18, price: 0.00668389}, // Addr: 0x027a9d301fb747cd972cfb29a63f3bda551dfc5c, Notional: 26.087434715474505 + {chain: 4, addr: "000000000000000000000000031b41e504677879370e9dbcf937283a8691fa7f", symbol: "FET", coinGeckoId: "fetch-ai", decimals: 18, price: 1.27}, // Addr: 0x031b41e504677879370e9dbcf937283a8691fa7f, Notional: 0.254 + {chain: 4, addr: "000000000000000000000000039cb485212f996a9dbb85a9a75d898f94d38da6", symbol: "DEXE", coinGeckoId: "dexe", decimals: 18, price: 14.67}, // Addr: 0x039cb485212f996a9dbb85a9a75d898f94d38da6, Notional: 30.807000000000002 + {chain: 4, addr: "00000000000000000000000003ff0ff224f904be3118461335064bb48df47938", symbol: "ONE", coinGeckoId: "wrapped-one", decimals: 18, price: 0.02612088}, // Addr: 0x03ff0ff224f904be3118461335064bb48df47938, Notional: 0.995205528 + {chain: 4, addr: "0000000000000000000000000782b6d8c4551b9760e74c0545a9bcd90bdc41e5", symbol: "HAY", coinGeckoId: "helio-protocol-hay", decimals: 18, price: 0.993028}, // Addr: 0x0782b6d8c4551b9760e74c0545a9bcd90bdc41e5, Notional: 17.365613226707243 + {chain: 4, addr: "00000000000000000000000008b450e4a48c04cdf6db2bd4cf24057f7b9563ff", symbol: "QUO", coinGeckoId: "quo", decimals: 18, price: 0.00408495}, // Addr: 0x08b450e4a48c04cdf6db2bd4cf24057f7b9563ff, Notional: 159596.5044541521 + {chain: 4, addr: "0000000000000000000000000a356f512f6fce740111ee04ab1699017a908680", symbol: "UFARM", coinGeckoId: "unifarm", decimals: 18, price: 0.00007284}, // Addr: 0x0a356f512f6fce740111ee04ab1699017a908680, Notional: 0.0495947819034312 + {chain: 4, addr: "0000000000000000000000000b15ddf19d47e6a86a56148fb4afffc6929bcb89", symbol: "IDIA", coinGeckoId: "idia", decimals: 18, price: 0.059907}, // Addr: 0x0b15ddf19d47e6a86a56148fb4afffc6929bcb89, Notional: 7946744.386317728 + {chain: 4, addr: "0000000000000000000000000b33542240d6fa323c796749f6d6869fdb7f13ca", symbol: "ETHM", coinGeckoId: "ethereum-meta", decimals: 18, price: 4.46256e-13}, // Addr: 0x0b33542240d6fa323c796749f6d6869fdb7f13ca, Notional: 0.0094468700775056 + {chain: 4, addr: "0000000000000000000000000c7d31befe4945089a3b8f835d6e8c1d4df6d952", symbol: "POKO", coinGeckoId: "poko", decimals: 9, price: 0.00000791}, // Addr: 0x0c7d31befe4945089a3b8f835d6e8c1d4df6d952, Notional: 1212.9974302725655 + {chain: 4, addr: "0000000000000000000000000cf8e180350253271f4b917ccfb0accc4862f262", symbol: "BTCBR", coinGeckoId: "bitcoin-br", decimals: 18, price: 1.0362e-14}, // Addr: 0x0cf8e180350253271f4b917ccfb0accc4862f262, Notional: 0.00052846210362 + {chain: 4, addr: "0000000000000000000000000d8ce2a99bb6e3b7db580ed848240e4a0f9ae153", symbol: "FIL", coinGeckoId: "binance-peg-filecoin", decimals: 18, price: 4.93}, // Addr: 0x0d8ce2a99bb6e3b7db580ed848240e4a0f9ae153, Notional: 350.81879999999995 + {chain: 4, addr: "0000000000000000000000000e09fabb73bd3ade0a17ecc321fd13a19e81ce82", symbol: "Cake", coinGeckoId: "pancakeswap-token", decimals: 18, price: 2.5}, // Addr: 0x0e09fabb73bd3ade0a17ecc321fd13a19e81ce82, Notional: 434.54270970000005 + {chain: 4, addr: "0000000000000000000000000eb3a705fc54725037cc9e008bdede697f62f335", symbol: "ATOM", coinGeckoId: "cosmos", decimals: 18, price: 6.18}, // Addr: 0x0eb3a705fc54725037cc9e008bdede697f62f335, Notional: 177.14398838219998 + {chain: 4, addr: "0000000000000000000000000ebd9537a25f56713e34c45b38f421a1e7191469", symbol: "MOOV", coinGeckoId: "dotmoovs", decimals: 18, price: 0.001787}, // Addr: 0x0ebd9537a25f56713e34c45b38f421a1e7191469, Notional: 399.0652500052427 + {chain: 4, addr: "00000000000000000000000010c9524dbf934b3b625dce3bdc0efdc367f4e84b", symbol: "MVX", coinGeckoId: "mavaverse-token", decimals: 8, price: 2.19861e-7}, // Addr: 0x10c9524dbf934b3b625dce3bdc0efdc367f4e84b, Notional: 0.03503233901974366 {chain: 4, addr: "00000000000000000000000010f6f2b97f3ab29583d9d38babf2994df7220c21", symbol: "TEDDY", coinGeckoId: "teddy-doge", decimals: 18, price: 1.50024e-10}, // Addr: 0x10f6f2b97f3ab29583d9d38babf2994df7220c21, Notional: 0.30783698513606866 - {chain: 4, addr: "000000000000000000000000111111111117dc0aa78b770fa6a738034120c302", symbol: "1INCH", coinGeckoId: "1inch", decimals: 18, price: 0.450082}, // Addr: 0x111111111117dc0aa78b770fa6a738034120c302, Notional: 35.12258051214046 - {chain: 4, addr: "000000000000000000000000114597f4260caf4cde1eeb0b9d9865b0b7b9a46a", symbol: "AGF", coinGeckoId: "augmented-finance", decimals: 18, price: 0.00010345}, // Addr: 0x114597f4260caf4cde1eeb0b9d9865b0b7b9a46a, Notional: 0.0020689999999999997 - {chain: 4, addr: "00000000000000000000000011a38e06699b238d6d9a0c7a01f3ac63a07ad318", symbol: "USDFI", coinGeckoId: "usdfi", decimals: 18, price: 0.909266}, // Addr: 0x11a38e06699b238d6d9a0c7a01f3ac63a07ad318, Notional: 0.909266 + {chain: 4, addr: "000000000000000000000000111111111117dc0aa78b770fa6a738034120c302", symbol: "1INCH", coinGeckoId: "1inch", decimals: 18, price: 0.381911}, // Addr: 0x111111111117dc0aa78b770fa6a738034120c302, Notional: 29.80279114910633 + {chain: 4, addr: "000000000000000000000000114597f4260caf4cde1eeb0b9d9865b0b7b9a46a", symbol: "AGF", coinGeckoId: "augmented-finance", decimals: 18, price: 0.00006308}, // Addr: 0x114597f4260caf4cde1eeb0b9d9865b0b7b9a46a, Notional: 0.0012615999999999999 + {chain: 4, addr: "00000000000000000000000011a38e06699b238d6d9a0c7a01f3ac63a07ad318", symbol: "USDFI", coinGeckoId: "usdfi", decimals: 18, price: 0.845019}, // Addr: 0x11a38e06699b238d6d9a0c7a01f3ac63a07ad318, Notional: 0.845019 {chain: 4, addr: "000000000000000000000000129385c4acd0075e45a0c9a5177bdfec9678a138", symbol: "MTK", coinGeckoId: "metakings", decimals: 18, price: 0.00010591}, // Addr: 0x129385c4acd0075e45a0c9a5177bdfec9678a138, Notional: 0.0042363999999999995 - {chain: 4, addr: "00000000000000000000000012bb890508c125661e03b09ec06e404bc9289040", symbol: "RACA", coinGeckoId: "radio-caca", decimals: 18, price: 0.00024251}, // Addr: 0x12bb890508c125661e03b09ec06e404bc9289040, Notional: 432.41109299746125 - {chain: 4, addr: "00000000000000000000000012e34cdf6a031a10fe241864c32fb03a4fdad739", symbol: "FREE", coinGeckoId: "freedom-coin", decimals: 18, price: 2.23171e-7}, // Addr: 0x12e34cdf6a031a10fe241864c32fb03a4fdad739, Notional: 0.00005132933 - {chain: 4, addr: "00000000000000000000000012f31b73d812c6bb0d735a218c086d44d5fe5f89", symbol: "agEUR", coinGeckoId: "ageur", decimals: 18, price: 1.046}, // Addr: 0x12f31b73d812c6bb0d735a218c086d44d5fe5f89, Notional: 16.40366103072 - {chain: 4, addr: "0000000000000000000000001446f3cedf4d86a9399e49f7937766e6de2a3aab", symbol: "KRW", coinGeckoId: "krown", decimals: 18, price: 0.00000228}, // Addr: 0x1446f3cedf4d86a9399e49f7937766e6de2a3aab, Notional: 0.0908969700053052 - {chain: 4, addr: "00000000000000000000000014778860e937f509e651192a90589de711fb88a9", symbol: "CYBER", coinGeckoId: "cyberconnect", decimals: 18, price: 4.62}, // Addr: 0x14778860e937f509e651192a90589de711fb88a9, Notional: 60.6293723574 - {chain: 4, addr: "000000000000000000000000154a9f9cbd3449ad22fdae23044319d6ef2a1fab", symbol: "SKILL", coinGeckoId: "cryptoblades", decimals: 18, price: 0.305214}, // Addr: 0x154a9f9cbd3449ad22fdae23044319d6ef2a1fab, Notional: 0.000305214 - {chain: 4, addr: "0000000000000000000000001591e923e0836a3949b59637fbe8959f000894b9", symbol: "MAI", coinGeckoId: "multi-ai", decimals: 18, price: 0.00203575}, // Addr: 0x1591e923e0836a3949b59637fbe8959f000894b9, Notional: 13.347527329078714 - {chain: 4, addr: "0000000000000000000000001613957159e9b0ac6c80e824f7eea748a32a0ae2", symbol: "CGG", coinGeckoId: "chain-guardians", decimals: 18, price: 0.01115428}, // Addr: 0x1613957159e9b0ac6c80e824f7eea748a32a0ae2, Notional: 9.268319074041917 - {chain: 4, addr: "0000000000000000000000001796ae0b0fa4862485106a0de9b654efe301d0b2", symbol: "PMON", coinGeckoId: "polychain-monsters", decimals: 18, price: 0.155208}, // Addr: 0x1796ae0b0fa4862485106a0de9b654efe301d0b2, Notional: 0.05660250752064001 - {chain: 4, addr: "00000000000000000000000019b99162adaab85134e781ac0048c275c31b205a", symbol: "TAUR", coinGeckoId: "marnotaur", decimals: 18, price: 0.00082903}, // Addr: 0x19b99162adaab85134e781ac0048c275c31b205a, Notional: 3.382169475713505 - {chain: 4, addr: "00000000000000000000000019c018e13cff682e729cc7b5fb68c8a641bf98a4", symbol: "burn", coinGeckoId: "burnedfi", decimals: 18, price: 0.859009}, // Addr: 0x19c018e13cff682e729cc7b5fb68c8a641bf98a4, Notional: 54.84311418548529 - {chain: 4, addr: "0000000000000000000000001a131f7b106d58f33eaf0fe5b47db2f2045e5732", symbol: "DEGEN", coinGeckoId: "degenreborn", decimals: 18, price: 2.6682e-8}, // Addr: 0x1a131f7b106d58f33eaf0fe5b47db2f2045e5732, Notional: 4833.563996982721 - {chain: 4, addr: "0000000000000000000000001a28ed8472f644e8898a169a644503b779748d6e", symbol: "SOFI", coinGeckoId: "rai-finance", decimals: 18, price: 0.01122514}, // Addr: 0x1a28ed8472f644e8898a169a644503b779748d6e, Notional: 37.67238578925277 - {chain: 4, addr: "0000000000000000000000001af3f329e8be154074d8769d1ffa4ee058b1dbc3", symbol: "DAI", coinGeckoId: "dai", decimals: 18, price: 1}, // Addr: 0x1af3f329e8be154074d8769d1ffa4ee058b1dbc3, Notional: 1527.3376407 - {chain: 4, addr: "0000000000000000000000001cb9ca00538265a22e56b758026948608ba5d86f", symbol: "LSR", coinGeckoId: "lasereyes", decimals: 8, price: 0.00094495}, // Addr: 0x1cb9ca00538265a22e56b758026948608ba5d86f, Notional: 0.1474122 - {chain: 4, addr: "0000000000000000000000001ce0c2827e2ef14d5c4f29a091d735a204794041", symbol: "AVAX", coinGeckoId: "binance-peg-avalanche", decimals: 18, price: 46.89}, // Addr: 0x1ce0c2827e2ef14d5c4f29a091d735a204794041, Notional: 5924.8703491866 - {chain: 4, addr: "0000000000000000000000001d1cb8997570e73949930c01fe5796c88d7336c6", symbol: "PBR", coinGeckoId: "polkabridge", decimals: 18, price: 0.03818387}, // Addr: 0x1d1cb8997570e73949930c01fe5796c88d7336c6, Notional: 0.03818387 - {chain: 4, addr: "0000000000000000000000001d2f0da169ceb9fc7b3144628db156f3f6c60dbe", symbol: "XRP", coinGeckoId: "binance-peg-xrp", decimals: 18, price: 2.35}, // Addr: 0x1d2f0da169ceb9fc7b3144628db156f3f6c60dbe, Notional: 2159.2337835099997 - {chain: 4, addr: "0000000000000000000000001da87b114f35e1dc91f72bf57fc07a768ad40bb0", symbol: "EQZ", coinGeckoId: "equalizer", decimals: 18, price: 0.00368382}, // Addr: 0x1da87b114f35e1dc91f72bf57fc07a768ad40bb0, Notional: 0.0368382 - {chain: 4, addr: "0000000000000000000000001ee098cbaf1f846d5df1993f7e2d10afb35a878d", symbol: "SABLE", coinGeckoId: "sable", decimals: 18, price: 0.00546652}, // Addr: 0x1ee098cbaf1f846d5df1993f7e2d10afb35a878d, Notional: 5956.702535778795 - {chain: 4, addr: "0000000000000000000000001fa4a73a3f0133f0025378af00236f3abdee5d63", symbol: "NEAR", coinGeckoId: "wrapped-near", decimals: 18, price: 6.55}, // Addr: 0x1fa4a73a3f0133f0025378af00236f3abdee5d63, Notional: 164.11811 - {chain: 4, addr: "000000000000000000000000200c234721b5e549c3693ccc93cf191f90dc2af9", symbol: "METAL", coinGeckoId: "drunk-robots", decimals: 18, price: 0.01704866}, // Addr: 0x200c234721b5e549c3693ccc93cf191f90dc2af9, Notional: 69.32606095747835 - {chain: 4, addr: "0000000000000000000000002170ed0880ac9a755fd29b2688956bd959f933f8", symbol: "ETH", coinGeckoId: "weth", decimals: 18, price: 3594.89}, // Addr: 0x2170ed0880ac9a755fd29b2688956bd959f933f8, Notional: 212214.668804658 - {chain: 4, addr: "00000000000000000000000021f9b5b2626603e3f40bfc13d01afb8c431d382f", symbol: "ZINU", coinGeckoId: "zombie-inu", decimals: 9, price: 2.80144e-10}, // Addr: 0x21f9b5b2626603e3f40bfc13d01afb8c431d382f, Notional: 1.9387021405881826 - {chain: 4, addr: "00000000000000000000000022168882276e5d5e1da694343b41dd7726eeb288", symbol: "WSB", coinGeckoId: "wall-street-bets-dapp", decimals: 18, price: 0.00016695}, // Addr: 0x22168882276e5d5e1da694343b41dd7726eeb288, Notional: 0.7425797772929446 - {chain: 4, addr: "0000000000000000000000002222227e22102fe3322098e4cbfe18cfebd57c95", symbol: "TLM", coinGeckoId: "alien-worlds", decimals: 4, price: 0.01406341}, // Addr: 0x2222227e22102fe3322098e4cbfe18cfebd57c95, Notional: 12.688008502 - {chain: 4, addr: "0000000000000000000000002235e79086dd23135119366da45851c741874e5b", symbol: "CREDI", coinGeckoId: "credefi", decimals: 18, price: 0.01816184}, // Addr: 0x2235e79086dd23135119366da45851c741874e5b, Notional: 47.40314403964449 - {chain: 4, addr: "0000000000000000000000002326c7395d02a8c89a9d7a0b0c1cf159d49ce51c", symbol: "TBAC", coinGeckoId: "blockaura", decimals: 8, price: 0.00976581}, // Addr: 0x2326c7395d02a8c89a9d7a0b0c1cf159d49ce51c, Notional: 0.0051758793 - {chain: 4, addr: "00000000000000000000000023396cf899ca06c4472205fc903bdb4de249d6fc", symbol: "UST", coinGeckoId: "wrapped-ust", decimals: 18, price: 0.02485643}, // Addr: 0x23396cf899ca06c4472205fc903bdb4de249d6fc, Notional: 1.3790059859616761 - {chain: 4, addr: "00000000000000000000000023e8a70534308a4aaf76fb8c32ec13d17a3bd89e", symbol: "lUSD", coinGeckoId: "lusd", decimals: 18, price: 0.00000323}, // Addr: 0x23e8a70534308a4aaf76fb8c32ec13d17a3bd89e, Notional: 22.869195647429503 - {chain: 4, addr: "0000000000000000000000002416092f143378750bb29b79ed961ab195cceea5", symbol: "ezETH", coinGeckoId: "renzo-restaked-eth", decimals: 18, price: 3690.34}, // Addr: 0x2416092f143378750bb29b79ed961ab195cceea5, Notional: 64.0304988856 - {chain: 4, addr: "000000000000000000000000245d9f531757f83064ad808b4c9b220c703a4934", symbol: "GODE", coinGeckoId: "gode-chain", decimals: 6, price: 0.00084764}, // Addr: 0x245d9f531757f83064ad808b4c9b220c703a4934, Notional: 0.00046620200000000003 - {chain: 4, addr: "000000000000000000000000250632378e573c6be1ac2f97fcdf00515d0aa91b", symbol: "BETH", coinGeckoId: "binance-eth", decimals: 18, price: 3763.17}, // Addr: 0x250632378e573c6be1ac2f97fcdf00515d0aa91b, Notional: 746.4690996426 + {chain: 4, addr: "00000000000000000000000012bb890508c125661e03b09ec06e404bc9289040", symbol: "RACA", coinGeckoId: "radio-caca", decimals: 18, price: 0.00019331}, // Addr: 0x12bb890508c125661e03b09ec06e404bc9289040, Notional: 344.68429502840803 + {chain: 4, addr: "00000000000000000000000012e34cdf6a031a10fe241864c32fb03a4fdad739", symbol: "FREE", coinGeckoId: "freedom-coin", decimals: 18, price: 1.5211e-7}, // Addr: 0x12e34cdf6a031a10fe241864c32fb03a4fdad739, Notional: 0.0000349853 + {chain: 4, addr: "00000000000000000000000012f31b73d812c6bb0d735a218c086d44d5fe5f89", symbol: "agEUR", coinGeckoId: "ageur", decimals: 18, price: 1.031}, // Addr: 0x12f31b73d812c6bb0d735a218c086d44d5fe5f89, Notional: 16.16842688592 + {chain: 4, addr: "0000000000000000000000001446f3cedf4d86a9399e49f7937766e6de2a3aab", symbol: "KRW", coinGeckoId: "krown", decimals: 18, price: 0.00000236}, // Addr: 0x1446f3cedf4d86a9399e49f7937766e6de2a3aab, Notional: 0.0940863373739124 + {chain: 4, addr: "00000000000000000000000014778860e937f509e651192a90589de711fb88a9", symbol: "CYBER", coinGeckoId: "cyberconnect", decimals: 18, price: 3.2}, // Addr: 0x14778860e937f509e651192a90589de711fb88a9, Notional: 41.994370464000006 + {chain: 4, addr: "000000000000000000000000154a9f9cbd3449ad22fdae23044319d6ef2a1fab", symbol: "SKILL", coinGeckoId: "cryptoblades", decimals: 18, price: 0.28497}, // Addr: 0x154a9f9cbd3449ad22fdae23044319d6ef2a1fab, Notional: 0.00028497 + {chain: 4, addr: "0000000000000000000000001591e923e0836a3949b59637fbe8959f000894b9", symbol: "MAI", coinGeckoId: "multi-ai", decimals: 18, price: 0.00065357}, // Addr: 0x1591e923e0836a3949b59637fbe8959f000894b9, Notional: 4.2851742288915515 + {chain: 4, addr: "0000000000000000000000001613957159e9b0ac6c80e824f7eea748a32a0ae2", symbol: "CGG", coinGeckoId: "chain-guardians", decimals: 18, price: 0.00987065}, // Addr: 0x1613957159e9b0ac6c80e824f7eea748a32a0ae2, Notional: 8.201724689374108 + {chain: 4, addr: "0000000000000000000000001796ae0b0fa4862485106a0de9b654efe301d0b2", symbol: "PMON", coinGeckoId: "polychain-monsters", decimals: 18, price: 0.125381}, // Addr: 0x1796ae0b0fa4862485106a0de9b654efe301d0b2, Notional: 0.04572495615848 + {chain: 4, addr: "00000000000000000000000019b99162adaab85134e781ac0048c275c31b205a", symbol: "TAUR", coinGeckoId: "marnotaur", decimals: 18, price: 0.00054311}, // Addr: 0x19b99162adaab85134e781ac0048c275c31b205a, Notional: 2.21571000320225 + {chain: 4, addr: "00000000000000000000000019c018e13cff682e729cc7b5fb68c8a641bf98a4", symbol: "burn", coinGeckoId: "burnedfi", decimals: 18, price: 1.003}, // Addr: 0x19c018e13cff682e729cc7b5fb68c8a641bf98a4, Notional: 62.97433031719999 + {chain: 4, addr: "0000000000000000000000001a131f7b106d58f33eaf0fe5b47db2f2045e5732", symbol: "DEGEN", coinGeckoId: "degenreborn", decimals: 18, price: 3.2946e-8}, // Addr: 0x1a131f7b106d58f33eaf0fe5b47db2f2045e5732, Notional: 5968.315697646081 + {chain: 4, addr: "0000000000000000000000001a28ed8472f644e8898a169a644503b779748d6e", symbol: "SOFI", coinGeckoId: "rai-finance", decimals: 18, price: 0.0105245}, // Addr: 0x1a28ed8472f644e8898a169a644503b779748d6e, Notional: 35.32098702011652 + {chain: 4, addr: "0000000000000000000000001af3f329e8be154074d8769d1ffa4ee058b1dbc3", symbol: "DAI", coinGeckoId: "dai", decimals: 18, price: 0.99899}, // Addr: 0x1af3f329e8be154074d8769d1ffa4ee058b1dbc3, Notional: 1525.795029682893 + {chain: 4, addr: "0000000000000000000000001cb9ca00538265a22e56b758026948608ba5d86f", symbol: "LSR", coinGeckoId: "lasereyes", decimals: 8, price: 0.00102348}, // Addr: 0x1cb9ca00538265a22e56b758026948608ba5d86f, Notional: 0.15966288 + {chain: 4, addr: "0000000000000000000000001ce0c2827e2ef14d5c4f29a091d735a204794041", symbol: "AVAX", coinGeckoId: "binance-peg-avalanche", decimals: 18, price: 35.63}, // Addr: 0x1ce0c2827e2ef14d5c4f29a091d735a204794041, Notional: 4502.0927818622 + {chain: 4, addr: "0000000000000000000000001d1cb8997570e73949930c01fe5796c88d7336c6", symbol: "PBR", coinGeckoId: "polkabridge", decimals: 18, price: 0.03113037}, // Addr: 0x1d1cb8997570e73949930c01fe5796c88d7336c6, Notional: 0.03113037 + {chain: 4, addr: "0000000000000000000000001d2f0da169ceb9fc7b3144628db156f3f6c60dbe", symbol: "XRP", coinGeckoId: "binance-peg-xrp", decimals: 18, price: 2.08}, // Addr: 0x1d2f0da169ceb9fc7b3144628db156f3f6c60dbe, Notional: 1911.151604128 + {chain: 4, addr: "0000000000000000000000001da87b114f35e1dc91f72bf57fc07a768ad40bb0", symbol: "EQZ", coinGeckoId: "equalizer", decimals: 18, price: 0.005379}, // Addr: 0x1da87b114f35e1dc91f72bf57fc07a768ad40bb0, Notional: 0.053790000000000004 + {chain: 4, addr: "0000000000000000000000001ee098cbaf1f846d5df1993f7e2d10afb35a878d", symbol: "SABLE", coinGeckoId: "sable", decimals: 18, price: 0.00467579}, // Addr: 0x1ee098cbaf1f846d5df1993f7e2d10afb35a878d, Notional: 5362.286264106417 + {chain: 4, addr: "0000000000000000000000001fa4a73a3f0133f0025378af00236f3abdee5d63", symbol: "NEAR", coinGeckoId: "wrapped-near", decimals: 18, price: 4.9}, // Addr: 0x1fa4a73a3f0133f0025378af00236f3abdee5d63, Notional: 122.77538000000001 + {chain: 4, addr: "000000000000000000000000200c234721b5e549c3693ccc93cf191f90dc2af9", symbol: "METAL", coinGeckoId: "drunk-robots", decimals: 18, price: 0.0122432}, // Addr: 0x200c234721b5e549c3693ccc93cf191f90dc2af9, Notional: 49.78531037129011 + {chain: 4, addr: "0000000000000000000000002170ed0880ac9a755fd29b2688956bd959f933f8", symbol: "ETH", coinGeckoId: "weth", decimals: 18, price: 3332.06}, // Addr: 0x2170ed0880ac9a755fd29b2688956bd959f933f8, Notional: 196720.653326528 + {chain: 4, addr: "00000000000000000000000021f9b5b2626603e3f40bfc13d01afb8c431d382f", symbol: "ZINU", coinGeckoId: "zombie-inu", decimals: 9, price: 4.5949e-11}, // Addr: 0x21f9b5b2626603e3f40bfc13d01afb8c431d382f, Notional: 0.3179844103671198 + {chain: 4, addr: "00000000000000000000000022168882276e5d5e1da694343b41dd7726eeb288", symbol: "WSB", coinGeckoId: "wall-street-bets-dapp", decimals: 18, price: 0.0001719}, // Addr: 0x22168882276e5d5e1da694343b41dd7726eeb288, Notional: 0.7645969674552691 + {chain: 4, addr: "0000000000000000000000002222227e22102fe3322098e4cbfe18cfebd57c95", symbol: "TLM", coinGeckoId: "alien-worlds", decimals: 4, price: 0.01328616}, // Addr: 0x2222227e22102fe3322098e4cbfe18cfebd57c95, Notional: 11.986773552 + {chain: 4, addr: "0000000000000000000000002235e79086dd23135119366da45851c741874e5b", symbol: "CREDI", coinGeckoId: "credefi", decimals: 18, price: 0.01493437}, // Addr: 0x2235e79086dd23135119366da45851c741874e5b, Notional: 38.97931554574567 + {chain: 4, addr: "0000000000000000000000002326c7395d02a8c89a9d7a0b0c1cf159d49ce51c", symbol: "TBAC", coinGeckoId: "blockaura", decimals: 8, price: 0.00414222}, // Addr: 0x2326c7395d02a8c89a9d7a0b0c1cf159d49ce51c, Notional: 0.0021953766000000004 + {chain: 4, addr: "00000000000000000000000023396cf899ca06c4472205fc903bdb4de249d6fc", symbol: "UST", coinGeckoId: "wrapped-ust", decimals: 18, price: 0.01958015}, // Addr: 0x23396cf899ca06c4472205fc903bdb4de249d6fc, Notional: 1.086284074423701 + {chain: 4, addr: "00000000000000000000000023e8a70534308a4aaf76fb8c32ec13d17a3bd89e", symbol: "lUSD", coinGeckoId: "lusd", decimals: 18, price: 0.00003213}, // Addr: 0x23e8a70534308a4aaf76fb8c32ec13d17a3bd89e, Notional: 227.48831459811453 + {chain: 4, addr: "0000000000000000000000002416092f143378750bb29b79ed961ab195cceea5", symbol: "ezETH", coinGeckoId: "renzo-restaked-eth", decimals: 18, price: 3426.84}, // Addr: 0x2416092f143378750bb29b79ed961ab195cceea5, Notional: 59.4585525456 + {chain: 4, addr: "000000000000000000000000245d9f531757f83064ad808b4c9b220c703a4934", symbol: "GODE", coinGeckoId: "gode-chain", decimals: 6, price: 0.00038819}, // Addr: 0x245d9f531757f83064ad808b4c9b220c703a4934, Notional: 0.00021350450000000003 + {chain: 4, addr: "000000000000000000000000250632378e573c6be1ac2f97fcdf00515d0aa91b", symbol: "BETH", coinGeckoId: "binance-eth", decimals: 18, price: 3533.75}, // Addr: 0x250632378e573c6be1ac2f97fcdf00515d0aa91b, Notional: 700.9609400749999 {chain: 4, addr: "0000000000000000000000002541be91fe0d220ffcbe65f11d88217a87a43bda", symbol: "$Lordz", coinGeckoId: "meme-lordz", decimals: 9, price: 0.00243802}, // Addr: 0x2541be91fe0d220ffcbe65f11d88217a87a43bda, Notional: 0.00243802 - {chain: 4, addr: "0000000000000000000000002598c30330d5771ae9f983979209486ae26de875", symbol: "AI", coinGeckoId: "any-inu", decimals: 18, price: 0.00000789}, // Addr: 0x2598c30330d5771ae9f983979209486ae26de875, Notional: 3967.025079260459 - {chain: 4, addr: "00000000000000000000000025a528af62e56512a19ce8c3cab427807c28cc19", symbol: "FORM", coinGeckoId: "formation-fi", decimals: 18, price: 0.00068998}, // Addr: 0x25a528af62e56512a19ce8c3cab427807c28cc19, Notional: 1.1611931122562145 - {chain: 4, addr: "00000000000000000000000025b24b3c47918b7962b3e49c4f468367f73cc0e0", symbol: "AXL", coinGeckoId: "axl-inu", decimals: 18, price: 0.00002219}, // Addr: 0x25b24b3c47918b7962b3e49c4f468367f73cc0e0, Notional: 0.2219 - {chain: 4, addr: "00000000000000000000000025d887ce7a35172c62febfd67a1856f20faebb00", symbol: "PEPE", coinGeckoId: "pepe", decimals: 18, price: 0.00002001}, // Addr: 0x25d887ce7a35172c62febfd67a1856f20faebb00, Notional: 52.51204637429548 - {chain: 4, addr: "00000000000000000000000027ae27110350b98d564b9a3eed31baebc82d878d", symbol: "CUMMIES", coinGeckoId: "cumrocket", decimals: 18, price: 0.00518489}, // Addr: 0x27ae27110350b98d564b9a3eed31baebc82d878d, Notional: 6.456741517810113 - {chain: 4, addr: "0000000000000000000000002859e4544c4bb03966803b044a93563bd2d0dd4d", symbol: "SHIB", coinGeckoId: "binance-peg-shib", decimals: 18, price: 0.00002863}, // Addr: 0x2859e4544c4bb03966803b044a93563bd2d0dd4d, Notional: 3681.791244864804 - {chain: 4, addr: "0000000000000000000000002a48ece377b87ce941406657b9278b4459595e06", symbol: "LunaT", coinGeckoId: "lunatics", decimals: 9, price: 4.67163e-7}, // Addr: 0x2a48ece377b87ce941406657b9278b4459595e06, Notional: 0.6761527018941069 - {chain: 4, addr: "0000000000000000000000002ab0e9e4ee70fff1fb9d67031e44f6410170d00e", symbol: "bXEN", coinGeckoId: "xen-crypto-bsc", decimals: 18, price: 8.34009e-10}, // Addr: 0x2ab0e9e4ee70fff1fb9d67031e44f6410170d00e, Notional: 1.8397435483231404 - {chain: 4, addr: "0000000000000000000000002c717059b366714d267039af8f59125cadce6d8c", symbol: "MHUNT", coinGeckoId: "metashooter", decimals: 18, price: 0.00042042}, // Addr: 0x2c717059b366714d267039af8f59125cadce6d8c, Notional: 0.0149490530305116 - {chain: 4, addr: "0000000000000000000000002cd96e8c3ff6b5e01169f6e3b61d28204e7810bb", symbol: "LBlock", coinGeckoId: "lucky-block", decimals: 9, price: 0.00001747}, // Addr: 0x2cd96e8c3ff6b5e01169f6e3b61d28204e7810bb, Notional: 891.5474422905502 - {chain: 4, addr: "0000000000000000000000002d6f3dc5b202ccd91db114b592872bca32a7e292", symbol: "SAUDISHIB", coinGeckoId: "saudi-shiba-inu", decimals: 8, price: 1.0687e-11}, // Addr: 0x2d6f3dc5b202ccd91db114b592872bca32a7e292, Notional: 1.5333488939358308 + {chain: 4, addr: "0000000000000000000000002598c30330d5771ae9f983979209486ae26de875", symbol: "AI", coinGeckoId: "any-inu", decimals: 18, price: 0.00000937}, // Addr: 0x2598c30330d5771ae9f983979209486ae26de875, Notional: 4716.837470913522 + {chain: 4, addr: "00000000000000000000000025a528af62e56512a19ce8c3cab427807c28cc19", symbol: "FORM", coinGeckoId: "formation-fi", decimals: 18, price: 0.0006149}, // Addr: 0x25a528af62e56512a19ce8c3cab427807c28cc19, Notional: 1.034838176072272 + {chain: 4, addr: "00000000000000000000000025b24b3c47918b7962b3e49c4f468367f73cc0e0", symbol: "AXL", coinGeckoId: "axl-inu", decimals: 18, price: 0.00001746}, // Addr: 0x25b24b3c47918b7962b3e49c4f468367f73cc0e0, Notional: 0.17459999999999998 + {chain: 4, addr: "00000000000000000000000025d887ce7a35172c62febfd67a1856f20faebb00", symbol: "PEPE", coinGeckoId: "pepe", decimals: 18, price: 0.00001994}, // Addr: 0x25d887ce7a35172c62febfd67a1856f20faebb00, Notional: 52.32834606214152 + {chain: 4, addr: "00000000000000000000000027ae27110350b98d564b9a3eed31baebc82d878d", symbol: "CUMMIES", coinGeckoId: "cumrocket", decimals: 18, price: 0.0044627}, // Addr: 0x27ae27110350b98d564b9a3eed31baebc82d878d, Notional: 5.557398589272133 + {chain: 4, addr: "0000000000000000000000002859e4544c4bb03966803b044a93563bd2d0dd4d", symbol: "SHIB", coinGeckoId: "binance-peg-shib", decimals: 18, price: 0.00002122}, // Addr: 0x2859e4544c4bb03966803b044a93563bd2d0dd4d, Notional: 3328.272524394019 + {chain: 4, addr: "0000000000000000000000002a48ece377b87ce941406657b9278b4459595e06", symbol: "LunaT", coinGeckoId: "lunatics", decimals: 9, price: 4.73291e-7}, // Addr: 0x2a48ece377b87ce941406657b9278b4459595e06, Notional: 0.6850221195432081 + {chain: 4, addr: "0000000000000000000000002ab0e9e4ee70fff1fb9d67031e44f6410170d00e", symbol: "bXEN", coinGeckoId: "xen-crypto-bsc", decimals: 18, price: 9.05813e-10}, // Addr: 0x2ab0e9e4ee70fff1fb9d67031e44f6410170d00e, Notional: 1.9981362584063587 + {chain: 4, addr: "0000000000000000000000002c717059b366714d267039af8f59125cadce6d8c", symbol: "MHUNT", coinGeckoId: "metashooter", decimals: 18, price: 0.00028232}, // Addr: 0x2c717059b366714d267039af8f59125cadce6d8c, Notional: 0.0100385725026736 + {chain: 4, addr: "0000000000000000000000002cd96e8c3ff6b5e01169f6e3b61d28204e7810bb", symbol: "LBlock", coinGeckoId: "lucky-block", decimals: 9, price: 0.00001576}, // Addr: 0x2cd96e8c3ff6b5e01169f6e3b61d28204e7810bb, Notional: 804.2809210360087 + {chain: 4, addr: "0000000000000000000000002d6f3dc5b202ccd91db114b592872bca32a7e292", symbol: "SAUDISHIB", coinGeckoId: "saudi-shiba-inu", decimals: 8, price: 1.0022e-11}, // Addr: 0x2d6f3dc5b202ccd91db114b592872bca32a7e292, Notional: 1.4379360545545896 {chain: 4, addr: "0000000000000000000000002d94172436d869c1e3c094bead272508fab0d9e3", symbol: "RCG", coinGeckoId: "recharge", decimals: 18, price: 0.00950839}, // Addr: 0x2d94172436d869c1e3c094bead272508fab0d9e3, Notional: 0.0093182222 - {chain: 4, addr: "0000000000000000000000002dff88a56767223a5529ea5960da7a3f5f766406", symbol: "ID", coinGeckoId: "space-id", decimals: 18, price: 0.552022}, // Addr: 0x2dff88a56767223a5529ea5960da7a3f5f766406, Notional: 1838.45151845836 + {chain: 4, addr: "0000000000000000000000002dff88a56767223a5529ea5960da7a3f5f766406", symbol: "ID", coinGeckoId: "space-id", decimals: 18, price: 0.434765}, // Addr: 0x2dff88a56767223a5529ea5960da7a3f5f766406, Notional: 1447.9393473857 {chain: 4, addr: "0000000000000000000000002f25d402829ca4085b8ea4d3bc68bf203f5a9fab", symbol: "Eagon", coinGeckoId: "eagonswap-token", decimals: 18, price: 0.00007782}, // Addr: 0x2f25d402829ca4085b8ea4d3bc68bf203f5a9fab, Notional: 1.6413002011647486 - {chain: 4, addr: "0000000000000000000000002f29bc0ffaf9bff337b31cbe6cb5fb3bf12e5840", symbol: "DOLA", coinGeckoId: "dola-usd", decimals: 18, price: 0.99265}, // Addr: 0x2f29bc0ffaf9bff337b31cbe6cb5fb3bf12e5840, Notional: 296.425727095113 - {chain: 4, addr: "0000000000000000000000002ff0b946a6782190c4fe5d4971cfe79f0b6e4df2", symbol: "MYST", coinGeckoId: "mysterium", decimals: 18, price: 0.233114}, // Addr: 0x2ff0b946a6782190c4fe5d4971cfe79f0b6e4df2, Notional: 0.23317799678641998 - {chain: 4, addr: "0000000000000000000000003019bf2a2ef8040c242c9a4c5c4bd4c81678b2a1", symbol: "GMT", coinGeckoId: "stepn", decimals: 8, price: 0.207966}, // Addr: 0x3019bf2a2ef8040c242c9a4c5c4bd4c81678b2a1, Notional: 347.49386292923873 - {chain: 4, addr: "00000000000000000000000030842a9c941d9de3af582c41ad12b11d776ba69e", symbol: "GPT", coinGeckoId: "qna3-ai", decimals: 18, price: 0.069379}, // Addr: 0x30842a9c941d9de3af582c41ad12b11d776ba69e, Notional: 134967.2844660411 - {chain: 4, addr: "00000000000000000000000031471e0791fcdbe82fbf4c44943255e923f1b794", symbol: "PVU", coinGeckoId: "plant-vs-undead-token", decimals: 18, price: 0.00125696}, // Addr: 0x31471e0791fcdbe82fbf4c44943255e923f1b794, Notional: 0.000012569599999999999 - {chain: 4, addr: "000000000000000000000000317eb4ad9cfac6232f0046831322e895507bcbeb", symbol: "TDX", coinGeckoId: "tidex-token", decimals: 18, price: 0.02571214}, // Addr: 0x317eb4ad9cfac6232f0046831322e895507bcbeb, Notional: 23.984203864703428 - {chain: 4, addr: "00000000000000000000000031d0a7ada4d4c131eb612db48861211f63e57610", symbol: "START", coinGeckoId: "bscstarter", decimals: 18, price: 0.056166}, // Addr: 0x31d0a7ada4d4c131eb612db48861211f63e57610, Notional: 0.0056166 - {chain: 4, addr: "000000000000000000000000323665443cef804a3b5206103304bd4872ea4253", symbol: "USDV", coinGeckoId: "verified-usd-foundation-usdv", decimals: 6, price: 0.999897}, // Addr: 0x323665443cef804a3b5206103304bd4872ea4253, Notional: 21.373798272000002 - {chain: 4, addr: "0000000000000000000000003419875b4d3bca7f3fdda2db7a476a79fd31b4fe", symbol: "DZHV", coinGeckoId: "dizzyhavoc", decimals: 18, price: 0.00084136}, // Addr: 0x3419875b4d3bca7f3fdda2db7a476a79fd31b4fe, Notional: 1.1460318329309407 - {chain: 4, addr: "000000000000000000000000352cb5e19b12fc216548a2677bd0fce83bae434b", symbol: "BTT", coinGeckoId: "bittorrent", decimals: 18, price: 0.00000136}, // Addr: 0x352cb5e19b12fc216548a2677bd0fce83bae434b, Notional: 0.0610164 - {chain: 4, addr: "00000000000000000000000035bedbf9291b22218a0da863170dcc9329ef2563", symbol: "TAP", coinGeckoId: "tap-fantasy", decimals: 18, price: 0.00094146}, // Addr: 0x35bedbf9291b22218a0da863170dcc9329ef2563, Notional: 43.69567313792583 - {chain: 4, addr: "000000000000000000000000368eb5efdca39126e8e76aae5187166de7c2766c", symbol: "CST", coinGeckoId: "cryptoskates", decimals: 18, price: 0.00012297}, // Addr: 0x368eb5efdca39126e8e76aae5187166de7c2766c, Notional: 0.0670393145379192 - {chain: 4, addr: "000000000000000000000000371c7ec6d8039ff7933a2aa28eb827ffe1f52f07", symbol: "JOE", coinGeckoId: "joe", decimals: 18, price: 0.530655}, // Addr: 0x371c7ec6d8039ff7933a2aa28eb827ffe1f52f07, Notional: 6.9370400117319 - {chain: 4, addr: "000000000000000000000000373e768f79c820aa441540d254dca6d045c6d25b", symbol: "DERC", coinGeckoId: "derace", decimals: 18, price: 0.10982}, // Addr: 0x373e768f79c820aa441540d254dca6d045c6d25b, Notional: 0.5504597154642 - {chain: 4, addr: "00000000000000000000000037fe635d1e25b2f7276c1b9dbbcc7b087f80c050", symbol: "OciCat", coinGeckoId: "ocicat-token", decimals: 18, price: 1.066e-9}, // Addr: 0x37fe635d1e25b2f7276c1b9dbbcc7b087f80c050, Notional: 152.031820421 - {chain: 4, addr: "00000000000000000000000038e382f74dfb84608f3c1f10187f6bef5951de93", symbol: "MUBI", coinGeckoId: "multibit", decimals: 18, price: 0.03520993}, // Addr: 0x38e382f74dfb84608f3c1f10187f6bef5951de93, Notional: 0.11870494046541341 - {chain: 4, addr: "00000000000000000000000039ae8eefb05138f418bb27659c21632dc1ddab10", symbol: "KAI", coinGeckoId: "kardiachain", decimals: 18, price: 0.00291829}, // Addr: 0x39ae8eefb05138f418bb27659c21632dc1ddab10, Notional: 194.03004261072144 - {chain: 4, addr: "0000000000000000000000003c1748d647e6a56b37b66fcd2b5626d0461d3aa0", symbol: "DNXC", coinGeckoId: "dinox", decimals: 18, price: 0.00090603}, // Addr: 0x3c1748d647e6a56b37b66fcd2b5626d0461d3aa0, Notional: 24.949926228426442 - {chain: 4, addr: "0000000000000000000000003ee2200efb3400fabb9aacf31297cbdd1d435d47", symbol: "ADA", coinGeckoId: "binance-peg-cardano", decimals: 18, price: 1.077}, // Addr: 0x3ee2200efb3400fabb9aacf31297cbdd1d435d47, Notional: 4859.3819534245795 - {chain: 4, addr: "00000000000000000000000040c8225329bd3e28a043b029e0d07a5344d2c27c", symbol: "AOG", coinGeckoId: "ageofgods", decimals: 18, price: 0.00400044}, // Addr: 0x40c8225329bd3e28a043b029e0d07a5344d2c27c, Notional: 1.3278018200955757 - {chain: 4, addr: "00000000000000000000000041065e3428188ba6eb27fbdde8526ae3af8e3830", symbol: "SWASH", coinGeckoId: "swash", decimals: 18, price: 0.00566342}, // Addr: 0x41065e3428188ba6eb27fbdde8526ae3af8e3830, Notional: 80.01917367861618 - {chain: 4, addr: "0000000000000000000000004268b8f0b87b6eae5d897996e6b845ddbd99adf3", symbol: "axlUSDC", coinGeckoId: "axlusdc", decimals: 6, price: 0.99899}, // Addr: 0x4268b8f0b87b6eae5d897996e6b845ddbd99adf3, Notional: 24.578764349860002 - {chain: 4, addr: "00000000000000000000000042981d0bfbaf196529376ee702f2a9eb9092fcb5", symbol: "SFM", coinGeckoId: "safemoon-2", decimals: 9, price: 0.00006887}, // Addr: 0x42981d0bfbaf196529376ee702f2a9eb9092fcb5, Notional: 0.4558610918198673 - {chain: 4, addr: "00000000000000000000000042c95788f791a2be3584446854c8d9bb01be88a9", symbol: "HBR", coinGeckoId: "harbor-3", decimals: 18, price: 0.01819869}, // Addr: 0x42c95788f791a2be3584446854c8d9bb01be88a9, Notional: 613986.7032241082 - {chain: 4, addr: "0000000000000000000000004338665cbb7b2485a8855a139b75d5e34ab0db94", symbol: "LTC", coinGeckoId: "binance-peg-litecoin", decimals: 18, price: 119.5}, // Addr: 0x4338665cbb7b2485a8855a139b75d5e34ab0db94, Notional: 1204.921629705 - {chain: 4, addr: "00000000000000000000000044c99ca267c2b2646ceec72e898273085ab87ca5", symbol: "RPTR", coinGeckoId: "raptor-finance-2", decimals: 18, price: 0.00012071}, // Addr: 0x44c99ca267c2b2646ceec72e898273085ab87ca5, Notional: 350.93048817027346 - {chain: 4, addr: "00000000000000000000000044ec807ce2f4a6f2737a92e985f318d035883e47", symbol: "HFT", coinGeckoId: "hashflow", decimals: 18, price: 0.244105}, // Addr: 0x44ec807ce2f4a6f2737a92e985f318d035883e47, Notional: 0.93492215 - {chain: 4, addr: "00000000000000000000000045f7967926e95fd161e56ed66b663c9114c5226f", symbol: "TOKO", coinGeckoId: "toko", decimals: 18, price: 0.00071551}, // Addr: 0x45f7967926e95fd161e56ed66b663c9114c5226f, Notional: 0.35134027564679343 - {chain: 4, addr: "0000000000000000000000004691937a7508860f876c9c0a2a617e7d9e945d4b", symbol: "WOO", coinGeckoId: "woo-network", decimals: 18, price: 0.294151}, // Addr: 0x4691937a7508860f876c9c0a2a617e7d9e945d4b, Notional: 3.0662986494282998 - {chain: 4, addr: "00000000000000000000000046d502fac9aea7c5bc7b13c8ec9d02378c33d36f", symbol: "WSPP", coinGeckoId: "wolfsafepoorpeople", decimals: 0, price: 1.6893e-11}, // Addr: 0x46d502fac9aea7c5bc7b13c8ec9d02378c33d36f, Notional: 25.991505742892723 - {chain: 4, addr: "000000000000000000000000477bc8d23c634c154061869478bce96be6045d12", symbol: "SFUND", coinGeckoId: "seedify-fund", decimals: 18, price: 1.96}, // Addr: 0x477bc8d23c634c154061869478bce96be6045d12, Notional: 0.0392 - {chain: 4, addr: "00000000000000000000000047bead2563dcbf3bf2c9407fea4dc236faba485a", symbol: "SXP", coinGeckoId: "swipe", decimals: 18, price: 0.425851}, // Addr: 0x47bead2563dcbf3bf2c9407fea4dc236faba485a, Notional: 1398.782661228988 - {chain: 4, addr: "000000000000000000000000482e6bd0a178f985818c5dfb9ac77918e8412fba", symbol: "ZEUM", coinGeckoId: "colizeum", decimals: 18, price: 0.00087503}, // Addr: 0x482e6bd0a178f985818c5dfb9ac77918e8412fba, Notional: 0.105739730275387 + {chain: 4, addr: "0000000000000000000000002f29bc0ffaf9bff337b31cbe6cb5fb3bf12e5840", symbol: "DOLA", coinGeckoId: "dola-usd", decimals: 18, price: 0.986265}, // Addr: 0x2f29bc0ffaf9bff337b31cbe6cb5fb3bf12e5840, Notional: 294.51903463805127 + {chain: 4, addr: "0000000000000000000000002ff0b946a6782190c4fe5d4971cfe79f0b6e4df2", symbol: "MYST", coinGeckoId: "mysterium", decimals: 18, price: 0.220917}, // Addr: 0x2ff0b946a6782190c4fe5d4971cfe79f0b6e4df2, Notional: 0.22097764834401 + {chain: 4, addr: "0000000000000000000000003019bf2a2ef8040c242c9a4c5c4bd4c81678b2a1", symbol: "GMT", coinGeckoId: "stepn", decimals: 8, price: 0.151428}, // Addr: 0x3019bf2a2ef8040c242c9a4c5c4bd4c81678b2a1, Notional: 253.02357440951292 + {chain: 4, addr: "00000000000000000000000030842a9c941d9de3af582c41ad12b11d776ba69e", symbol: "GPT", coinGeckoId: "qna3-ai", decimals: 18, price: 0.059626}, // Addr: 0x30842a9c941d9de3af582c41ad12b11d776ba69e, Notional: 115991.54333030155 + {chain: 4, addr: "00000000000000000000000031471e0791fcdbe82fbf4c44943255e923f1b794", symbol: "PVU", coinGeckoId: "plant-vs-undead-token", decimals: 18, price: 0.00129469}, // Addr: 0x31471e0791fcdbe82fbf4c44943255e923f1b794, Notional: 0.000012946900000000001 + {chain: 4, addr: "000000000000000000000000317eb4ad9cfac6232f0046831322e895507bcbeb", symbol: "TDX", coinGeckoId: "tidex-token", decimals: 18, price: 0.01371324}, // Addr: 0x317eb4ad9cfac6232f0046831322e895507bcbeb, Notional: 12.791667430466916 + {chain: 4, addr: "00000000000000000000000031d0a7ada4d4c131eb612db48861211f63e57610", symbol: "START", coinGeckoId: "bscstarter", decimals: 18, price: 0.407304}, // Addr: 0x31d0a7ada4d4c131eb612db48861211f63e57610, Notional: 0.0407304 + {chain: 4, addr: "000000000000000000000000323665443cef804a3b5206103304bd4872ea4253", symbol: "USDV", coinGeckoId: "verified-usd-foundation-usdv", decimals: 6, price: 0.994502}, // Addr: 0x323665443cef804a3b5206103304bd4872ea4253, Notional: 21.258474752 + {chain: 4, addr: "0000000000000000000000003419875b4d3bca7f3fdda2db7a476a79fd31b4fe", symbol: "DZHV", coinGeckoId: "dizzyhavoc", decimals: 18, price: 0.00053758}, // Addr: 0x3419875b4d3bca7f3fdda2db7a476a79fd31b4fe, Notional: 0.7322475429626023 + {chain: 4, addr: "000000000000000000000000352cb5e19b12fc216548a2677bd0fce83bae434b", symbol: "BTT", coinGeckoId: "bittorrent", decimals: 18, price: 0.00000107}, // Addr: 0x352cb5e19b12fc216548a2677bd0fce83bae434b, Notional: 0.048005549999999994 + {chain: 4, addr: "00000000000000000000000035bedbf9291b22218a0da863170dcc9329ef2563", symbol: "TAP", coinGeckoId: "tap-fantasy", decimals: 18, price: 0.00072188}, // Addr: 0x35bedbf9291b22218a0da863170dcc9329ef2563, Notional: 33.50437886347365 + {chain: 4, addr: "000000000000000000000000368eb5efdca39126e8e76aae5187166de7c2766c", symbol: "CST", coinGeckoId: "cryptoskates", decimals: 18, price: 0.00015159}, // Addr: 0x368eb5efdca39126e8e76aae5187166de7c2766c, Notional: 0.08264202399612239 + {chain: 4, addr: "000000000000000000000000371c7ec6d8039ff7933a2aa28eb827ffe1f52f07", symbol: "JOE", coinGeckoId: "joe", decimals: 18, price: 0.363725}, // Addr: 0x371c7ec6d8039ff7933a2aa28eb827ffe1f52f07, Notional: 4.7548310640005 + {chain: 4, addr: "000000000000000000000000373e768f79c820aa441540d254dca6d045c6d25b", symbol: "DERC", coinGeckoId: "derace", decimals: 18, price: 0.117109}, // Addr: 0x373e768f79c820aa441540d254dca6d045c6d25b, Notional: 0.5869949628327901 + {chain: 4, addr: "00000000000000000000000037fe635d1e25b2f7276c1b9dbbcc7b087f80c050", symbol: "OciCat", coinGeckoId: "ocicat-token", decimals: 18, price: 1.28e-9}, // Addr: 0x37fe635d1e25b2f7276c1b9dbbcc7b087f80c050, Notional: 182.55227968 + {chain: 4, addr: "00000000000000000000000038e382f74dfb84608f3c1f10187f6bef5951de93", symbol: "MUBI", coinGeckoId: "multibit", decimals: 18, price: 0.02101726}, // Addr: 0x38e382f74dfb84608f3c1f10187f6bef5951de93, Notional: 4.072611476414393 + {chain: 4, addr: "00000000000000000000000039ae8eefb05138f418bb27659c21632dc1ddab10", symbol: "KAI", coinGeckoId: "kardiachain", decimals: 18, price: 0.00208042}, // Addr: 0x39ae8eefb05138f418bb27659c21632dc1ddab10, Notional: 138.32209316010304 + {chain: 4, addr: "0000000000000000000000003c1748d647e6a56b37b66fcd2b5626d0461d3aa0", symbol: "DNXC", coinGeckoId: "dinox", decimals: 18, price: 0.00065944}, // Addr: 0x3c1748d647e6a56b37b66fcd2b5626d0461d3aa0, Notional: 18.159420054604738 + {chain: 4, addr: "0000000000000000000000003ee2200efb3400fabb9aacf31297cbdd1d435d47", symbol: "ADA", coinGeckoId: "binance-peg-cardano", decimals: 18, price: 0.844277}, // Addr: 0x3ee2200efb3400fabb9aacf31297cbdd1d435d47, Notional: 3827.5216072363514 + {chain: 4, addr: "00000000000000000000000040c8225329bd3e28a043b029e0d07a5344d2c27c", symbol: "AOG", coinGeckoId: "ageofgods", decimals: 18, price: 0.00768853}, // Addr: 0x40c8225329bd3e28a043b029e0d07a5344d2c27c, Notional: 2.5519303196296996 + {chain: 4, addr: "00000000000000000000000041065e3428188ba6eb27fbdde8526ae3af8e3830", symbol: "SWASH", coinGeckoId: "swash", decimals: 18, price: 0.00542182}, // Addr: 0x41065e3428188ba6eb27fbdde8526ae3af8e3830, Notional: 76.60557688361358 + {chain: 4, addr: "0000000000000000000000004268b8f0b87b6eae5d897996e6b845ddbd99adf3", symbol: "axlUSDC", coinGeckoId: "axlusdc", decimals: 6, price: 0.998424}, // Addr: 0x4268b8f0b87b6eae5d897996e6b845ddbd99adf3, Notional: 24.564838704336 + {chain: 4, addr: "00000000000000000000000042981d0bfbaf196529376ee702f2a9eb9092fcb5", symbol: "SFM", coinGeckoId: "safemoon-2", decimals: 9, price: 0.00005061}, // Addr: 0x42981d0bfbaf196529376ee702f2a9eb9092fcb5, Notional: 0.3349953514883619 + {chain: 4, addr: "00000000000000000000000042c95788f791a2be3584446854c8d9bb01be88a9", symbol: "HBR", coinGeckoId: "harbor-3", decimals: 18, price: 0.0151693}, // Addr: 0x42c95788f791a2be3584446854c8d9bb01be88a9, Notional: 412621.85224091104 + {chain: 4, addr: "0000000000000000000000004338665cbb7b2485a8855a139b75d5e34ab0db94", symbol: "LTC", coinGeckoId: "binance-peg-litecoin", decimals: 18, price: 103.42}, // Addr: 0x4338665cbb7b2485a8855a139b75d5e34ab0db94, Notional: 1042.7865685698 + {chain: 4, addr: "00000000000000000000000044c99ca267c2b2646ceec72e898273085ab87ca5", symbol: "RPTR", coinGeckoId: "raptor-finance-2", decimals: 18, price: 0.00013656}, // Addr: 0x44c99ca267c2b2646ceec72e898273085ab87ca5, Notional: 344.43417265174145 + {chain: 4, addr: "00000000000000000000000044ec807ce2f4a6f2737a92e985f318d035883e47", symbol: "HFT", coinGeckoId: "hashflow", decimals: 18, price: 0.200533}, // Addr: 0x44ec807ce2f4a6f2737a92e985f318d035883e47, Notional: 0.7680413899999999 + {chain: 4, addr: "00000000000000000000000045f7967926e95fd161e56ed66b663c9114c5226f", symbol: "TOKO", coinGeckoId: "toko", decimals: 18, price: 0.00072278}, // Addr: 0x45f7967926e95fd161e56ed66b663c9114c5226f, Notional: 0.3549100982963052 + {chain: 4, addr: "0000000000000000000000004691937a7508860f876c9c0a2a617e7d9e945d4b", symbol: "WOO", coinGeckoId: "woo-network", decimals: 18, price: 0.207659}, // Addr: 0x4691937a7508860f876c9c0a2a617e7d9e945d4b, Notional: 2.1646858628447 + {chain: 4, addr: "00000000000000000000000046d502fac9aea7c5bc7b13c8ec9d02378c33d36f", symbol: "WSPP", coinGeckoId: "wolfsafepoorpeople", decimals: 0, price: 1.3351e-11}, // Addr: 0x46d502fac9aea7c5bc7b13c8ec9d02378c33d36f, Notional: 20.54179797391587 + {chain: 4, addr: "000000000000000000000000477bc8d23c634c154061869478bce96be6045d12", symbol: "SFUND", coinGeckoId: "seedify-fund", decimals: 18, price: 1.3}, // Addr: 0x477bc8d23c634c154061869478bce96be6045d12, Notional: 0.026000000000000002 + {chain: 4, addr: "00000000000000000000000047bead2563dcbf3bf2c9407fea4dc236faba485a", symbol: "SXP", coinGeckoId: "swipe", decimals: 18, price: 0.32693}, // Addr: 0x47bead2563dcbf3bf2c9407fea4dc236faba485a, Notional: 1073.8592029503113 + {chain: 4, addr: "000000000000000000000000482e6bd0a178f985818c5dfb9ac77918e8412fba", symbol: "ZEUM", coinGeckoId: "colizeum", decimals: 18, price: 0.00085967}, // Addr: 0x482e6bd0a178f985818c5dfb9ac77918e8412fba, Notional: 0.103883608477243 {chain: 4, addr: "0000000000000000000000004841181ae4079072ebe83a29b718388a387169e3", symbol: "SUI", coinGeckoId: "salmonation", decimals: 9, price: 0.00391361}, // Addr: 0x4841181ae4079072ebe83a29b718388a387169e3, Notional: 47.606875480271036 - {chain: 4, addr: "000000000000000000000000489580eb70a50515296ef31e8179ff3e77e24965", symbol: "RADAR", coinGeckoId: "dappradar", decimals: 18, price: 0.00557818}, // Addr: 0x489580eb70a50515296ef31e8179ff3e77e24965, Notional: 16.030287872058032 - {chain: 4, addr: "0000000000000000000000004a2c860cec6471b9f5f5a336eb4f38bb21683c98", symbol: "GST", coinGeckoId: "green-satoshi-token-bsc", decimals: 8, price: 0.00585842}, // Addr: 0x4a2c860cec6471b9f5f5a336eb4f38bb21683c98, Notional: 578.0132808113498 - {chain: 4, addr: "0000000000000000000000004aac18de824ec1b553dbf342829834e4ff3f7a9f", symbol: "ANCHOR", coinGeckoId: "anchorswap", decimals: 18, price: 0.00008225}, // Addr: 0x4aac18de824ec1b553dbf342829834e4ff3f7a9f, Notional: 0.0253461228205325 - {chain: 4, addr: "0000000000000000000000004afc8c2be6a0783ea16e16066fde140d15979296", symbol: "HARE", coinGeckoId: "hare-token", decimals: 9, price: 2.9e-17}, // Addr: 0x4afc8c2be6a0783ea16e16066fde140d15979296, Notional: 2.6100000000000005e-13 - {chain: 4, addr: "0000000000000000000000004b0f1812e5df2a09796481ff14017e6005508003", symbol: "TWT", coinGeckoId: "trust-wallet-token", decimals: 18, price: 1.19}, // Addr: 0x4b0f1812e5df2a09796481ff14017e6005508003, Notional: 11045.491506863798 - {chain: 4, addr: "0000000000000000000000004b5c23cac08a567ecf0c1ffca8372a45a5d33743", symbol: "FARM", coinGeckoId: "harvest-finance", decimals: 18, price: 60.07}, // Addr: 0x4b5c23cac08a567ecf0c1ffca8372a45a5d33743, Notional: 0.9870083679 - {chain: 4, addr: "0000000000000000000000004b5decb9327b4d511a58137a1ade61434aacdd43", symbol: "PKN", coinGeckoId: "poken", decimals: 18, price: 0.00015725}, // Addr: 0x4b5decb9327b4d511a58137a1ade61434aacdd43, Notional: 7.918766607562747 - {chain: 4, addr: "0000000000000000000000004b8285ab433d8f69cb48d5ad62b415ed1a221e4f", symbol: "MCRT", coinGeckoId: "magiccraft", decimals: 9, price: 0.00120617}, // Addr: 0x4b8285ab433d8f69cb48d5ad62b415ed1a221e4f, Notional: 21013.834719358045 - {chain: 4, addr: "0000000000000000000000004ba0057f784858a48fe351445c672ff2a3d43515", symbol: "KALM", coinGeckoId: "kalmar", decimals: 18, price: 0.01281804}, // Addr: 0x4ba0057f784858a48fe351445c672ff2a3d43515, Notional: 608.0691598651674 - {chain: 4, addr: "0000000000000000000000004d2d32d8652058bf98c772953e1df5c5c85d9f45", symbol: "DAO", coinGeckoId: "dao-maker", decimals: 18, price: 0.423369}, // Addr: 0x4d2d32d8652058bf98c772953e1df5c5c85d9f45, Notional: 2828481.216476622 - {chain: 4, addr: "0000000000000000000000004da996c5fe84755c80e108cf96fe705174c5e36a", symbol: "WOW", coinGeckoId: "wowswap", decimals: 18, price: 0.082543}, // Addr: 0x4da996c5fe84755c80e108cf96fe705174c5e36a, Notional: 0.59879810344368 - {chain: 4, addr: "0000000000000000000000004f39c3319188a723003670c3f9b9e7ef991e52f3", symbol: "FIGHT", coinGeckoId: "crypto-fight-club", decimals: 18, price: 0.0001609}, // Addr: 0x4f39c3319188a723003670c3f9b9e7ef991e52f3, Notional: 0.0004827 - {chain: 4, addr: "0000000000000000000000005012c90f14d190607662ca8344120812aaa2639d", symbol: "PNP", coinGeckoId: "penpie", decimals: 18, price: 3.11}, // Addr: 0x5012c90f14d190607662ca8344120812aaa2639d, Notional: 151.7036282248 - {chain: 4, addr: "00000000000000000000000050d809c74e0b8e49e7b4c65bb3109abe3ff4c1c1", symbol: "CUB", coinGeckoId: "cub-finance", decimals: 18, price: 0.00185108}, // Addr: 0x50d809c74e0b8e49e7b4c65bb3109abe3ff4c1c1, Notional: 0.0000227720046708 - {chain: 4, addr: "000000000000000000000000524df384bffb18c0c8f3f43d012011f8f9795579", symbol: "YAY", coinGeckoId: "yay-games", decimals: 18, price: 0.00123613}, // Addr: 0x524df384bffb18c0c8f3f43d012011f8f9795579, Notional: 0.0123613 - {chain: 4, addr: "00000000000000000000000052f24a5e03aee338da5fd9df68d2b6fae1178827", symbol: "ankrBNB", coinGeckoId: "ankr-staked-bnb", decimals: 18, price: 689.3}, // Addr: 0x52f24a5e03aee338da5fd9df68d2b6fae1178827, Notional: 1.3347191619999998 - {chain: 4, addr: "0000000000000000000000005512014efa6cd57764fa743756f7a6ce3358cc83", symbol: "EZ", coinGeckoId: "easyfi", decimals: 18, price: 0.01002764}, // Addr: 0x5512014efa6cd57764fa743756f7a6ce3358cc83, Notional: 0.0640122735377132 + {chain: 4, addr: "000000000000000000000000489580eb70a50515296ef31e8179ff3e77e24965", symbol: "RADAR", coinGeckoId: "dappradar", decimals: 18, price: 0.00530581}, // Addr: 0x489580eb70a50515296ef31e8179ff3e77e24965, Notional: 15.247564921613183 + {chain: 4, addr: "0000000000000000000000004a2c860cec6471b9f5f5a336eb4f38bb21683c98", symbol: "GST", coinGeckoId: "green-satoshi-token-bsc", decimals: 8, price: 0.00480408}, // Addr: 0x4a2c860cec6471b9f5f5a336eb4f38bb21683c98, Notional: 473.9882156076535 + {chain: 4, addr: "0000000000000000000000004aac18de824ec1b553dbf342829834e4ff3f7a9f", symbol: "ANCHOR", coinGeckoId: "anchorswap", decimals: 18, price: 0.00007946}, // Addr: 0x4aac18de824ec1b553dbf342829834e4ff3f7a9f, Notional: 0.0244863576816962 + {chain: 4, addr: "0000000000000000000000004afc8c2be6a0783ea16e16066fde140d15979296", symbol: "HARE", coinGeckoId: "hare-token", decimals: 9, price: 3.2e-17}, // Addr: 0x4afc8c2be6a0783ea16e16066fde140d15979296, Notional: 2.8800000000000004e-13 + {chain: 4, addr: "0000000000000000000000004b0f1812e5df2a09796481ff14017e6005508003", symbol: "TWT", coinGeckoId: "trust-wallet-token", decimals: 18, price: 1.19}, // Addr: 0x4b0f1812e5df2a09796481ff14017e6005508003, Notional: 11364.8084493685 + {chain: 4, addr: "0000000000000000000000004b5c23cac08a567ecf0c1ffca8372a45a5d33743", symbol: "FARM", coinGeckoId: "harvest-finance", decimals: 18, price: 46.31}, // Addr: 0x4b5c23cac08a567ecf0c1ffca8372a45a5d33743, Notional: 0.7609182207 + {chain: 4, addr: "0000000000000000000000004b5decb9327b4d511a58137a1ade61434aacdd43", symbol: "PKN", coinGeckoId: "poken", decimals: 18, price: 0.00009148}, // Addr: 0x4b5decb9327b4d511a58137a1ade61434aacdd43, Notional: 4.606733031859079 + {chain: 4, addr: "0000000000000000000000004b8285ab433d8f69cb48d5ad62b415ed1a221e4f", symbol: "MCRT", coinGeckoId: "magiccraft", decimals: 9, price: 0.00101283}, // Addr: 0x4b8285ab433d8f69cb48d5ad62b415ed1a221e4f, Notional: 18441.175151374235 + {chain: 4, addr: "0000000000000000000000004ba0057f784858a48fe351445c672ff2a3d43515", symbol: "KALM", coinGeckoId: "kalmar", decimals: 18, price: 0.01386537}, // Addr: 0x4ba0057f784858a48fe351445c672ff2a3d43515, Notional: 657.7529705883034 + {chain: 4, addr: "0000000000000000000000004d2d32d8652058bf98c772953e1df5c5c85d9f45", symbol: "DAO", coinGeckoId: "dao-maker", decimals: 18, price: 0.325357}, // Addr: 0x4d2d32d8652058bf98c772953e1df5c5c85d9f45, Notional: 2203255.2408634466 + {chain: 4, addr: "0000000000000000000000004da996c5fe84755c80e108cf96fe705174c5e36a", symbol: "WOW", coinGeckoId: "wowswap", decimals: 18, price: 0.066075}, // Addr: 0x4da996c5fe84755c80e108cf96fe705174c5e36a, Notional: 0.47933301049199994 + {chain: 4, addr: "0000000000000000000000004f39c3319188a723003670c3f9b9e7ef991e52f3", symbol: "FIGHT", coinGeckoId: "crypto-fight-club", decimals: 18, price: 0.00015431}, // Addr: 0x4f39c3319188a723003670c3f9b9e7ef991e52f3, Notional: 0.00046293 + {chain: 4, addr: "0000000000000000000000005012c90f14d190607662ca8344120812aaa2639d", symbol: "PNP", coinGeckoId: "penpie", decimals: 18, price: 2.28}, // Addr: 0x5012c90f14d190607662ca8344120812aaa2639d, Notional: 111.2168078304 + {chain: 4, addr: "00000000000000000000000050d809c74e0b8e49e7b4c65bb3109abe3ff4c1c1", symbol: "CUB", coinGeckoId: "cub-finance", decimals: 18, price: 0.00190325}, // Addr: 0x50d809c74e0b8e49e7b4c65bb3109abe3ff4c1c1, Notional: 0.0000234138005325 + {chain: 4, addr: "000000000000000000000000524df384bffb18c0c8f3f43d012011f8f9795579", symbol: "YAY", coinGeckoId: "yay-games", decimals: 18, price: 0.00144672}, // Addr: 0x524df384bffb18c0c8f3f43d012011f8f9795579, Notional: 0.014467200000000001 + {chain: 4, addr: "00000000000000000000000052f24a5e03aee338da5fd9df68d2b6fae1178827", symbol: "ankrBNB", coinGeckoId: "ankr-staked-bnb", decimals: 18, price: 760.16}, // Addr: 0x52f24a5e03aee338da5fd9df68d2b6fae1178827, Notional: 1.4719282143999999 + {chain: 4, addr: "0000000000000000000000005512014efa6cd57764fa743756f7a6ce3358cc83", symbol: "EZ", coinGeckoId: "easyfi", decimals: 18, price: 0.01091411}, // Addr: 0x5512014efa6cd57764fa743756f7a6ce3358cc83, Notional: 0.06967112847496429 {chain: 4, addr: "000000000000000000000000552594612f935441c01c6854edf111f343c1ca07", symbol: "GWT", coinGeckoId: "galaxy-war", decimals: 18, price: 0.00011302}, // Addr: 0x552594612f935441c01c6854edf111f343c1ca07, Notional: 2.0766120137886124 - {chain: 4, addr: "00000000000000000000000055d398326f99059ff775485246999027b3197955", symbol: "USDT", coinGeckoId: "tether", decimals: 18, price: 1}, // Addr: 0x55d398326f99059ff775485246999027b3197955, Notional: 259257.35310194 - {chain: 4, addr: "000000000000000000000000570a5d26f7765ecb712c0924e4de545b89fd43df", symbol: "SOL", coinGeckoId: "wrapped-solana", decimals: 18, price: 222.86}, // Addr: 0x570a5d26f7765ecb712c0924e4de545b89fd43df, Notional: 51533.728657844404 - {chain: 4, addr: "00000000000000000000000059c49b54d4425c7ff1e49f40958a14d48cc87c26", symbol: "MC", coinGeckoId: "tap-fantasy-mc", decimals: 18, price: 0.108047}, // Addr: 0x59c49b54d4425c7ff1e49f40958a14d48cc87c26, Notional: 0.7675960115036 - {chain: 4, addr: "00000000000000000000000059f4f336bf3d0c49dbfba4a74ebd2a6ace40539a", symbol: "CAT", coinGeckoId: "catcoin-cash", decimals: 9, price: 2.84432e-10}, // Addr: 0x59f4f336bf3d0c49dbfba4a74ebd2a6ace40539a, Notional: 40.45664254912997 - {chain: 4, addr: "0000000000000000000000005b65cd9feb54f1df3d0c60576003344079f8dc06", symbol: "UNW", coinGeckoId: "uniwhale", decimals: 18, price: 0.00595163}, // Addr: 0x5b65cd9feb54f1df3d0c60576003344079f8dc06, Notional: 12918.117586239854 - {chain: 4, addr: "0000000000000000000000005b6dcf557e2abe2323c48445e8cc948910d8c2c9", symbol: "MIR", coinGeckoId: "mirror-protocol", decimals: 18, price: 0.0324267}, // Addr: 0x5b6dcf557e2abe2323c48445e8cc948910d8c2c9, Notional: 223.03261462738746 - {chain: 4, addr: "0000000000000000000000005e7f472b9481c80101b22d0ba4ef4253aa61dabc", symbol: "MUDOL2", coinGeckoId: "hero-blaze-three-kingdoms", decimals: 18, price: 0.00497466}, // Addr: 0x5e7f472b9481c80101b22d0ba4ef4253aa61dabc, Notional: 158387.7693016049 + {chain: 4, addr: "00000000000000000000000055d398326f99059ff775485246999027b3197955", symbol: "USDT", coinGeckoId: "tether", decimals: 18, price: 0.99789}, // Addr: 0x55d398326f99059ff775485246999027b3197955, Notional: 269917.91753079765 + {chain: 4, addr: "000000000000000000000000570a5d26f7765ecb712c0924e4de545b89fd43df", symbol: "SOL", coinGeckoId: "wrapped-solana", decimals: 18, price: 190.69}, // Addr: 0x570a5d26f7765ecb712c0924e4de545b89fd43df, Notional: 43914.3708547532 + {chain: 4, addr: "00000000000000000000000059c49b54d4425c7ff1e49f40958a14d48cc87c26", symbol: "MC", coinGeckoId: "tap-fantasy-mc", decimals: 18, price: 0.131966}, // Addr: 0x59c49b54d4425c7ff1e49f40958a14d48cc87c26, Notional: 0.9375232561208 + {chain: 4, addr: "00000000000000000000000059f4f336bf3d0c49dbfba4a74ebd2a6ace40539a", symbol: "CAT", coinGeckoId: "catcoin-cash", decimals: 9, price: 1.96287e-10}, // Addr: 0x59f4f336bf3d0c49dbfba4a74ebd2a6ace40539a, Notional: 27.91919684156872 + {chain: 4, addr: "0000000000000000000000005b65cd9feb54f1df3d0c60576003344079f8dc06", symbol: "UNW", coinGeckoId: "uniwhale", decimals: 18, price: 0.00439078}, // Addr: 0x5b65cd9feb54f1df3d0c60576003344079f8dc06, Notional: 9530.265210591087 + {chain: 4, addr: "0000000000000000000000005b6dcf557e2abe2323c48445e8cc948910d8c2c9", symbol: "MIR", coinGeckoId: "mirror-protocol", decimals: 18, price: 0.02541862}, // Addr: 0x5b6dcf557e2abe2323c48445e8cc948910d8c2c9, Notional: 174.8306574156483 + {chain: 4, addr: "0000000000000000000000005e7f472b9481c80101b22d0ba4ef4253aa61dabc", symbol: "MUDOL2", coinGeckoId: "hero-blaze-three-kingdoms", decimals: 18, price: 0.00388268}, // Addr: 0x5e7f472b9481c80101b22d0ba4ef4253aa61dabc, Notional: 121928.51458599846 {chain: 4, addr: "0000000000000000000000005e95a952a7f79f978585afd54a053af0f51372fa", symbol: "SBG", coinGeckoId: "sb-group", decimals: 9, price: 3.67439e-7}, // Addr: 0x5e95a952a7f79f978585afd54a053af0f51372fa, Notional: 0.000367439 - {chain: 4, addr: "0000000000000000000000005fb4968fc85868df3ad2d6e59883a10570f01d18", symbol: "SHR", coinGeckoId: "sharering", decimals: 18, price: 0.00362878}, // Addr: 0x5fb4968fc85868df3ad2d6e59883a10570f01d18, Notional: 162.91770688 - {chain: 4, addr: "000000000000000000000000603c7f932ed1fc6575303d8fb018fdcbb0f39a95", symbol: "BANANA", coinGeckoId: "apeswap-finance", decimals: 18, price: 0.00058152}, // Addr: 0x603c7f932ed1fc6575303d8fb018fdcbb0f39a95, Notional: 27.582679885395535 - {chain: 4, addr: "00000000000000000000000062823659d09f9f9d2222058878f89437425eb261", symbol: "ERTHA", coinGeckoId: "ertha", decimals: 18, price: 0.00127272}, // Addr: 0x62823659d09f9f9d2222058878f89437425eb261, Notional: 0.02672712 - {chain: 4, addr: "00000000000000000000000063eaeb6e33e11252b10553900a9f38a9ed172871", symbol: "TUP", coinGeckoId: "tenup", decimals: 18, price: 0.0216096}, // Addr: 0x63eaeb6e33e11252b10553900a9f38a9ed172871, Notional: 1.07399712 - {chain: 4, addr: "00000000000000000000000064619f611248256f7f4b72fe83872f89d5d60d64", symbol: "QUINT", coinGeckoId: "quint", decimals: 18, price: 0.00247699}, // Addr: 0x64619f611248256f7f4b72fe83872f89d5d60d64, Notional: 545.6453091260996 - {chain: 4, addr: "00000000000000000000000065c8743a5a266c3512eabd34e65ade42d4355ef1", symbol: "BPLC", coinGeckoId: "blackpearl-chain", decimals: 18, price: 1.78e-9}, // Addr: 0x65c8743a5a266c3512eabd34e65ade42d4355ef1, Notional: 0.476160217711216 - {chain: 4, addr: "000000000000000000000000678e840c640f619e17848045d23072844224dd37", symbol: "CRTS", coinGeckoId: "cratos", decimals: 18, price: 0.00032079}, // Addr: 0x678e840c640f619e17848045d23072844224dd37, Notional: 6089.627008722122 - {chain: 4, addr: "00000000000000000000000067ee3cb086f8a16f34bee3ca72fad36f7db929e2", symbol: "DODO", coinGeckoId: "dodo", decimals: 18, price: 0.155016}, // Addr: 0x67ee3cb086f8a16f34bee3ca72fad36f7db929e2, Notional: 1.55016 - {chain: 4, addr: "00000000000000000000000068784ffaa6ff05e3e04575df77960dc1d9f42b4a", symbol: "ABR", coinGeckoId: "allbridge", decimals: 18, price: 0.116295}, // Addr: 0x68784ffaa6ff05e3e04575df77960dc1d9f42b4a, Notional: 2.62234765078815 - {chain: 4, addr: "0000000000000000000000006bff4fb161347ad7de4a625ae5aa3a1ca7077819", symbol: "ADX", coinGeckoId: "adex", decimals: 18, price: 0.205019}, // Addr: 0x6bff4fb161347ad7de4a625ae5aa3a1ca7077819, Notional: 2.665247 - {chain: 4, addr: "0000000000000000000000006d1dc3928604b00180bb570bdae94b9698d33b79", symbol: "UCT", coinGeckoId: "unitedcrowd", decimals: 18, price: 0.00283048}, // Addr: 0x6d1dc3928604b00180bb570bdae94b9698d33b79, Notional: 0.28304799999999997 - {chain: 4, addr: "0000000000000000000000006d57f5c286e04850c2c085350f2e60aaa7b7c15b", symbol: "GrokGirl", coinGeckoId: "grok-girl", decimals: 9, price: 2.8301e-13}, // Addr: 0x6d57f5c286e04850c2c085350f2e60aaa7b7c15b, Notional: 0.052206130338816506 - {chain: 4, addr: "0000000000000000000000006d86f0a41c3966cef8ea139648db707e912563c9", symbol: "MCOIN", coinGeckoId: "mcoin1", decimals: 18, price: 0.169571}, // Addr: 0x6d86f0a41c3966cef8ea139648db707e912563c9, Notional: 0.0169571 - {chain: 4, addr: "0000000000000000000000006e2a5ea25b161befa6a8444c71ae3a89c39933c6", symbol: "B2M", coinGeckoId: "bit2me", decimals: 18, price: 0.01672051}, // Addr: 0x6e2a5ea25b161befa6a8444c71ae3a89c39933c6, Notional: 152.156641 - {chain: 4, addr: "0000000000000000000000006f769e65c14ebd1f68817f5f1dcdb61cfa2d6f7e", symbol: "ARPA", coinGeckoId: "arpa", decimals: 18, price: 0.061043}, // Addr: 0x6f769e65c14ebd1f68817f5f1dcdb61cfa2d6f7e, Notional: 26.208812050000002 - {chain: 4, addr: "0000000000000000000000006ff1bfa14a57594a5874b37ff6ac5efbd9f9599a", symbol: "TOTM", coinGeckoId: "totemfi", decimals: 18, price: 0.00224001}, // Addr: 0x6ff1bfa14a57594a5874b37ff6ac5efbd9f9599a, Notional: 0.221617873297089 - {chain: 4, addr: "0000000000000000000000007083609fce4d1d8dc0c979aab8c869ea2c873402", symbol: "DOT", coinGeckoId: "binance-peg-polkadot", decimals: 18, price: 8.55}, // Addr: 0x7083609fce4d1d8dc0c979aab8c869ea2c873402, Notional: 9115.3285724385 - {chain: 4, addr: "0000000000000000000000007130d2a12b9bcbfae4f2634d864a1ee1ce3ead9c", symbol: "BTCB", coinGeckoId: "binance-bitcoin", decimals: 18, price: 94872}, // Addr: 0x7130d2a12b9bcbfae4f2634d864a1ee1ce3ead9c, Notional: 997370.7856778401 - {chain: 4, addr: "000000000000000000000000715d400f88c167884bbcc41c5fea407ed4d2f8a0", symbol: "AXS", coinGeckoId: "axie-infinity", decimals: 18, price: 7.74}, // Addr: 0x715d400f88c167884bbcc41c5fea407ed4d2f8a0, Notional: 784.8380730816 - {chain: 4, addr: "00000000000000000000000071be881e9c5d4465b3fff61e89c6f3651e69b5bb", symbol: "BRZ", coinGeckoId: "brz", decimals: 4, price: 0.159991}, // Addr: 0x71be881e9c5d4465b3fff61e89c6f3651e69b5bb, Notional: 51.97307635 - {chain: 4, addr: "0000000000000000000000007269d98af4aa705e0b1a5d8512fadb4d45817d5a", symbol: "SHI", coinGeckoId: "shirtum", decimals: 18, price: 0.00094555}, // Addr: 0x7269d98af4aa705e0b1a5d8512fadb4d45817d5a, Notional: 0.094555 - {chain: 4, addr: "00000000000000000000000072b7d61e8fc8cf971960dd9cfa59b8c829d91991", symbol: "AQUA", coinGeckoId: "planet-finance", decimals: 18, price: 5.06}, // Addr: 0x72b7d61e8fc8cf971960dd9cfa59b8c829d91991, Notional: 0.5060034914 - {chain: 4, addr: "00000000000000000000000072eb7ca07399ec402c5b7aa6a65752b6a1dc0c27", symbol: "ASTRO", coinGeckoId: "astroswap", decimals: 18, price: 0.00017557}, // Addr: 0x72eb7ca07399ec402c5b7aa6a65752b6a1dc0c27, Notional: 0.0087785 - {chain: 4, addr: "000000000000000000000000734c5f3f8f6ad9697b26ecc6388678aafd3db3b2", symbol: "METAMUSK", coinGeckoId: "musk-metaverse", decimals: 18, price: 2.96611e-10}, // Addr: 0x734c5f3f8f6ad9697b26ecc6388678aafd3db3b2, Notional: 0.000009647168408824725 - {chain: 4, addr: "0000000000000000000000007559c49c3aec50e763a486bb232fa8d0d76078e4", symbol: "ATR", coinGeckoId: "artrade", decimals: 9, price: 0.04365822}, // Addr: 0x7559c49c3aec50e763a486bb232fa8d0d76078e4, Notional: 8249419.970038747 - {chain: 4, addr: "000000000000000000000000766afcf83fd5eaf884b3d529b432ca27a6d84617", symbol: "BLID", coinGeckoId: "bolide", decimals: 18, price: 0.0011358}, // Addr: 0x766afcf83fd5eaf884b3d529b432ca27a6d84617, Notional: 36.72080596015038 - {chain: 4, addr: "00000000000000000000000077edfae59a7948d66e9911a30cc787d2172343d4", symbol: "LBL", coinGeckoId: "label-foundation", decimals: 18, price: 0.00270958}, // Addr: 0x77edfae59a7948d66e9911a30cc787d2172343d4, Notional: 41.548358769402945 - {chain: 4, addr: "0000000000000000000000007881cd2b5724431372f57c50e91611352557a606", symbol: "HyPC", coinGeckoId: "hypercycle", decimals: 6, price: 0.205753}, // Addr: 0x7881cd2b5724431372f57c50e91611352557a606, Notional: 2.326256174686 - {chain: 4, addr: "00000000000000000000000079ebc9a2ce02277a4b5b3a768b1c0a4ed75bd936", symbol: "CATGIRL", coinGeckoId: "catgirl", decimals: 9, price: 1.6758e-11}, // Addr: 0x79ebc9a2ce02277a4b5b3a768b1c0a4ed75bd936, Notional: 3.3516000000000003e-9 - {chain: 4, addr: "0000000000000000000000007af173f350d916358af3e218bdf2178494beb748", symbol: "TRADE", coinGeckoId: "unitrade", decimals: 18, price: 0.00869144}, // Addr: 0x7af173f350d916358af3e218bdf2178494beb748, Notional: 4.791589261476168 - {chain: 4, addr: "0000000000000000000000007b610012bdc4d6deba2c2d91684e408f40863429", symbol: "OSEA", coinGeckoId: "omnisea", decimals: 18, price: 0.00304541}, // Addr: 0x7b610012bdc4d6deba2c2d91684e408f40863429, Notional: 0.40611606626387287 + {chain: 4, addr: "0000000000000000000000005fb4968fc85868df3ad2d6e59883a10570f01d18", symbol: "SHR", coinGeckoId: "sharering", decimals: 18, price: 0.00365694}, // Addr: 0x5fb4968fc85868df3ad2d6e59883a10570f01d18, Notional: 164.18197824 + {chain: 4, addr: "000000000000000000000000603c7f932ed1fc6575303d8fb018fdcbb0f39a95", symbol: "BANANA", coinGeckoId: "apeswap-finance", decimals: 18, price: 0.00058826}, // Addr: 0x603c7f932ed1fc6575303d8fb018fdcbb0f39a95, Notional: 27.90237183481699 + {chain: 4, addr: "00000000000000000000000062823659d09f9f9d2222058878f89437425eb261", symbol: "ERTHA", coinGeckoId: "ertha", decimals: 18, price: 0.00134901}, // Addr: 0x62823659d09f9f9d2222058878f89437425eb261, Notional: 0.02832921 + {chain: 4, addr: "00000000000000000000000063eaeb6e33e11252b10553900a9f38a9ed172871", symbol: "TUP", coinGeckoId: "tenup", decimals: 18, price: 0.02589539}, // Addr: 0x63eaeb6e33e11252b10553900a9f38a9ed172871, Notional: 1.2870008830000002 + {chain: 4, addr: "00000000000000000000000064619f611248256f7f4b72fe83872f89d5d60d64", symbol: "QUINT", coinGeckoId: "quint", decimals: 18, price: 0.00146425}, // Addr: 0x64619f611248256f7f4b72fe83872f89d5d60d64, Notional: 322.5532375535999 + {chain: 4, addr: "00000000000000000000000065c8743a5a266c3512eabd34e65ade42d4355ef1", symbol: "BPLC", coinGeckoId: "blackpearl-chain", decimals: 18, price: 1.747e-9}, // Addr: 0x65c8743a5a266c3512eabd34e65ade42d4355ef1, Notional: 1.2322596842126192 + {chain: 4, addr: "000000000000000000000000678e840c640f619e17848045d23072844224dd37", symbol: "CRTS", coinGeckoId: "cratos", decimals: 18, price: 0.00026728}, // Addr: 0x678e840c640f619e17848045d23072844224dd37, Notional: 5073.83492905405 + {chain: 4, addr: "00000000000000000000000067ee3cb086f8a16f34bee3ca72fad36f7db929e2", symbol: "DODO", coinGeckoId: "dodo", decimals: 18, price: 0.151651}, // Addr: 0x67ee3cb086f8a16f34bee3ca72fad36f7db929e2, Notional: 1.51651 + {chain: 4, addr: "00000000000000000000000068784ffaa6ff05e3e04575df77960dc1d9f42b4a", symbol: "ABR", coinGeckoId: "allbridge", decimals: 18, price: 0.096751}, // Addr: 0x68784ffaa6ff05e3e04575df77960dc1d9f42b4a, Notional: 2.18164802924807 + {chain: 4, addr: "0000000000000000000000006bff4fb161347ad7de4a625ae5aa3a1ca7077819", symbol: "ADX", coinGeckoId: "adex", decimals: 18, price: 0.211913}, // Addr: 0x6bff4fb161347ad7de4a625ae5aa3a1ca7077819, Notional: 2.754869 + {chain: 4, addr: "0000000000000000000000006d1dc3928604b00180bb570bdae94b9698d33b79", symbol: "UCT", coinGeckoId: "unitedcrowd", decimals: 18, price: 0.00159153}, // Addr: 0x6d1dc3928604b00180bb570bdae94b9698d33b79, Notional: 0.15915300000000002 + {chain: 4, addr: "0000000000000000000000006d57f5c286e04850c2c085350f2e60aaa7b7c15b", symbol: "GrokGirl", coinGeckoId: "grok-girl", decimals: 9, price: 7.1635e-14}, // Addr: 0x6d57f5c286e04850c2c085350f2e60aaa7b7c15b, Notional: 0.013214325100954454 + {chain: 4, addr: "0000000000000000000000006d86f0a41c3966cef8ea139648db707e912563c9", symbol: "MCOIN", coinGeckoId: "mcoin1", decimals: 18, price: 0.24509}, // Addr: 0x6d86f0a41c3966cef8ea139648db707e912563c9, Notional: 0.024509000000000003 + {chain: 4, addr: "0000000000000000000000006e2a5ea25b161befa6a8444c71ae3a89c39933c6", symbol: "B2M", coinGeckoId: "bit2me", decimals: 18, price: 0.01785051}, // Addr: 0x6e2a5ea25b161befa6a8444c71ae3a89c39933c6, Notional: 162.439641 + {chain: 4, addr: "0000000000000000000000006f769e65c14ebd1f68817f5f1dcdb61cfa2d6f7e", symbol: "ARPA", coinGeckoId: "arpa", decimals: 18, price: 0.04820544}, // Addr: 0x6f769e65c14ebd1f68817f5f1dcdb61cfa2d6f7e, Notional: 20.697005664000002 + {chain: 4, addr: "0000000000000000000000006ff1bfa14a57594a5874b37ff6ac5efbd9f9599a", symbol: "TOTM", coinGeckoId: "totemfi", decimals: 18, price: 0.00312213}, // Addr: 0x6ff1bfa14a57594a5874b37ff6ac5efbd9f9599a, Notional: 0.308891393679957 + {chain: 4, addr: "0000000000000000000000007083609fce4d1d8dc0c979aab8c869ea2c873402", symbol: "DOT", coinGeckoId: "binance-peg-polkadot", decimals: 18, price: 6.63}, // Addr: 0x7083609fce4d1d8dc0c979aab8c869ea2c873402, Notional: 7068.3775947681 + {chain: 4, addr: "0000000000000000000000007130d2a12b9bcbfae4f2634d864a1ee1ce3ead9c", symbol: "BTCB", coinGeckoId: "binance-bitcoin", decimals: 18, price: 93401}, // Addr: 0x7130d2a12b9bcbfae4f2634d864a1ee1ce3ead9c, Notional: 1010826.3915365001 + {chain: 4, addr: "000000000000000000000000715d400f88c167884bbcc41c5fea407ed4d2f8a0", symbol: "AXS", coinGeckoId: "axie-infinity", decimals: 18, price: 6.18}, // Addr: 0x715d400f88c167884bbcc41c5fea407ed4d2f8a0, Notional: 626.6536552512 + {chain: 4, addr: "00000000000000000000000071be881e9c5d4465b3fff61e89c6f3651e69b5bb", symbol: "BRZ", coinGeckoId: "brz", decimals: 4, price: 0.16085}, // Addr: 0x71be881e9c5d4465b3fff61e89c6f3651e69b5bb, Notional: 52.2521225 + {chain: 4, addr: "0000000000000000000000007269d98af4aa705e0b1a5d8512fadb4d45817d5a", symbol: "SHI", coinGeckoId: "shirtum", decimals: 18, price: 0.0009429}, // Addr: 0x7269d98af4aa705e0b1a5d8512fadb4d45817d5a, Notional: 0.09429 + {chain: 4, addr: "00000000000000000000000072b7d61e8fc8cf971960dd9cfa59b8c829d91991", symbol: "AQUA", coinGeckoId: "planet-finance", decimals: 18, price: 4.51}, // Addr: 0x72b7d61e8fc8cf971960dd9cfa59b8c829d91991, Notional: 0.4510031119 + {chain: 4, addr: "00000000000000000000000072eb7ca07399ec402c5b7aa6a65752b6a1dc0c27", symbol: "ASTRO", coinGeckoId: "astroswap", decimals: 18, price: 0.0001479}, // Addr: 0x72eb7ca07399ec402c5b7aa6a65752b6a1dc0c27, Notional: 0.007395 + {chain: 4, addr: "000000000000000000000000734c5f3f8f6ad9697b26ecc6388678aafd3db3b2", symbol: "METAMUSK", coinGeckoId: "musk-metaverse", decimals: 18, price: 2.97686e-10}, // Addr: 0x734c5f3f8f6ad9697b26ecc6388678aafd3db3b2, Notional: 0.000009682132405572946 + {chain: 4, addr: "0000000000000000000000007559c49c3aec50e763a486bb232fa8d0d76078e4", symbol: "ATR", coinGeckoId: "artrade", decimals: 9, price: 0.04246451}, // Addr: 0x7559c49c3aec50e763a486bb232fa8d0d76078e4, Notional: 8295600.105542452 + {chain: 4, addr: "000000000000000000000000766afcf83fd5eaf884b3d529b432ca27a6d84617", symbol: "BLID", coinGeckoId: "bolide", decimals: 18, price: 0.00094546}, // Addr: 0x766afcf83fd5eaf884b3d529b432ca27a6d84617, Notional: 30.567048074558706 + {chain: 4, addr: "00000000000000000000000077edfae59a7948d66e9911a30cc787d2172343d4", symbol: "LBL", coinGeckoId: "label-foundation", decimals: 18, price: 0.00218697}, // Addr: 0x77edfae59a7948d66e9911a30cc787d2172343d4, Notional: 33.53472279021884 + {chain: 4, addr: "0000000000000000000000007881cd2b5724431372f57c50e91611352557a606", symbol: "HyPC", coinGeckoId: "hypercycle", decimals: 6, price: 0.194766}, // Addr: 0x7881cd2b5724431372f57c50e91611352557a606, Notional: 2.202036471492 + {chain: 4, addr: "00000000000000000000000079ebc9a2ce02277a4b5b3a768b1c0a4ed75bd936", symbol: "CATGIRL", coinGeckoId: "catgirl", decimals: 9, price: 2.4718e-11}, // Addr: 0x79ebc9a2ce02277a4b5b3a768b1c0a4ed75bd936, Notional: 4.943599999999999e-9 + {chain: 4, addr: "0000000000000000000000007af173f350d916358af3e218bdf2178494beb748", symbol: "TRADE", coinGeckoId: "unitrade", decimals: 18, price: 0.03133751}, // Addr: 0x7af173f350d916358af3e218bdf2178494beb748, Notional: 17.276363456159395 + {chain: 4, addr: "0000000000000000000000007b610012bdc4d6deba2c2d91684e408f40863429", symbol: "OSEA", coinGeckoId: "omnisea", decimals: 18, price: 0.00254962}, // Addr: 0x7b610012bdc4d6deba2c2d91684e408f40863429, Notional: 0.34000073713151774 {chain: 4, addr: "0000000000000000000000007b65b489fe53fce1f6548db886c08ad73111ddd8", symbol: "IRON", coinGeckoId: "iron-bsc", decimals: 18, price: 0.0161403}, // Addr: 0x7b65b489fe53fce1f6548db886c08ad73111ddd8, Notional: 1.936836 - {chain: 4, addr: "0000000000000000000000007dc6dc21ce07e6499fdcc30dcdb943a8ee4db802", symbol: "GPTG", coinGeckoId: "gpt-guru", decimals: 18, price: 0.00006309}, // Addr: 0x7dc6dc21ce07e6499fdcc30dcdb943a8ee4db802, Notional: 959.6870620290899 - {chain: 4, addr: "0000000000000000000000007ddc52c4de30e94be3a6a0a2b259b2850f421989", symbol: "GMT", coinGeckoId: "gmt-token", decimals: 18, price: 0.400034}, // Addr: 0x7ddc52c4de30e94be3a6a0a2b259b2850f421989, Notional: 100.0085 - {chain: 4, addr: "0000000000000000000000007e35d0e9180bf3a1fc47b0d110be7a21a10b41fe", symbol: "OVR", coinGeckoId: "ovr", decimals: 18, price: 0.210239}, // Addr: 0x7e35d0e9180bf3a1fc47b0d110be7a21a10b41fe, Notional: 39.26653557687157 - {chain: 4, addr: "0000000000000000000000007e624fa0e1c4abfd309cc15719b7e2580887f570", symbol: "POLS", coinGeckoId: "polkastarter", decimals: 18, price: 0.513654}, // Addr: 0x7e624fa0e1c4abfd309cc15719b7e2580887f570, Notional: 3.5955780000000006 - {chain: 4, addr: "0000000000000000000000007e8db69dcff9209e486a100e611b0af300c3374e", symbol: "TRDC", coinGeckoId: "traders-coin", decimals: 18, price: 0.00023177}, // Addr: 0x7e8db69dcff9209e486a100e611b0af300c3374e, Notional: 0.40546309532544206 + {chain: 4, addr: "0000000000000000000000007dc6dc21ce07e6499fdcc30dcdb943a8ee4db802", symbol: "GPTG", coinGeckoId: "gpt-guru", decimals: 18, price: 0.00006058}, // Addr: 0x7dc6dc21ce07e6499fdcc30dcdb943a8ee4db802, Notional: 921.5064545525801 + {chain: 4, addr: "0000000000000000000000007ddc52c4de30e94be3a6a0a2b259b2850f421989", symbol: "GMT", coinGeckoId: "gmt-token", decimals: 18, price: 0.500553}, // Addr: 0x7ddc52c4de30e94be3a6a0a2b259b2850f421989, Notional: 125.13825 + {chain: 4, addr: "0000000000000000000000007e35d0e9180bf3a1fc47b0d110be7a21a10b41fe", symbol: "OVR", coinGeckoId: "ovr", decimals: 18, price: 0.311931}, // Addr: 0x7e35d0e9180bf3a1fc47b0d110be7a21a10b41fe, Notional: 58.259645969725526 + {chain: 4, addr: "0000000000000000000000007e624fa0e1c4abfd309cc15719b7e2580887f570", symbol: "POLS", coinGeckoId: "polkastarter", decimals: 18, price: 0.38991}, // Addr: 0x7e624fa0e1c4abfd309cc15719b7e2580887f570, Notional: 2.72937 + {chain: 4, addr: "0000000000000000000000007e8db69dcff9209e486a100e611b0af300c3374e", symbol: "TRDC", coinGeckoId: "traders-coin", decimals: 18, price: 0.00024093}, // Addr: 0x7e8db69dcff9209e486a100e611b0af300c3374e, Notional: 0.42148778339197807 {chain: 4, addr: "0000000000000000000000007eefb6aeb8bc2c1ba6be1d4273ec0758a1321272", symbol: "ENG", coinGeckoId: "endless-battlefield", decimals: 18, price: 0.00006497}, // Addr: 0x7eefb6aeb8bc2c1ba6be1d4273ec0758a1321272, Notional: 0.06497 - {chain: 4, addr: "0000000000000000000000008076c74c5e3f5852037f31ff0093eeb8c8add8d3", symbol: "SAFEMOON", coinGeckoId: "safemoon", decimals: 9, price: 7.841e-9}, // Addr: 0x8076c74c5e3f5852037f31ff0093eeb8c8add8d3, Notional: 3.5284500007841e-7 - {chain: 4, addr: "000000000000000000000000818835503f55283cd51a4399f595e295a9338753", symbol: "AGI", coinGeckoId: "delysium", decimals: 18, price: 0.221272}, // Addr: 0x818835503f55283cd51a4399f595e295a9338753, Notional: 0.0663816 - {chain: 4, addr: "00000000000000000000000082443a77684a7da92fdcb639c8d2bd068a596245", symbol: "SWAP", coinGeckoId: "trustswap", decimals: 18, price: 0.136464}, // Addr: 0x82443a77684a7da92fdcb639c8d2bd068a596245, Notional: 0.409392 - {chain: 4, addr: "0000000000000000000000008263cd1601fe73c066bf49cc09841f35348e3be0", symbol: "ALU", coinGeckoId: "altura", decimals: 18, price: 0.129114}, // Addr: 0x8263cd1601fe73c066bf49cc09841f35348e3be0, Notional: 2065.9129466346 - {chain: 4, addr: "00000000000000000000000082d2f8e02afb160dd5a480a617692e62de9038c4", symbol: "ALEPH", coinGeckoId: "aleph", decimals: 18, price: 0.169864}, // Addr: 0x82d2f8e02afb160dd5a480a617692e62de9038c4, Notional: 70.77736154178815 - {chain: 4, addr: "000000000000000000000000833f307ac507d47309fd8cdd1f835bef8d702a93", symbol: "REVV", coinGeckoId: "revv", decimals: 18, price: 0.00425741}, // Addr: 0x833f307ac507d47309fd8cdd1f835bef8d702a93, Notional: 0.08940561 + {chain: 4, addr: "0000000000000000000000008076c74c5e3f5852037f31ff0093eeb8c8add8d3", symbol: "SAFEMOON", coinGeckoId: "safemoon", decimals: 9, price: 9.54e-9}, // Addr: 0x8076c74c5e3f5852037f31ff0093eeb8c8add8d3, Notional: 4.293000000954e-7 + {chain: 4, addr: "000000000000000000000000818835503f55283cd51a4399f595e295a9338753", symbol: "AGI", coinGeckoId: "delysium", decimals: 18, price: 0.137788}, // Addr: 0x818835503f55283cd51a4399f595e295a9338753, Notional: 0.041336399999999995 + {chain: 4, addr: "00000000000000000000000082443a77684a7da92fdcb639c8d2bd068a596245", symbol: "SWAP", coinGeckoId: "trustswap", decimals: 18, price: 0.114969}, // Addr: 0x82443a77684a7da92fdcb639c8d2bd068a596245, Notional: 0.344907 + {chain: 4, addr: "0000000000000000000000008263cd1601fe73c066bf49cc09841f35348e3be0", symbol: "ALU", coinGeckoId: "altura", decimals: 18, price: 0.102764}, // Addr: 0x8263cd1601fe73c066bf49cc09841f35348e3be0, Notional: 1644.2947941195998 + {chain: 4, addr: "00000000000000000000000082d2f8e02afb160dd5a480a617692e62de9038c4", symbol: "ALEPH", coinGeckoId: "aleph", decimals: 18, price: 0.132321}, // Addr: 0x82d2f8e02afb160dd5a480a617692e62de9038c4, Notional: 55.13429129521823 + {chain: 4, addr: "000000000000000000000000833f307ac507d47309fd8cdd1f835bef8d702a93", symbol: "REVV", coinGeckoId: "revv", decimals: 18, price: 0.00430643}, // Addr: 0x833f307ac507d47309fd8cdd1f835bef8d702a93, Notional: 0.09043503 {chain: 4, addr: "00000000000000000000000083adb07bb91ddde95a24982f1b2d343963ba3995", symbol: "Fwcl", coinGeckoId: "legends", decimals: 9, price: 0.02347393}, // Addr: 0x83adb07bb91ddde95a24982f1b2d343963ba3995, Notional: 0.11736965 - {chain: 4, addr: "00000000000000000000000083d8ea5a4650b68cd2b57846783d86df940f7458", symbol: "HUDI", coinGeckoId: "hudi", decimals: 18, price: 0.04884186}, // Addr: 0x83d8ea5a4650b68cd2b57846783d86df940f7458, Notional: 1.3297232762417328 - {chain: 4, addr: "000000000000000000000000842668e2b9a73240abf6532dedc89c9c3e050c98", symbol: "LIGHT", coinGeckoId: "light-defi", decimals: 9, price: 0.00009019}, // Addr: 0x842668e2b9a73240abf6532dedc89c9c3e050c98, Notional: 0.81315304910919 - {chain: 4, addr: "00000000000000000000000084e9a6f9d240fdd33801f7135908bfa16866939a", symbol: "GMEE", coinGeckoId: "gamee", decimals: 18, price: 0.01186076}, // Addr: 0x84e9a6f9d240fdd33801f7135908bfa16866939a, Notional: 22.777334111911976 - {chain: 4, addr: "00000000000000000000000084f4f7cdb4574c9556a494dab18ffc1d1d22316c", symbol: "KINGSHIB", coinGeckoId: "king-shiba", decimals: 9, price: 0.00116304}, // Addr: 0x84f4f7cdb4574c9556a494dab18ffc1d1d22316c, Notional: 1.2730635841395648 - {chain: 4, addr: "0000000000000000000000008519ea49c997f50ceffa444d240fb655e89248aa", symbol: "RAMP", coinGeckoId: "ramp", decimals: 18, price: 0.086508}, // Addr: 0x8519ea49c997f50ceffa444d240fb655e89248aa, Notional: 121.85045464342896 - {chain: 4, addr: "000000000000000000000000854a63b35b70a7becbed508ff0b6ff5038d0c917", symbol: "MNTO", coinGeckoId: "minato", decimals: 18, price: 1.21}, // Addr: 0x854a63b35b70a7becbed508ff0b6ff5038d0c917, Notional: 35.340995660299996 - {chain: 4, addr: "0000000000000000000000008578eb576e126f67913a8bc0622e0a22eba0989a", symbol: "PANDA", coinGeckoId: "hashpanda", decimals: 9, price: 9.05232e-10}, // Addr: 0x8578eb576e126f67913a8bc0622e0a22eba0989a, Notional: 0.06554328909655967 - {chain: 4, addr: "0000000000000000000000008595f9da7b868b1822194faed312235e43007b49", symbol: "BTT", coinGeckoId: "bittorrent-old", decimals: 18, price: 0.00104771}, // Addr: 0x8595f9da7b868b1822194faed312235e43007b49, Notional: 0.00104771 - {chain: 4, addr: "000000000000000000000000872d068c25511be88c1f5990c53eeffcdf46c9b4", symbol: "VENT", coinGeckoId: "vent-finance", decimals: 18, price: 0.00168383}, // Addr: 0x872d068c25511be88c1f5990c53eeffcdf46c9b4, Notional: 0.5085166600000001 - {chain: 4, addr: "000000000000000000000000885c5fb8f0e67b2b0cf3a437e6cc6ebc0f9f9014", symbol: "GEMG", coinGeckoId: "gemguardian", decimals: 18, price: 0.00434154}, // Addr: 0x885c5fb8f0e67b2b0cf3a437e6cc6ebc0f9f9014, Notional: 0.1703583453257406 - {chain: 4, addr: "00000000000000000000000088d7e9b65dc24cf54f5edef929225fc3e1580c25", symbol: "JMPT", coinGeckoId: "jumptoken", decimals: 18, price: 1.12}, // Addr: 0x88d7e9b65dc24cf54f5edef929225fc3e1580c25, Notional: 354580.0333117392 - {chain: 4, addr: "0000000000000000000000008929e9dbd2785e3ba16175e596cdd61520fee0d1", symbol: "ALTD", coinGeckoId: "altitude", decimals: 18, price: 0.00074529}, // Addr: 0x8929e9dbd2785e3ba16175e596cdd61520fee0d1, Notional: 0.030894820584263998 + {chain: 4, addr: "00000000000000000000000083d8ea5a4650b68cd2b57846783d86df940f7458", symbol: "HUDI", coinGeckoId: "hudi", decimals: 18, price: 0.058375}, // Addr: 0x83d8ea5a4650b68cd2b57846783d86df940f7458, Notional: 1.5892637227700002 + {chain: 4, addr: "000000000000000000000000842668e2b9a73240abf6532dedc89c9c3e050c98", symbol: "LIGHT", coinGeckoId: "light-defi", decimals: 9, price: 0.00009616}, // Addr: 0x842668e2b9a73240abf6532dedc89c9c3e050c98, Notional: 0.8669785697121599 + {chain: 4, addr: "00000000000000000000000084e9a6f9d240fdd33801f7135908bfa16866939a", symbol: "GMEE", coinGeckoId: "gamee", decimals: 18, price: 0.01098331}, // Addr: 0x84e9a6f9d240fdd33801f7135908bfa16866939a, Notional: 21.092284265485848 + {chain: 4, addr: "00000000000000000000000084f4f7cdb4574c9556a494dab18ffc1d1d22316c", symbol: "KINGSHIB", coinGeckoId: "king-shiba", decimals: 9, price: 0.00126522}, // Addr: 0x84f4f7cdb4574c9556a494dab18ffc1d1d22316c, Notional: 1.3849098121518264 + {chain: 4, addr: "0000000000000000000000008519ea49c997f50ceffa444d240fb655e89248aa", symbol: "RAMP", coinGeckoId: "ramp", decimals: 18, price: 0.065342}, // Addr: 0x8519ea49c997f50ceffa444d240fb655e89248aa, Notional: 92.03718046089304 + {chain: 4, addr: "000000000000000000000000854a63b35b70a7becbed508ff0b6ff5038d0c917", symbol: "MNTO", coinGeckoId: "minato", decimals: 18, price: 0.799733}, // Addr: 0x854a63b35b70a7becbed508ff0b6ff5038d0c917, Notional: 23.35814915900719 + {chain: 4, addr: "0000000000000000000000008578eb576e126f67913a8bc0622e0a22eba0989a", symbol: "PANDA", coinGeckoId: "hashpanda", decimals: 9, price: 1.004e-9}, // Addr: 0x8578eb576e126f67913a8bc0622e0a22eba0989a, Notional: 0.0726945824417894 + {chain: 4, addr: "0000000000000000000000008595f9da7b868b1822194faed312235e43007b49", symbol: "BTT", coinGeckoId: "bittorrent-old", decimals: 18, price: 0.00107359}, // Addr: 0x8595f9da7b868b1822194faed312235e43007b49, Notional: 0.00107359 + {chain: 4, addr: "000000000000000000000000872d068c25511be88c1f5990c53eeffcdf46c9b4", symbol: "VENT", coinGeckoId: "vent-finance", decimals: 18, price: 0.00155177}, // Addr: 0x872d068c25511be88c1f5990c53eeffcdf46c9b4, Notional: 0.46863454000000004 + {chain: 4, addr: "000000000000000000000000885c5fb8f0e67b2b0cf3a437e6cc6ebc0f9f9014", symbol: "GEMG", coinGeckoId: "gemguardian", decimals: 18, price: 0.00445814}, // Addr: 0x885c5fb8f0e67b2b0cf3a437e6cc6ebc0f9f9014, Notional: 0.17493363037781462 + {chain: 4, addr: "00000000000000000000000088d7e9b65dc24cf54f5edef929225fc3e1580c25", symbol: "JMPT", coinGeckoId: "jumptoken", decimals: 18, price: 1.14}, // Addr: 0x88d7e9b65dc24cf54f5edef929225fc3e1580c25, Notional: 360688.94404341595 + {chain: 4, addr: "0000000000000000000000008929e9dbd2785e3ba16175e596cdd61520fee0d1", symbol: "ALTD", coinGeckoId: "altitude", decimals: 18, price: 0.00044128}, // Addr: 0x8929e9dbd2785e3ba16175e596cdd61520fee0d1, Notional: 0.018292565883648 {chain: 4, addr: "0000000000000000000000008a5d7fcd4c90421d21d30fcc4435948ac3618b2f", symbol: "MONSTA", coinGeckoId: "cake-monster", decimals: 18, price: 0.00004838}, // Addr: 0x8a5d7fcd4c90421d21d30fcc4435948ac3618b2f, Notional: 0.000045960999999999996 - {chain: 4, addr: "0000000000000000000000008ac76a51cc950d9822d68b83fe1ad97b32cd580d", symbol: "USDC", coinGeckoId: "usd-coin", decimals: 18, price: 1}, // Addr: 0x8ac76a51cc950d9822d68b83fe1ad97b32cd580d, Notional: 2080005.89990646 - {chain: 4, addr: "0000000000000000000000008bd778b12b15416359a227f0533ce2d91844e1ed", symbol: "SAKE", coinGeckoId: "sake-token", decimals: 18, price: 0.00146595}, // Addr: 0x8bd778b12b15416359a227f0533ce2d91844e1ed, Notional: 2.851049825886081 - {chain: 4, addr: "0000000000000000000000008bfca09e5877ea59f85883d13a6873334b937d41", symbol: "MADPEPE", coinGeckoId: "mad-pepe", decimals: 18, price: 2.83752e-10}, // Addr: 0x8bfca09e5877ea59f85883d13a6873334b937d41, Notional: 0.004257131256 - {chain: 4, addr: "0000000000000000000000008d11ec38a3eb5e956b052f67da8bdc9bef8abf3e", symbol: "KEX", coinGeckoId: "kira-network", decimals: 6, price: 0.02417903}, // Addr: 0x8d11ec38a3eb5e956b052f67da8bdc9bef8abf3e, Notional: 0.00024179030000000002 - {chain: 4, addr: "0000000000000000000000008da443f84fea710266c8eb6bc34b71702d033ef2", symbol: "CTSI", coinGeckoId: "cartesi", decimals: 18, price: 0.200232}, // Addr: 0x8da443f84fea710266c8eb6bc34b71702d033ef2, Notional: 4.34303208 - {chain: 4, addr: "0000000000000000000000008ebc361536094fd5b4ffb8521e31900614c9f55d", symbol: "DARC", coinGeckoId: "darcmatter-coin", decimals: 18, price: 0.00234057}, // Addr: 0x8ebc361536094fd5b4ffb8521e31900614c9f55d, Notional: 10795.656944781245 - {chain: 4, addr: "0000000000000000000000008ff795a6f4d97e7887c79bea79aba5cc76444adf", symbol: "BCH", coinGeckoId: "binance-peg-bitcoin-cash", decimals: 18, price: 498.45}, // Addr: 0x8ff795a6f4d97e7887c79bea79aba5cc76444adf, Notional: 0.001844265 - {chain: 4, addr: "0000000000000000000000009029fdfae9a03135846381c7ce16595c3554e10a", symbol: "OOE", coinGeckoId: "openocean", decimals: 18, price: 0.01553995}, // Addr: 0x9029fdfae9a03135846381c7ce16595c3554e10a, Notional: 0.01553995 - {chain: 4, addr: "00000000000000000000000092868a5255c628da08f550a858a802f5351c5223", symbol: "BRIDGE", coinGeckoId: "cross-chain-bridge", decimals: 18, price: 0.00097352}, // Addr: 0x92868a5255c628da08f550a858a802f5351c5223, Notional: 0.07885512 - {chain: 4, addr: "000000000000000000000000928e55dab735aa8260af3cedada18b5f70c72f1b", symbol: "FRONT", coinGeckoId: "frontier-token", decimals: 18, price: 0.50088}, // Addr: 0x928e55dab735aa8260af3cedada18b5f70c72f1b, Notional: 3.5117447719296 - {chain: 4, addr: "000000000000000000000000935a544bf5816e3a7c13db2efe3009ffda0acda2", symbol: "BLZ", coinGeckoId: "bluzelle", decimals: 18, price: 0.145078}, // Addr: 0x935a544bf5816e3a7c13db2efe3009ffda0acda2, Notional: 66.90998999526478 - {chain: 4, addr: "00000000000000000000000093c27727e72ec7510a06ea450366c1418c4ce547", symbol: "PXP", coinGeckoId: "pirate-x-pirate", decimals: 18, price: 0.00013215}, // Addr: 0x93c27727e72ec7510a06ea450366c1418c4ce547, Notional: 0.0002643 - {chain: 4, addr: "000000000000000000000000947950bcc74888a40ffa2593c5798f11fc9124c4", symbol: "SUSHI", coinGeckoId: "sushi", decimals: 18, price: 1.35}, // Addr: 0x947950bcc74888a40ffa2593c5798f11fc9124c4, Notional: 6.2367850125 - {chain: 4, addr: "0000000000000000000000009573c88ae3e37508f87649f87c4dd5373c9f31e0", symbol: "MONI", coinGeckoId: "monsta-infinite", decimals: 18, price: 0.00695536}, // Addr: 0x9573c88ae3e37508f87649f87c4dd5373c9f31e0, Notional: 0.0077949410187248 - {chain: 4, addr: "000000000000000000000000959229d94c9060552daea25ac17193bca65d7884", symbol: "IOI", coinGeckoId: "ioi-token", decimals: 6, price: 0.01931646}, // Addr: 0x959229d94c9060552daea25ac17193bca65d7884, Notional: 0.4906093990569 - {chain: 4, addr: "000000000000000000000000961c8c0b1aad0c0b10a51fef6a867e3091bcef17", symbol: "DYP", coinGeckoId: "defi-yield-protocol", decimals: 18, price: 0.314992}, // Addr: 0x961c8c0b1aad0c0b10a51fef6a867e3091bcef17, Notional: 4919.103155795848 - {chain: 4, addr: "000000000000000000000000965f527d9159dce6288a2219db51fc6eef120dd1", symbol: "BSW", coinGeckoId: "biswap", decimals: 18, price: 0.078867}, // Addr: 0x965f527d9159dce6288a2219db51fc6eef120dd1, Notional: 0.157734 - {chain: 4, addr: "0000000000000000000000009678e42cebeb63f23197d726b29b1cb20d0064e5", symbol: "IOTX", coinGeckoId: "binance-peg-iotex", decimals: 18, price: 0.053629}, // Addr: 0x9678e42cebeb63f23197d726b29b1cb20d0064e5, Notional: 298.2608956893985 - {chain: 4, addr: "0000000000000000000000009767c8e438aa18f550208e6d1fdf5f43541cc2c8", symbol: "MMIT", coinGeckoId: "mangoman-intelligent", decimals: 18, price: 2.16e-9}, // Addr: 0x9767c8e438aa18f550208e6d1fdf5f43541cc2c8, Notional: 2.16e-7 - {chain: 4, addr: "00000000000000000000000098f8669f6481ebb341b522fcd3663f79a3d1a6a7", symbol: "NEST", coinGeckoId: "nest", decimals: 18, price: 0.00115453}, // Addr: 0x98f8669f6481ebb341b522fcd3663f79a3d1a6a7, Notional: 0.08197163053108379 - {chain: 4, addr: "000000000000000000000000998305efdc264b9674178899fffbb44a47134a76", symbol: "GMRX", coinGeckoId: "gaimin", decimals: 18, price: 0.00096179}, // Addr: 0x998305efdc264b9674178899fffbb44a47134a76, Notional: 261096.71400562336 - {chain: 4, addr: "0000000000000000000000009b17baadf0f21f03e35249e0e59723f34994f806", symbol: "SURE", coinGeckoId: "insure", decimals: 18, price: 0.00379377}, // Addr: 0x9b17baadf0f21f03e35249e0e59723f34994f806, Notional: 1.138131 - {chain: 4, addr: "0000000000000000000000009bf543d8460583ff8a669aae01d9cdbee4defe3c", symbol: "SKO", coinGeckoId: "sugar-kingdom-odyssey", decimals: 18, price: 0.00164248}, // Addr: 0x9bf543d8460583ff8a669aae01d9cdbee4defe3c, Notional: 2082.9113733455997 - {chain: 4, addr: "0000000000000000000000009d7107c8e30617cadc11f9692a19c82ae8bba938", symbol: "ROO", coinGeckoId: "lucky-roo", decimals: 18, price: 3.4803e-8}, // Addr: 0x9d7107c8e30617cadc11f9692a19c82ae8bba938, Notional: 0.34103170987097436 - {chain: 4, addr: "0000000000000000000000009df465460938f9ebdf51c38cc87d72184471f8f0", symbol: "GENE", coinGeckoId: "genopets", decimals: 18, price: 0.117324}, // Addr: 0x9df465460938f9ebdf51c38cc87d72184471f8f0, Notional: 9.862607286463321 - {chain: 4, addr: "0000000000000000000000009e20461bc2c4c980f62f1b279d71734207a6a356", symbol: "OMNI", coinGeckoId: "omnicat", decimals: 18, price: 0.00004722}, // Addr: 0x9e20461bc2c4c980f62f1b279d71734207a6a356, Notional: 95.75795293005984 - {chain: 4, addr: "0000000000000000000000009e24415d1e549ebc626a13a482bb117a2b43e9cf", symbol: "LOVELY", coinGeckoId: "lovely-inu-finance", decimals: 8, price: 0.00279063}, // Addr: 0x9e24415d1e549ebc626a13a482bb117a2b43e9cf, Notional: 16575292.723932182 - {chain: 4, addr: "0000000000000000000000009e3a9f1612028eee48f85ca85f8bed2f37d76848", symbol: "QDX", coinGeckoId: "quidax", decimals: 18, price: 0.02881626}, // Addr: 0x9e3a9f1612028eee48f85ca85f8bed2f37d76848, Notional: 14.40813 - {chain: 4, addr: "0000000000000000000000009e6b3e35c8f563b45d864f9ff697a144ad28a371", symbol: "DOGO", coinGeckoId: "dogemon-go", decimals: 18, price: 5.63585e-7}, // Addr: 0x9e6b3e35c8f563b45d864f9ff697a144ad28a371, Notional: 9.569012719829042 - {chain: 4, addr: "0000000000000000000000009eb6935aea6afb5bc6d1a74be0c2f78280ab6448", symbol: "ACA", coinGeckoId: "aca-token", decimals: 9, price: 0.0002647}, // Addr: 0x9eb6935aea6afb5bc6d1a74be0c2f78280ab6448, Notional: 1.7067643884772599 - {chain: 4, addr: "0000000000000000000000009ed7e4b1bff939ad473da5e7a218c771d1569456", symbol: "REUNI", coinGeckoId: "reunit-wallet", decimals: 6, price: 0.04971907}, // Addr: 0x9ed7e4b1bff939ad473da5e7a218c771d1569456, Notional: 0.9322325625 - {chain: 4, addr: "0000000000000000000000009f5c37e0fd9bf729b1f0a6f39ce57be5e9bfd435", symbol: " BTCPAY", coinGeckoId: "bitcoin-pay", decimals: 18, price: 0.00596848}, // Addr: 0x9f5c37e0fd9bf729b1f0a6f39ce57be5e9bfd435, Notional: 0.0000255631788944 - {chain: 4, addr: "0000000000000000000000009fb9a33956351cf4fa040f65a13b835a3c8764e3", symbol: "MULTI", coinGeckoId: "multichain", decimals: 18, price: 0.577897}, // Addr: 0x9fb9a33956351cf4fa040f65a13b835a3c8764e3, Notional: 173.05364567619802 - {chain: 4, addr: "000000000000000000000000a0d96fd642156fc7e964949642257b3572f10cd6", symbol: "BLOK", coinGeckoId: "bloktopia", decimals: 18, price: 0.00084917}, // Addr: 0xa0d96fd642156fc7e964949642257b3572f10cd6, Notional: 66.14343727407227 - {chain: 4, addr: "000000000000000000000000a2120b9e674d3fc3875f415a7df52e382f141225", symbol: "ATA", coinGeckoId: "automata", decimals: 18, price: 0.121332}, // Addr: 0xa2120b9e674d3fc3875f415a7df52e382f141225, Notional: 2.5843716 - {chain: 4, addr: "000000000000000000000000a260e12d2b924cb899ae80bb58123ac3fee1e2f0", symbol: "HOOK", coinGeckoId: "hooked-protocol", decimals: 18, price: 0.593299}, // Addr: 0xa260e12d2b924cb899ae80bb58123ac3fee1e2f0, Notional: 1.186598 - {chain: 4, addr: "000000000000000000000000a2b726b1145a4773f68593cf171187d8ebe4d495", symbol: "INJ", coinGeckoId: "injective-protocol", decimals: 18, price: 28.5}, // Addr: 0xa2b726b1145a4773f68593cf171187d8ebe4d495, Notional: 4674.201975795 + {chain: 4, addr: "0000000000000000000000008ac76a51cc950d9822d68b83fe1ad97b32cd580d", symbol: "USDC", coinGeckoId: "usd-coin", decimals: 18, price: 0.999339}, // Addr: 0x8ac76a51cc950d9822d68b83fe1ad97b32cd580d, Notional: 1978644.93424586 + {chain: 4, addr: "0000000000000000000000008bd778b12b15416359a227f0533ce2d91844e1ed", symbol: "SAKE", coinGeckoId: "sake-token", decimals: 18, price: 0.00120754}, // Addr: 0x8bd778b12b15416359a227f0533ce2d91844e1ed, Notional: 2.348481671783129 + {chain: 4, addr: "0000000000000000000000008bfca09e5877ea59f85883d13a6873334b937d41", symbol: "MADPEPE", coinGeckoId: "mad-pepe", decimals: 18, price: 1.8632e-10}, // Addr: 0x8bfca09e5877ea59f85883d13a6873334b937d41, Notional: 0.00279535896 + {chain: 4, addr: "0000000000000000000000008d11ec38a3eb5e956b052f67da8bdc9bef8abf3e", symbol: "KEX", coinGeckoId: "kira-network", decimals: 6, price: 0.02888893}, // Addr: 0x8d11ec38a3eb5e956b052f67da8bdc9bef8abf3e, Notional: 0.0002888893 + {chain: 4, addr: "0000000000000000000000008da443f84fea710266c8eb6bc34b71702d033ef2", symbol: "CTSI", coinGeckoId: "cartesi", decimals: 18, price: 0.152479}, // Addr: 0x8da443f84fea710266c8eb6bc34b71702d033ef2, Notional: 3.3072695100000002 + {chain: 4, addr: "0000000000000000000000008ebc361536094fd5b4ffb8521e31900614c9f55d", symbol: "DARC", coinGeckoId: "darcmatter-coin", decimals: 18, price: 0.00069774}, // Addr: 0x8ebc361536094fd5b4ffb8521e31900614c9f55d, Notional: 4295.867463725354 + {chain: 4, addr: "0000000000000000000000008ff795a6f4d97e7887c79bea79aba5cc76444adf", symbol: "BCH", coinGeckoId: "binance-peg-bitcoin-cash", decimals: 18, price: 437.53}, // Addr: 0x8ff795a6f4d97e7887c79bea79aba5cc76444adf, Notional: 0.0016188609999999999 + {chain: 4, addr: "0000000000000000000000009029fdfae9a03135846381c7ce16595c3554e10a", symbol: "OOE", coinGeckoId: "openocean", decimals: 18, price: 0.00922924}, // Addr: 0x9029fdfae9a03135846381c7ce16595c3554e10a, Notional: 0.00922924 + {chain: 4, addr: "00000000000000000000000092868a5255c628da08f550a858a802f5351c5223", symbol: "BRIDGE", coinGeckoId: "cross-chain-bridge", decimals: 18, price: 0.00089285}, // Addr: 0x92868a5255c628da08f550a858a802f5351c5223, Notional: 0.07232085 + {chain: 4, addr: "000000000000000000000000928e55dab735aa8260af3cedada18b5f70c72f1b", symbol: "FRONT", coinGeckoId: "frontier-token", decimals: 18, price: 0.518809}, // Addr: 0x928e55dab735aa8260af3cedada18b5f70c72f1b, Notional: 3.63744767884528 + {chain: 4, addr: "000000000000000000000000935a544bf5816e3a7c13db2efe3009ffda0acda2", symbol: "BLZ", coinGeckoId: "bluzelle", decimals: 18, price: 0.053927}, // Addr: 0x935a544bf5816e3a7c13db2efe3009ffda0acda2, Notional: 24.87113849429027 + {chain: 4, addr: "00000000000000000000000093c27727e72ec7510a06ea450366c1418c4ce547", symbol: "PXP", coinGeckoId: "pirate-x-pirate", decimals: 18, price: 0.00012972}, // Addr: 0x93c27727e72ec7510a06ea450366c1418c4ce547, Notional: 0.00025944 + {chain: 4, addr: "000000000000000000000000947950bcc74888a40ffa2593c5798f11fc9124c4", symbol: "SUSHI", coinGeckoId: "sushi", decimals: 18, price: 1.36}, // Addr: 0x947950bcc74888a40ffa2593c5798f11fc9124c4, Notional: 6.28298342 + {chain: 4, addr: "0000000000000000000000009573c88ae3e37508f87649f87c4dd5373c9f31e0", symbol: "MONI", coinGeckoId: "monsta-infinite", decimals: 18, price: 0.00626275}, // Addr: 0x9573c88ae3e37508f87649f87c4dd5373c9f31e0, Notional: 0.007018726114107501 + {chain: 4, addr: "000000000000000000000000959229d94c9060552daea25ac17193bca65d7884", symbol: "IOI", coinGeckoId: "ioi-token", decimals: 6, price: 0.00854447}, // Addr: 0x959229d94c9060552daea25ac17193bca65d7884, Notional: 0.21701684946205 + {chain: 4, addr: "000000000000000000000000961c8c0b1aad0c0b10a51fef6a867e3091bcef17", symbol: "DYP", coinGeckoId: "defi-yield-protocol", decimals: 18, price: 0.205661}, // Addr: 0x961c8c0b1aad0c0b10a51fef6a867e3091bcef17, Notional: 3211.72497753635 + {chain: 4, addr: "000000000000000000000000965f527d9159dce6288a2219db51fc6eef120dd1", symbol: "BSW", coinGeckoId: "biswap", decimals: 18, price: 0.074718}, // Addr: 0x965f527d9159dce6288a2219db51fc6eef120dd1, Notional: 0.149436 + {chain: 4, addr: "0000000000000000000000009678e42cebeb63f23197d726b29b1cb20d0064e5", symbol: "IOTX", coinGeckoId: "binance-peg-iotex", decimals: 18, price: 0.03835049}, // Addr: 0x9678e42cebeb63f23197d726b29b1cb20d0064e5, Notional: 213.2885471951243 + {chain: 4, addr: "0000000000000000000000009767c8e438aa18f550208e6d1fdf5f43541cc2c8", symbol: "MMIT", coinGeckoId: "mangoman-intelligent", decimals: 18, price: 1.137e-9}, // Addr: 0x9767c8e438aa18f550208e6d1fdf5f43541cc2c8, Notional: 1.1369999999999999e-7 + {chain: 4, addr: "00000000000000000000000098f8669f6481ebb341b522fcd3663f79a3d1a6a7", symbol: "NEST", coinGeckoId: "nest", decimals: 18, price: 0.00124569}, // Addr: 0x98f8669f6481ebb341b522fcd3663f79a3d1a6a7, Notional: 0.0884439905730174 + {chain: 4, addr: "000000000000000000000000998305efdc264b9674178899fffbb44a47134a76", symbol: "GMRX", coinGeckoId: "gaimin", decimals: 18, price: 0.00057492}, // Addr: 0x998305efdc264b9674178899fffbb44a47134a76, Notional: 193152.38253702957 + {chain: 4, addr: "0000000000000000000000009b17baadf0f21f03e35249e0e59723f34994f806", symbol: "SURE", coinGeckoId: "insure", decimals: 18, price: 0.0030549}, // Addr: 0x9b17baadf0f21f03e35249e0e59723f34994f806, Notional: 0.91647 + {chain: 4, addr: "0000000000000000000000009bf543d8460583ff8a669aae01d9cdbee4defe3c", symbol: "SKO", coinGeckoId: "sugar-kingdom-odyssey", decimals: 18, price: 0.00147253}, // Addr: 0x9bf543d8460583ff8a669aae01d9cdbee4defe3c, Notional: 1849.8455210366 + {chain: 4, addr: "0000000000000000000000009d7107c8e30617cadc11f9692a19c82ae8bba938", symbol: "ROO", coinGeckoId: "lucky-roo", decimals: 18, price: 3.2395e-8}, // Addr: 0x9d7107c8e30617cadc11f9692a19c82ae8bba938, Notional: 0.3174359176298082 + {chain: 4, addr: "0000000000000000000000009df465460938f9ebdf51c38cc87d72184471f8f0", symbol: "GENE", coinGeckoId: "genopets", decimals: 18, price: 0.124587}, // Addr: 0x9df465460938f9ebdf51c38cc87d72184471f8f0, Notional: 10.47315684769191 + {chain: 4, addr: "0000000000000000000000009e20461bc2c4c980f62f1b279d71734207a6a356", symbol: "OMNI", coinGeckoId: "omnicat", decimals: 18, price: 0.00002616}, // Addr: 0x9e20461bc2c4c980f62f1b279d71734207a6a356, Notional: 53.05014927256175 + {chain: 4, addr: "0000000000000000000000009e24415d1e549ebc626a13a482bb117a2b43e9cf", symbol: "LOVELY", coinGeckoId: "lovely-inu-finance", decimals: 8, price: 0.00152587}, // Addr: 0x9e24415d1e549ebc626a13a482bb117a2b43e9cf, Notional: 39623456.88150961 + {chain: 4, addr: "0000000000000000000000009e3a9f1612028eee48f85ca85f8bed2f37d76848", symbol: "QDX", coinGeckoId: "quidax", decimals: 18, price: 0.054285}, // Addr: 0x9e3a9f1612028eee48f85ca85f8bed2f37d76848, Notional: 27.1425 + {chain: 4, addr: "0000000000000000000000009e6b3e35c8f563b45d864f9ff697a144ad28a371", symbol: "DOGO", coinGeckoId: "dogemon-go", decimals: 18, price: 1.96155e-7}, // Addr: 0x9e6b3e35c8f563b45d864f9ff697a144ad28a371, Notional: 3.330481985961418 + {chain: 4, addr: "0000000000000000000000009eb6935aea6afb5bc6d1a74be0c2f78280ab6448", symbol: "ACA", coinGeckoId: "aca-token", decimals: 9, price: 0.00029669}, // Addr: 0x9eb6935aea6afb5bc6d1a74be0c2f78280ab6448, Notional: 1.9130333449842019 + {chain: 4, addr: "0000000000000000000000009ed7e4b1bff939ad473da5e7a218c771d1569456", symbol: "REUNI", coinGeckoId: "reunit-wallet", decimals: 6, price: 0.03726833}, // Addr: 0x9ed7e4b1bff939ad473da5e7a218c771d1569456, Notional: 0.6987811875000001 + {chain: 4, addr: "0000000000000000000000009f5c37e0fd9bf729b1f0a6f39ce57be5e9bfd435", symbol: " BTCPAY", coinGeckoId: "bitcoin-pay", decimals: 18, price: 0.00442021}, // Addr: 0x9f5c37e0fd9bf729b1f0a6f39ce57be5e9bfd435, Notional: 0.0000189318920363 + {chain: 4, addr: "0000000000000000000000009fb9a33956351cf4fa040f65a13b835a3c8764e3", symbol: "MULTI", coinGeckoId: "multichain", decimals: 18, price: 0.380015}, // Addr: 0x9fb9a33956351cf4fa040f65a13b835a3c8764e3, Notional: 119.63097315945805 + {chain: 4, addr: "000000000000000000000000a0d96fd642156fc7e964949642257b3572f10cd6", symbol: "BLOK", coinGeckoId: "bloktopia", decimals: 18, price: 0.00067727}, // Addr: 0xa0d96fd642156fc7e964949642257b3572f10cd6, Notional: 52.75382522064007 + {chain: 4, addr: "000000000000000000000000a2120b9e674d3fc3875f415a7df52e382f141225", symbol: "ATA", coinGeckoId: "automata", decimals: 18, price: 0.176101}, // Addr: 0xa2120b9e674d3fc3875f415a7df52e382f141225, Notional: 3.7509513 + {chain: 4, addr: "000000000000000000000000a260e12d2b924cb899ae80bb58123ac3fee1e2f0", symbol: "HOOK", coinGeckoId: "hooked-protocol", decimals: 18, price: 0.421073}, // Addr: 0xa260e12d2b924cb899ae80bb58123ac3fee1e2f0, Notional: 0.842146 + {chain: 4, addr: "000000000000000000000000a2b726b1145a4773f68593cf171187d8ebe4d495", symbol: "INJ", coinGeckoId: "injective-protocol", decimals: 18, price: 19.64}, // Addr: 0xa2b726b1145a4773f68593cf171187d8ebe4d495, Notional: 3221.0991861268 {chain: 4, addr: "000000000000000000000000a38898a4ae982cb0131104a6746f77fa0da57aaa", symbol: "QBIT", coinGeckoId: "project-quantum", decimals: 2, price: 0.00000173}, // Addr: 0xa38898a4ae982cb0131104a6746f77fa0da57aaa, Notional: 0.00001557 - {chain: 4, addr: "000000000000000000000000a5496935a247fa81b1462e553ad139d2fd0af795", symbol: "FLAG", coinGeckoId: "flag-network", decimals: 18, price: 0.00001501}, // Addr: 0xa5496935a247fa81b1462e553ad139d2fd0af795, Notional: 6.922696469918913 - {chain: 4, addr: "000000000000000000000000a58950f05fea2277d2608748412bf9f802ea4901", symbol: "WSG", coinGeckoId: "wall-street-games", decimals: 18, price: 7.28116e-10}, // Addr: 0xa58950f05fea2277d2608748412bf9f802ea4901, Notional: 1.1249347577507611 - {chain: 4, addr: "000000000000000000000000a6168c7e5eb7c5c379f3a1d7cf1073e09b2f031e", symbol: "GRAV", coinGeckoId: "graviton-zero", decimals: 18, price: 0.0000828}, // Addr: 0xa6168c7e5eb7c5c379f3a1d7cf1073e09b2f031e, Notional: 0.00001629504 + {chain: 4, addr: "000000000000000000000000a5496935a247fa81b1462e553ad139d2fd0af795", symbol: "FLAG", coinGeckoId: "flag-network", decimals: 18, price: 0.00001425}, // Addr: 0xa5496935a247fa81b1462e553ad139d2fd0af795, Notional: 6.572180192960993 + {chain: 4, addr: "000000000000000000000000a58950f05fea2277d2608748412bf9f802ea4901", symbol: "WSG", coinGeckoId: "wall-street-games", decimals: 18, price: 2.30122e-10}, // Addr: 0xa58950f05fea2277d2608748412bf9f802ea4901, Notional: 0.3555370797003783 + {chain: 4, addr: "000000000000000000000000a6168c7e5eb7c5c379f3a1d7cf1073e09b2f031e", symbol: "GRAV", coinGeckoId: "graviton-zero", decimals: 18, price: 0.00008185}, // Addr: 0xa6168c7e5eb7c5c379f3a1d7cf1073e09b2f031e, Notional: 0.00001610808 {chain: 4, addr: "000000000000000000000000a67b8e40111a0edd30c3210b77aadb86ad234c43", symbol: "Bandex", coinGeckoId: "banana-index", decimals: 9, price: 1.2007e-8}, // Addr: 0xa67b8e40111a0edd30c3210b77aadb86ad234c43, Notional: 4.967892563718809 - {chain: 4, addr: "000000000000000000000000a719b8ab7ea7af0ddb4358719a34631bb79d15dc", symbol: "FRM", coinGeckoId: "ferrum-network", decimals: 18, price: 0.01180405}, // Addr: 0xa719b8ab7ea7af0ddb4358719a34631bb79d15dc, Notional: 1.1742759683634374 - {chain: 4, addr: "000000000000000000000000a75d9ca2a0a1d547409d82e1b06618ec284a2ced", symbol: "WMX", coinGeckoId: "wombex", decimals: 18, price: 0.00043066}, // Addr: 0xa75d9ca2a0a1d547409d82e1b06618ec284a2ced, Notional: 3553.707975990752 - {chain: 4, addr: "000000000000000000000000a7bd657c5838472ddf85ff0797a2e6fce8fd4833", symbol: "ARBI", coinGeckoId: "arbipad", decimals: 18, price: 0.00006327}, // Addr: 0xa7bd657c5838472ddf85ff0797a2e6fce8fd4833, Notional: 424.98689369469304 - {chain: 4, addr: "000000000000000000000000aa076b62efc6f357882e07665157a271ab46a063", symbol: "NSFW", coinGeckoId: "pleasure-coin", decimals: 18, price: 0.00002497}, // Addr: 0xaa076b62efc6f357882e07665157a271ab46a063, Notional: 13877.693072352991 + {chain: 4, addr: "000000000000000000000000a719b8ab7ea7af0ddb4358719a34631bb79d15dc", symbol: "FRM", coinGeckoId: "ferrum-network", decimals: 18, price: 0.00724468}, // Addr: 0xa719b8ab7ea7af0ddb4358719a34631bb79d15dc, Notional: 0.72070633574775 + {chain: 4, addr: "000000000000000000000000a75d9ca2a0a1d547409d82e1b06618ec284a2ced", symbol: "WMX", coinGeckoId: "wombex", decimals: 18, price: 0.00023918}, // Addr: 0xa75d9ca2a0a1d547409d82e1b06618ec284a2ced, Notional: 1937.56256884904 + {chain: 4, addr: "000000000000000000000000a7bd657c5838472ddf85ff0797a2e6fce8fd4833", symbol: "ARBI", coinGeckoId: "arbipad", decimals: 18, price: 0.00005776}, // Addr: 0xa7bd657c5838472ddf85ff0797a2e6fce8fd4833, Notional: 387.9760230726327 + {chain: 4, addr: "000000000000000000000000aa076b62efc6f357882e07665157a271ab46a063", symbol: "NSFW", coinGeckoId: "pleasure-coin", decimals: 18, price: 0.00002127}, // Addr: 0xaa076b62efc6f357882e07665157a271ab46a063, Notional: 10980.356728315503 {chain: 4, addr: "000000000000000000000000aa2ded323944b25c0b6f1f891bc96f010b65622c", symbol: "TheRadio", coinGeckoId: "radioreum", decimals: 18, price: 0.00023167}, // Addr: 0xaa2ded323944b25c0b6f1f891bc96f010b65622c, Notional: 0.0013409563065244002 - {chain: 4, addr: "000000000000000000000000aa9826732f3a4973ff8b384b3f4e3c70c2984651", symbol: "XPRESS", coinGeckoId: "cryptoexpress", decimals: 18, price: 0.050292}, // Addr: 0xaa9826732f3a4973ff8b384b3f4e3c70c2984651, Notional: 8.64898069173732 - {chain: 4, addr: "000000000000000000000000ac472d0eed2b8a2f57a6e304ea7ebd8e88d1d36f", symbol: "ANI", coinGeckoId: "anime-token", decimals: 18, price: 0.00163775}, // Addr: 0xac472d0eed2b8a2f57a6e304ea7ebd8e88d1d36f, Notional: 250.5610693393158 - {chain: 4, addr: "000000000000000000000000ac51066d7bec65dc4589368da368b212745d63e8", symbol: "ALICE", coinGeckoId: "my-neighbor-alice", decimals: 6, price: 1.48}, // Addr: 0xac51066d7bec65dc4589368da368b212745d63e8, Notional: 0.888 - {chain: 4, addr: "000000000000000000000000ace8c5e6e492aa7aebf31a8053f8a487f62ceb84", symbol: "NADA", coinGeckoId: "nothing", decimals: 18, price: 6.69421e-7}, // Addr: 0xace8c5e6e492aa7aebf31a8053f8a487f62ceb84, Notional: 0.2677684 - {chain: 4, addr: "000000000000000000000000ad29abb318791d579433d831ed122afeaf29dcfe", symbol: "FTM", coinGeckoId: "wrapped-fantom", decimals: 18, price: 1.003}, // Addr: 0xad29abb318791d579433d831ed122afeaf29dcfe, Notional: 3421.7399878141996 - {chain: 4, addr: "000000000000000000000000ad6742a35fb341a9cc6ad674738dd8da98b94fb1", symbol: "WOM", coinGeckoId: "wombat-exchange", decimals: 18, price: 0.01130773}, // Addr: 0xad6742a35fb341a9cc6ad674738dd8da98b94fb1, Notional: 743137.7845752477 - {chain: 4, addr: "000000000000000000000000ad86d0e9764ba90ddd68747d64bffbd79879a238", symbol: "PAID", coinGeckoId: "paid-network", decimals: 18, price: 0.106253}, // Addr: 0xad86d0e9764ba90ddd68747d64bffbd79879a238, Notional: 0.6331514267120001 - {chain: 4, addr: "000000000000000000000000ae9269f27437f0fcbc232d39ec814844a51d6b8f", symbol: "BURGER", coinGeckoId: "burger-swap", decimals: 18, price: 0.496056}, // Addr: 0xae9269f27437f0fcbc232d39ec814844a51d6b8f, Notional: 0.06492664175976 - {chain: 4, addr: "000000000000000000000000aec945e04baf28b135fa7c640f624f8d90f1c3a6", symbol: "C98", coinGeckoId: "coin98", decimals: 18, price: 0.205573}, // Addr: 0xaec945e04baf28b135fa7c640f624f8d90f1c3a6, Notional: 86.45649064545127 - {chain: 4, addr: "000000000000000000000000aef0d72a118ce24fee3cd1d43d383897d05b4e99", symbol: "WIN", coinGeckoId: "winklink-bsc", decimals: 18, price: 0.00010938}, // Addr: 0xaef0d72a118ce24fee3cd1d43d383897d05b4e99, Notional: 21.247953180555527 - {chain: 4, addr: "000000000000000000000000af20f5f19698f1d19351028cd7103b63d30de7d7", symbol: "WAGMI", coinGeckoId: "wagmi-2", decimals: 18, price: 0.01652413}, // Addr: 0xaf20f5f19698f1d19351028cd7103b63d30de7d7, Notional: 0.10740684500000001 - {chain: 4, addr: "000000000000000000000000af7bfa6240745fd41d1ed4b5fade9dcaf369ba6c", symbol: "Mverse", coinGeckoId: "maticverse", decimals: 18, price: 1.35985e-7}, // Addr: 0xaf7bfa6240745fd41d1ed4b5fade9dcaf369ba6c, Notional: 15.118298232071437 - {chain: 4, addr: "000000000000000000000000b0d502e938ed5f4df2e681fe6e419ff29631d62b", symbol: "STG", coinGeckoId: "stargate-finance", decimals: 18, price: 0.382194}, // Addr: 0xb0d502e938ed5f4df2e681fe6e419ff29631d62b, Notional: 29.669980398565496 - {chain: 4, addr: "000000000000000000000000b46584e0efde3092e04010a13f2eae62adb3b9f0", symbol: "PEPE", coinGeckoId: "pepe-coin-bsc-c45e8b31-8ae1-43f4-bd34-e75551d97285", decimals: 18, price: 4.044e-9}, // Addr: 0xb46584e0efde3092e04010a13f2eae62adb3b9f0, Notional: 475.79710298666606 - {chain: 4, addr: "000000000000000000000000b6c53431608e626ac81a9776ac3e999c5556717c", symbol: "TLOS", coinGeckoId: "wrapped-telos", decimals: 18, price: 0.19073}, // Addr: 0xb6c53431608e626ac81a9776ac3e999c5556717c, Notional: 1.8752709380687003 - {chain: 4, addr: "000000000000000000000000b8501a9a9aaae239a2490f44e00b284baa0b131a", symbol: "CREMAT", coinGeckoId: "cremation-coin", decimals: 18, price: 1.6418e-8}, // Addr: 0xb8501a9a9aaae239a2490f44e00b284baa0b131a, Notional: 0.140287960375639 - {chain: 4, addr: "000000000000000000000000b955b4cab9aa3b49e23aeb5204ebc5ff6678e86d", symbol: "Afin", coinGeckoId: "afin-coin", decimals: 18, price: 0.00100889}, // Addr: 0xb955b4cab9aa3b49e23aeb5204ebc5ff6678e86d, Notional: 8.888427252300772 - {chain: 4, addr: "000000000000000000000000ba2ae424d960c26247dd6c32edc70b295c744c43", symbol: "DOGE", coinGeckoId: "binance-peg-dogecoin", decimals: 8, price: 0.410361}, // Addr: 0xba2ae424d960c26247dd6c32edc70b295c744c43, Notional: 84052.44445441804 - {chain: 4, addr: "000000000000000000000000bb4cdb9cbd36b01bd1cbaebf2de08d9173bc095c", symbol: "WBNB", coinGeckoId: "wbnb", decimals: 18, price: 632.16}, // Addr: 0xbb4cdb9cbd36b01bd1cbaebf2de08d9173bc095c, Notional: 3181160.185043745 - {chain: 4, addr: "000000000000000000000000bd100d061e120b2c67a24453cf6368e63f1be056", symbol: "iDYP", coinGeckoId: "idefiyieldprotocol", decimals: 18, price: 0.00059256}, // Addr: 0xbd100d061e120b2c67a24453cf6368e63f1be056, Notional: 1.6663024224 - {chain: 4, addr: "000000000000000000000000bd7b8e4de08d9b01938f7ff2058f110ee1e0e8d4", symbol: "GHX", coinGeckoId: "gamercoin", decimals: 18, price: 0.091215}, // Addr: 0xbd7b8e4de08d9b01938f7ff2058f110ee1e0e8d4, Notional: 146.8467624003048 - {chain: 4, addr: "000000000000000000000000bd83010eb60f12112908774998f65761cf9f6f9a", symbol: "STARS", coinGeckoId: "mogul-productions", decimals: 18, price: 0.000199}, // Addr: 0xbd83010eb60f12112908774998f65761cf9f6f9a, Notional: 0.08303076000000001 - {chain: 4, addr: "000000000000000000000000bdeae1ca48894a1759a8374d63925f21f2ee2639", symbol: "EDU", coinGeckoId: "edu-coin", decimals: 18, price: 0.619}, // Addr: 0xbdeae1ca48894a1759a8374d63925f21f2ee2639, Notional: 30.95619 - {chain: 4, addr: "000000000000000000000000bf05279f9bf1ce69bbfed670813b7e431142afa4", symbol: "MM", coinGeckoId: "million", decimals: 18, price: 1.13}, // Addr: 0xbf05279f9bf1ce69bbfed670813b7e431142afa4, Notional: 2.26 + {chain: 4, addr: "000000000000000000000000aa9826732f3a4973ff8b384b3f4e3c70c2984651", symbol: "XPRESS", coinGeckoId: "cryptoexpress", decimals: 18, price: 0.051598}, // Addr: 0xaa9826732f3a4973ff8b384b3f4e3c70c2984651, Notional: 8.87358040507958 + {chain: 4, addr: "000000000000000000000000ac472d0eed2b8a2f57a6e304ea7ebd8e88d1d36f", symbol: "ANI", coinGeckoId: "anime-token", decimals: 18, price: 0.0021041}, // Addr: 0xac472d0eed2b8a2f57a6e304ea7ebd8e88d1d36f, Notional: 1644.0567480031002 + {chain: 4, addr: "000000000000000000000000ac51066d7bec65dc4589368da368b212745d63e8", symbol: "ALICE", coinGeckoId: "my-neighbor-alice", decimals: 6, price: 1.1}, // Addr: 0xac51066d7bec65dc4589368da368b212745d63e8, Notional: 0.66 + {chain: 4, addr: "000000000000000000000000ace8c5e6e492aa7aebf31a8053f8a487f62ceb84", symbol: "NADA", coinGeckoId: "nothing", decimals: 18, price: 7.32312e-7}, // Addr: 0xace8c5e6e492aa7aebf31a8053f8a487f62ceb84, Notional: 0.2929248 + {chain: 4, addr: "000000000000000000000000ad29abb318791d579433d831ed122afeaf29dcfe", symbol: "FTM", coinGeckoId: "wrapped-fantom", decimals: 18, price: 0.675103}, // Addr: 0xad29abb318791d579433d831ed122afeaf29dcfe, Notional: 2303.117578258554 + {chain: 4, addr: "000000000000000000000000ad6742a35fb341a9cc6ad674738dd8da98b94fb1", symbol: "WOM", coinGeckoId: "wombat-exchange", decimals: 18, price: 0.0069762}, // Addr: 0xad6742a35fb341a9cc6ad674738dd8da98b94fb1, Notional: 460142.086523872 + {chain: 4, addr: "000000000000000000000000ad86d0e9764ba90ddd68747d64bffbd79879a238", symbol: "PAID", coinGeckoId: "paid-network", decimals: 18, price: 0.078007}, // Addr: 0xad86d0e9764ba90ddd68747d64bffbd79879a238, Notional: 0.4648362243280001 + {chain: 4, addr: "000000000000000000000000ae9269f27437f0fcbc232d39ec814844a51d6b8f", symbol: "BURGER", coinGeckoId: "burger-swap", decimals: 18, price: 0.450437}, // Addr: 0xae9269f27437f0fcbc232d39ec814844a51d6b8f, Notional: 0.05895576655526999 + {chain: 4, addr: "000000000000000000000000aec945e04baf28b135fa7c640f624f8d90f1c3a6", symbol: "C98", coinGeckoId: "coin98", decimals: 18, price: 0.166627}, // Addr: 0xaec945e04baf28b135fa7c640f624f8d90f1c3a6, Notional: 70.07722641971274 + {chain: 4, addr: "000000000000000000000000aef0d72a118ce24fee3cd1d43d383897d05b4e99", symbol: "WIN", coinGeckoId: "winklink-bsc", decimals: 18, price: 0.00009971}, // Addr: 0xaef0d72a118ce24fee3cd1d43d383897d05b4e99, Notional: 19.369477158833348 + {chain: 4, addr: "000000000000000000000000af20f5f19698f1d19351028cd7103b63d30de7d7", symbol: "WAGMI", coinGeckoId: "wagmi-2", decimals: 18, price: 0.0121481}, // Addr: 0xaf20f5f19698f1d19351028cd7103b63d30de7d7, Notional: 0.07896265 + {chain: 4, addr: "000000000000000000000000af7bfa6240745fd41d1ed4b5fade9dcaf369ba6c", symbol: "Mverse", coinGeckoId: "maticverse", decimals: 18, price: 1.40561e-7}, // Addr: 0xaf7bfa6240745fd41d1ed4b5fade9dcaf369ba6c, Notional: 15.627040613289651 + {chain: 4, addr: "000000000000000000000000b0d502e938ed5f4df2e681fe6e419ff29631d62b", symbol: "STG", coinGeckoId: "stargate-finance", decimals: 18, price: 0.36685}, // Addr: 0xb0d502e938ed5f4df2e681fe6e419ff29631d62b, Notional: 28.4788152331375 + {chain: 4, addr: "000000000000000000000000b46584e0efde3092e04010a13f2eae62adb3b9f0", symbol: "PEPE", coinGeckoId: "pepe-coin-bsc-c45e8b31-8ae1-43f4-bd34-e75551d97285", decimals: 18, price: 3.318e-9}, // Addr: 0xb46584e0efde3092e04010a13f2eae62adb3b9f0, Notional: 390.37952218342184 + {chain: 4, addr: "000000000000000000000000b6c53431608e626ac81a9776ac3e999c5556717c", symbol: "TLOS", coinGeckoId: "wrapped-telos", decimals: 18, price: 0.184696}, // Addr: 0xb6c53431608e626ac81a9776ac3e999c5556717c, Notional: 1.8159442205082401 + {chain: 4, addr: "000000000000000000000000b8501a9a9aaae239a2490f44e00b284baa0b131a", symbol: "CREMAT", coinGeckoId: "cremation-coin", decimals: 18, price: 1.6376e-8}, // Addr: 0xb8501a9a9aaae239a2490f44e00b284baa0b131a, Notional: 0.13992908022362435 + {chain: 4, addr: "000000000000000000000000b955b4cab9aa3b49e23aeb5204ebc5ff6678e86d", symbol: "Afin", coinGeckoId: "afin-coin", decimals: 18, price: 0.00074809}, // Addr: 0xb955b4cab9aa3b49e23aeb5204ebc5ff6678e86d, Notional: 6.590751760027044 + {chain: 4, addr: "000000000000000000000000ba2ae424d960c26247dd6c32edc70b295c744c43", symbol: "DOGE", coinGeckoId: "binance-peg-dogecoin", decimals: 8, price: 0.315887}, // Addr: 0xba2ae424d960c26247dd6c32edc70b295c744c43, Notional: 65386.98674093858 + {chain: 4, addr: "000000000000000000000000bb4cdb9cbd36b01bd1cbaebf2de08d9173bc095c", symbol: "WBNB", coinGeckoId: "wbnb", decimals: 18, price: 699.48}, // Addr: 0xbb4cdb9cbd36b01bd1cbaebf2de08d9173bc095c, Notional: 3596863.1638880232 + {chain: 4, addr: "000000000000000000000000bd100d061e120b2c67a24453cf6368e63f1be056", symbol: "iDYP", coinGeckoId: "idefiyieldprotocol", decimals: 18, price: 0.00071252}, // Addr: 0xbd100d061e120b2c67a24453cf6368e63f1be056, Notional: 2.0036347408 + {chain: 4, addr: "000000000000000000000000bd7b8e4de08d9b01938f7ff2058f110ee1e0e8d4", symbol: "GHX", coinGeckoId: "gamercoin", decimals: 18, price: 0.070941}, // Addr: 0xbd7b8e4de08d9b01938f7ff2058f110ee1e0e8d4, Notional: 114.20770894523953 + {chain: 4, addr: "000000000000000000000000bd83010eb60f12112908774998f65761cf9f6f9a", symbol: "STARS", coinGeckoId: "mogul-productions", decimals: 18, price: 0.00015821}, // Addr: 0xbd83010eb60f12112908774998f65761cf9f6f9a, Notional: 0.0660115404 + {chain: 4, addr: "000000000000000000000000bdeae1ca48894a1759a8374d63925f21f2ee2639", symbol: "EDU", coinGeckoId: "edu-coin", decimals: 18, price: 0.524621}, // Addr: 0xbdeae1ca48894a1759a8374d63925f21f2ee2639, Notional: 26.23629621 + {chain: 4, addr: "000000000000000000000000bf05279f9bf1ce69bbfed670813b7e431142afa4", symbol: "MM", coinGeckoId: "million", decimals: 18, price: 0.995765}, // Addr: 0xbf05279f9bf1ce69bbfed670813b7e431142afa4, Notional: 1.99153 {chain: 4, addr: "000000000000000000000000bf0cf158e84ebacca1b7746e794d507073e5adfe", symbol: "BEPR", coinGeckoId: "blockchain-euro-project", decimals: 9, price: 0.00578218}, // Addr: 0xbf0cf158e84ebacca1b7746e794d507073e5adfe, Notional: 1269.4396114071453 {chain: 4, addr: "000000000000000000000000bf37f781473f3b50e82c668352984865eac9853f", symbol: "MILK", coinGeckoId: "the-crypto-you", decimals: 18, price: 3.2174e-8}, // Addr: 0xbf37f781473f3b50e82c668352984865eac9853f, Notional: 3.2174e-8 - {chain: 4, addr: "000000000000000000000000bf5140a22578168fd562dccf235e5d43a02ce9b1", symbol: "UNI", coinGeckoId: "uniswap", decimals: 18, price: 14.02}, // Addr: 0xbf5140a22578168fd562dccf235e5d43a02ce9b1, Notional: 52.897150298199996 - {chain: 4, addr: "000000000000000000000000bf7c81fff98bbe61b40ed186e4afd6ddd01337fe", symbol: "EGLD", coinGeckoId: "wrapped-elrond", decimals: 18, price: 42.15}, // Addr: 0xbf7c81fff98bbe61b40ed186e4afd6ddd01337fe, Notional: 377.625260778 - {chain: 4, addr: "000000000000000000000000bfbee3dac982148ac793161f7362344925506903", symbol: "CATZ", coinGeckoId: "catzcoin", decimals: 18, price: 0.0000016}, // Addr: 0xbfbee3dac982148ac793161f7362344925506903, Notional: 0.19377919999999998 - {chain: 4, addr: "000000000000000000000000bfea674ce7d16e26e39e3c088810367a708ef94c", symbol: "APRIL", coinGeckoId: "april", decimals: 18, price: 0.00052407}, // Addr: 0xbfea674ce7d16e26e39e3c088810367a708ef94c, Notional: 52.93107 - {chain: 4, addr: "000000000000000000000000c0366a104b429f0806bfa98d0008daa9555b2bed", symbol: "SMARS", coinGeckoId: "safemars-protocol", decimals: 9, price: 4.424e-9}, // Addr: 0xc0366a104b429f0806bfa98d0008daa9555b2bed, Notional: 0.0017077107308792713 - {chain: 4, addr: "000000000000000000000000c0c6e4c6e70c6231b20979bda581a66f062a7967", symbol: "bATRI", coinGeckoId: "atari", decimals: 0, price: 0.0002562}, // Addr: 0xc0c6e4c6e70c6231b20979bda581a66f062a7967, Notional: 0.5902847999999999 - {chain: 4, addr: "000000000000000000000000c0ecb8499d8da2771abcbf4091db7f65158f1468", symbol: "SWTH", coinGeckoId: "switcheo", decimals: 8, price: 0.00220617}, // Addr: 0xc0ecb8499d8da2771abcbf4091db7f65158f1468, Notional: 0.00220617 - {chain: 4, addr: "000000000000000000000000c146b7cdbaff065090077151d391f4c96aa09e0c", symbol: "MCC", coinGeckoId: "multi-chain-capital-2", decimals: 9, price: 4.30849e-7}, // Addr: 0xc146b7cdbaff065090077151d391f4c96aa09e0c, Notional: 0.000006462735 - {chain: 4, addr: "000000000000000000000000c14a7747cfec02cfea62e72bb93538de6b2078e6", symbol: "GBL", coinGeckoId: "waweswaps-global-token", decimals: 18, price: 27.85}, // Addr: 0xc14a7747cfec02cfea62e72bb93538de6b2078e6, Notional: 13277.2697829035 - {chain: 4, addr: "000000000000000000000000c19fe21b4ef356f2f65894392dde4252aa083605", symbol: "WSO", coinGeckoId: "widi-soul", decimals: 18, price: 0.00000976}, // Addr: 0xc19fe21b4ef356f2f65894392dde4252aa083605, Notional: 0.000689964304152 - {chain: 4, addr: "000000000000000000000000c27a719105a987b4c34116223cae8bd8f4b5def4", symbol: "ACE", coinGeckoId: "endurance", decimals: 18, price: 2.99}, // Addr: 0xc27a719105a987b4c34116223cae8bd8f4b5def4, Notional: 12723.650015151401 - {chain: 4, addr: "000000000000000000000000c335df7c25b72eec661d5aa32a7c2b7b2a1d1874", symbol: "ICE", coinGeckoId: "ice", decimals: 18, price: 0.00734825}, // Addr: 0xc335df7c25b72eec661d5aa32a7c2b7b2a1d1874, Notional: 1011605.8506816206 - {chain: 4, addr: "000000000000000000000000c342774492b54ce5f8ac662113ed702fc1b34972", symbol: "BGEO", coinGeckoId: "geodb", decimals: 18, price: 0.00156339}, // Addr: 0xc342774492b54ce5f8ac662113ed702fc1b34972, Notional: 1563.39 - {chain: 4, addr: "000000000000000000000000c3d912863152e1afc935ad0d42d469e7c6b05b77", symbol: "LUCKY", coinGeckoId: "lucky-lion", decimals: 18, price: 0.00011951}, // Addr: 0xc3d912863152e1afc935ad0d42d469e7c6b05b77, Notional: 0.0033825398347468996 - {chain: 4, addr: "000000000000000000000000c49dde62b4a0810074721faca54aab52369f486a", symbol: "PKR", coinGeckoId: "polker", decimals: 18, price: 0.00128602}, // Addr: 0xc49dde62b4a0810074721faca54aab52369f486a, Notional: 1.0159558 - {chain: 4, addr: "000000000000000000000000c51ef828319b131b595b7ec4b28210ecf4d05ad0", symbol: "EFX", coinGeckoId: "effect-network", decimals: 18, price: 0.0108596}, // Addr: 0xc51ef828319b131b595b7ec4b28210ecf4d05ad0, Notional: 108.596 - {chain: 4, addr: "000000000000000000000000c5326b32e8baef125acd68f8bc646fd646104f1c", symbol: "ZAP", coinGeckoId: "zap", decimals: 18, price: 0.0037053}, // Addr: 0xc5326b32e8baef125acd68f8bc646fd646104f1c, Notional: 12977.023787946591 - {chain: 4, addr: "000000000000000000000000c598275452fa319d75ee5f176fd3b8384925b425", symbol: "STRM", coinGeckoId: "streamcoin", decimals: 18, price: 0.00066156}, // Addr: 0xc598275452fa319d75ee5f176fd3b8384925b425, Notional: 0.00132312 - {chain: 4, addr: "000000000000000000000000c5e6689c9c8b02be7c49912ef19e79cf24977f03", symbol: "ALPA", coinGeckoId: "alpaca", decimals: 18, price: 0.00618517}, // Addr: 0xc5e6689c9c8b02be7c49912ef19e79cf24977f03, Notional: 8.841130263293726 - {chain: 4, addr: "000000000000000000000000c6f509274fcc1f485644167cb911fd0c61545e6c", symbol: "OBS", coinGeckoId: "obsidium", decimals: 18, price: 0.00253039}, // Addr: 0xc6f509274fcc1f485644167cb911fd0c61545e6c, Notional: 2.783429 - {chain: 4, addr: "000000000000000000000000c703da39ae3b9db67c207c7bad8100e1afdc0f9c", symbol: "FRGX", coinGeckoId: "frgx-finance", decimals: 18, price: 0.02787072}, // Addr: 0xc703da39ae3b9db67c207c7bad8100e1afdc0f9c, Notional: 11826.887879828804 - {chain: 4, addr: "000000000000000000000000c732b6586a93b6b7cf5fed3470808bc74998224d", symbol: "KMON", coinGeckoId: "kryptomon", decimals: 18, price: 0.00090534}, // Addr: 0xc732b6586a93b6b7cf5fed3470808bc74998224d, Notional: 2118.678961762317 - {chain: 4, addr: "000000000000000000000000c748673057861a797275cd8a068abb95a902e8de", symbol: "BabyDoge", coinGeckoId: "baby-doge-coin", decimals: 9, price: 2.327e-9}, // Addr: 0xc748673057861a797275cd8a068abb95a902e8de, Notional: 26.622235840631316 - {chain: 4, addr: "000000000000000000000000c74cd0042c837ce59210857504ebb0859e06aa22", symbol: "SAFUYIELD", coinGeckoId: "safu-protocol", decimals: 9, price: 7.54662e-10}, // Addr: 0xc74cd0042c837ce59210857504ebb0859e06aa22, Notional: 0.0006858368256014715 - {chain: 4, addr: "000000000000000000000000c864019047b864b6ab609a968ae2725dfaee808a", symbol: "BIT", coinGeckoId: "biconomy-exchange-token", decimals: 9, price: 0.00001284}, // Addr: 0xc864019047b864b6ab609a968ae2725dfaee808a, Notional: 27805.343730270495 - {chain: 4, addr: "000000000000000000000000c8a11f433512c16ed895245f34bcc2ca44eb06bd", symbol: "KSN", coinGeckoId: "kissan", decimals: 18, price: 0.0441753}, // Addr: 0xc8a11f433512c16ed895245f34bcc2ca44eb06bd, Notional: 0.4859283 - {chain: 4, addr: "000000000000000000000000c94595b56e301f3ffedb8ccc2d672882d623e53a", symbol: "ACY", coinGeckoId: "acy-finance", decimals: 18, price: 0.00475415}, // Addr: 0xc94595b56e301f3ffedb8ccc2d672882d623e53a, Notional: 0.0475415 - {chain: 4, addr: "000000000000000000000000c9ad37e9baf41377540df5a77831db98c1915128", symbol: "GINUX", coinGeckoId: "green-shiba-inu", decimals: 18, price: 4.12228e-7}, // Addr: 0xc9ad37e9baf41377540df5a77831db98c1915128, Notional: 171.93196701590756 - {chain: 4, addr: "000000000000000000000000ca3f508b8e4dd382ee878a314789373d80a5190a", symbol: "BIFI", coinGeckoId: "beefy-finance", decimals: 18, price: 332.12}, // Addr: 0xca3f508b8e4dd382ee878a314789373d80a5190a, Notional: 3.9941847196 - {chain: 4, addr: "000000000000000000000000ca830317146bfdde71e7c0b880e2ec1f66e273ee", symbol: "GULL", coinGeckoId: "polygod", decimals: 18, price: 0.00373205}, // Addr: 0xca830317146bfdde71e7c0b880e2ec1f66e273ee, Notional: 3.73205 - {chain: 4, addr: "000000000000000000000000cafe001067cdef266afb7eb5a286dcfd277f3de5", symbol: "PSP", coinGeckoId: "paraswap", decimals: 18, price: 0.02058788}, // Addr: 0xcafe001067cdef266afb7eb5a286dcfd277f3de5, Notional: 0.1475464734019596 - {chain: 4, addr: "000000000000000000000000cbd9f6d748dd3d19416f8914528a65c7838e27d8", symbol: "RGAME", coinGeckoId: "r-games", decimals: 18, price: 0.00076567}, // Addr: 0xcbd9f6d748dd3d19416f8914528a65c7838e27d8, Notional: 0.1240687166166668 - {chain: 4, addr: "000000000000000000000000cc42724c6683b7e57334c4e856f4c9965ed682bd", symbol: "MATIC", coinGeckoId: "matic-network", decimals: 18, price: 0.587051}, // Addr: 0xcc42724c6683b7e57334c4e856f4c9965ed682bd, Notional: 4242.145429010848 - {chain: 4, addr: "000000000000000000000000ce355300b9d7909f577640a3fb179cf911a23fbb", symbol: "PPP", coinGeckoId: "playposeidon-nft", decimals: 18, price: 0.00021648}, // Addr: 0xce355300b9d7909f577640a3fb179cf911a23fbb, Notional: 2.1648 - {chain: 4, addr: "000000000000000000000000ce7de646e7208a4ef112cb6ed5038fa6cc6b12e3", symbol: "TRX", coinGeckoId: "tron-bsc", decimals: 6, price: 0.2061}, // Addr: 0xce7de646e7208a4ef112cb6ed5038fa6cc6b12e3, Notional: 2311.3245258 - {chain: 4, addr: "000000000000000000000000d06716e1ff2e492cc5034c2e81805562dd3b45fa", symbol: "MGP", coinGeckoId: "magpie", decimals: 18, price: 0.141098}, // Addr: 0xd06716e1ff2e492cc5034c2e81805562dd3b45fa, Notional: 11142111.822038738 + {chain: 4, addr: "000000000000000000000000bf5140a22578168fd562dccf235e5d43a02ce9b1", symbol: "UNI", coinGeckoId: "uniswap", decimals: 18, price: 13.19}, // Addr: 0xbf5140a22578168fd562dccf235e5d43a02ce9b1, Notional: 49.765578632899995 + {chain: 4, addr: "000000000000000000000000bf7c81fff98bbe61b40ed186e4afd6ddd01337fe", symbol: "EGLD", coinGeckoId: "wrapped-elrond", decimals: 18, price: 33.23}, // Addr: 0xbf7c81fff98bbe61b40ed186e4afd6ddd01337fe, Notional: 297.71025897159996 + {chain: 4, addr: "000000000000000000000000bfbee3dac982148ac793161f7362344925506903", symbol: "CATZ", coinGeckoId: "catzcoin", decimals: 18, price: 0.0000017}, // Addr: 0xbfbee3dac982148ac793161f7362344925506903, Notional: 0.2058904 + {chain: 4, addr: "000000000000000000000000bfea674ce7d16e26e39e3c088810367a708ef94c", symbol: "APRIL", coinGeckoId: "april", decimals: 18, price: 0.00047451}, // Addr: 0xbfea674ce7d16e26e39e3c088810367a708ef94c, Notional: 47.925509999999996 + {chain: 4, addr: "000000000000000000000000c0366a104b429f0806bfa98d0008daa9555b2bed", symbol: "SMARS", coinGeckoId: "safemars-protocol", decimals: 9, price: 5.06e-9}, // Addr: 0xc0366a104b429f0806bfa98d0008daa9555b2bed, Notional: 0.0019532134489713185 + {chain: 4, addr: "000000000000000000000000c0c6e4c6e70c6231b20979bda581a66f062a7967", symbol: "bATRI", coinGeckoId: "atari", decimals: 0, price: 0.00024964}, // Addr: 0xc0c6e4c6e70c6231b20979bda581a66f062a7967, Notional: 0.5751705599999999 + {chain: 4, addr: "000000000000000000000000c0ecb8499d8da2771abcbf4091db7f65158f1468", symbol: "SWTH", coinGeckoId: "switcheo", decimals: 8, price: 0.00188678}, // Addr: 0xc0ecb8499d8da2771abcbf4091db7f65158f1468, Notional: 0.00188678 + {chain: 4, addr: "000000000000000000000000c146b7cdbaff065090077151d391f4c96aa09e0c", symbol: "MCC", coinGeckoId: "multi-chain-capital-2", decimals: 9, price: 4.75074e-7}, // Addr: 0xc146b7cdbaff065090077151d391f4c96aa09e0c, Notional: 0.00000712611 + {chain: 4, addr: "000000000000000000000000c14a7747cfec02cfea62e72bb93538de6b2078e6", symbol: "GBL", coinGeckoId: "waweswaps-global-token", decimals: 18, price: 23.63}, // Addr: 0xc14a7747cfec02cfea62e72bb93538de6b2078e6, Notional: 11265.4177727113 + {chain: 4, addr: "000000000000000000000000c19fe21b4ef356f2f65894392dde4252aa083605", symbol: "WSO", coinGeckoId: "widi-soul", decimals: 18, price: 0.00001369}, // Addr: 0xc19fe21b4ef356f2f65894392dde4252aa083605, Notional: 0.0009677880454754999 + {chain: 4, addr: "000000000000000000000000c27a719105a987b4c34116223cae8bd8f4b5def4", symbol: "ACE", coinGeckoId: "endurance", decimals: 18, price: 2.07}, // Addr: 0xc27a719105a987b4c34116223cae8bd8f4b5def4, Notional: 8791.6128053427 + {chain: 4, addr: "000000000000000000000000c335df7c25b72eec661d5aa32a7c2b7b2a1d1874", symbol: "ICE", coinGeckoId: "ice", decimals: 18, price: 0.00555147}, // Addr: 0xc335df7c25b72eec661d5aa32a7c2b7b2a1d1874, Notional: 845614.8158940356 + {chain: 4, addr: "000000000000000000000000c342774492b54ce5f8ac662113ed702fc1b34972", symbol: "BGEO", coinGeckoId: "geodb", decimals: 18, price: 0.00019776}, // Addr: 0xc342774492b54ce5f8ac662113ed702fc1b34972, Notional: 197.76 + {chain: 4, addr: "000000000000000000000000c3d912863152e1afc935ad0d42d469e7c6b05b77", symbol: "LUCKY", coinGeckoId: "lucky-lion", decimals: 18, price: 0.00012156}, // Addr: 0xc3d912863152e1afc935ad0d42d469e7c6b05b77, Notional: 0.0034405618133363995 + {chain: 4, addr: "000000000000000000000000c49dde62b4a0810074721faca54aab52369f486a", symbol: "PKR", coinGeckoId: "polker", decimals: 18, price: 0.00219388}, // Addr: 0xc49dde62b4a0810074721faca54aab52369f486a, Notional: 1.7331652 + {chain: 4, addr: "000000000000000000000000c51ef828319b131b595b7ec4b28210ecf4d05ad0", symbol: "EFX", coinGeckoId: "effect-network", decimals: 18, price: 0.02701893}, // Addr: 0xc51ef828319b131b595b7ec4b28210ecf4d05ad0, Notional: 81.05679 + {chain: 4, addr: "000000000000000000000000c5326b32e8baef125acd68f8bc646fd646104f1c", symbol: "ZAP", coinGeckoId: "zap", decimals: 18, price: 0.00228207}, // Addr: 0xc5326b32e8baef125acd68f8bc646fd646104f1c, Notional: 7917.067864037124 + {chain: 4, addr: "000000000000000000000000c598275452fa319d75ee5f176fd3b8384925b425", symbol: "STRM", coinGeckoId: "streamcoin", decimals: 18, price: 0.00073393}, // Addr: 0xc598275452fa319d75ee5f176fd3b8384925b425, Notional: 0.00146786 + {chain: 4, addr: "000000000000000000000000c5e6689c9c8b02be7c49912ef19e79cf24977f03", symbol: "ALPA", coinGeckoId: "alpaca", decimals: 18, price: 0.00549487}, // Addr: 0xc5e6689c9c8b02be7c49912ef19e79cf24977f03, Notional: 7.8544100566136095 + {chain: 4, addr: "000000000000000000000000c6f509274fcc1f485644167cb911fd0c61545e6c", symbol: "OBS", coinGeckoId: "obsidium", decimals: 18, price: 0.00252524}, // Addr: 0xc6f509274fcc1f485644167cb911fd0c61545e6c, Notional: 2.7777640000000003 + {chain: 4, addr: "000000000000000000000000c703da39ae3b9db67c207c7bad8100e1afdc0f9c", symbol: "FRGX", coinGeckoId: "frgx-finance", decimals: 18, price: 0.02626993}, // Addr: 0xc703da39ae3b9db67c207c7bad8100e1afdc0f9c, Notional: 11147.595638754618 + {chain: 4, addr: "000000000000000000000000c732b6586a93b6b7cf5fed3470808bc74998224d", symbol: "KMON", coinGeckoId: "kryptomon", decimals: 18, price: 0.00105321}, // Addr: 0xc732b6586a93b6b7cf5fed3470808bc74998224d, Notional: 7118.062797443746 + {chain: 4, addr: "000000000000000000000000c748673057861a797275cd8a068abb95a902e8de", symbol: "BabyDoge", coinGeckoId: "baby-doge-coin", decimals: 9, price: 3.077e-9}, // Addr: 0xc748673057861a797275cd8a068abb95a902e8de, Notional: 342.03594791732337 + {chain: 4, addr: "000000000000000000000000c74cd0042c837ce59210857504ebb0859e06aa22", symbol: "SAFUYIELD", coinGeckoId: "safu-protocol", decimals: 9, price: 8.41729e-10}, // Addr: 0xc74cd0042c837ce59210857504ebb0859e06aa22, Notional: 0.0007649633152016414 + {chain: 4, addr: "000000000000000000000000c864019047b864b6ab609a968ae2725dfaee808a", symbol: "BIT", coinGeckoId: "biconomy-exchange-token", decimals: 9, price: 0.00001202}, // Addr: 0xc864019047b864b6ab609a968ae2725dfaee808a, Notional: 26029.613055907426 + {chain: 4, addr: "000000000000000000000000c8a11f433512c16ed895245f34bcc2ca44eb06bd", symbol: "KSN", coinGeckoId: "kissan", decimals: 18, price: 0.04185119}, // Addr: 0xc8a11f433512c16ed895245f34bcc2ca44eb06bd, Notional: 0.46036309000000003 + {chain: 4, addr: "000000000000000000000000c94595b56e301f3ffedb8ccc2d672882d623e53a", symbol: "ACY", coinGeckoId: "acy-finance", decimals: 18, price: 0.00418474}, // Addr: 0xc94595b56e301f3ffedb8ccc2d672882d623e53a, Notional: 0.0418474 + {chain: 4, addr: "000000000000000000000000c9ad37e9baf41377540df5a77831db98c1915128", symbol: "GINUX", coinGeckoId: "green-shiba-inu", decimals: 18, price: 2.61327e-7}, // Addr: 0xc9ad37e9baf41377540df5a77831db98c1915128, Notional: 108.994209865332 + {chain: 4, addr: "000000000000000000000000ca3f508b8e4dd382ee878a314789373d80a5190a", symbol: "BIFI", coinGeckoId: "beefy-finance", decimals: 18, price: 337.37}, // Addr: 0xca3f508b8e4dd382ee878a314789373d80a5190a, Notional: 4.0573229521 + {chain: 4, addr: "000000000000000000000000ca830317146bfdde71e7c0b880e2ec1f66e273ee", symbol: "GULL", coinGeckoId: "polygod", decimals: 18, price: 0.0038012}, // Addr: 0xca830317146bfdde71e7c0b880e2ec1f66e273ee, Notional: 3.8011999999999997 + {chain: 4, addr: "000000000000000000000000cafe001067cdef266afb7eb5a286dcfd277f3de5", symbol: "PSP", coinGeckoId: "paraswap", decimals: 18, price: 0.02347798}, // Addr: 0xcafe001067cdef266afb7eb5a286dcfd277f3de5, Notional: 0.16825885674492658 + {chain: 4, addr: "000000000000000000000000cbd9f6d748dd3d19416f8914528a65c7838e27d8", symbol: "RGAME", coinGeckoId: "r-games", decimals: 18, price: 0.00063932}, // Addr: 0xcbd9f6d748dd3d19416f8914528a65c7838e27d8, Notional: 0.1035950369054128 + {chain: 4, addr: "000000000000000000000000cc42724c6683b7e57334c4e856f4c9965ed682bd", symbol: "MATIC", coinGeckoId: "matic-network", decimals: 18, price: 0.449834}, // Addr: 0xcc42724c6683b7e57334c4e856f4c9965ed682bd, Notional: 3250.588529639956 + {chain: 4, addr: "000000000000000000000000ce355300b9d7909f577640a3fb179cf911a23fbb", symbol: "PPP", coinGeckoId: "playposeidon-nft", decimals: 18, price: 0.00030028}, // Addr: 0xce355300b9d7909f577640a3fb179cf911a23fbb, Notional: 3.0027999999999997 + {chain: 4, addr: "000000000000000000000000ce7de646e7208a4ef112cb6ed5038fa6cc6b12e3", symbol: "TRX", coinGeckoId: "tron-bsc", decimals: 6, price: 0.25417}, // Addr: 0xce7de646e7208a4ef112cb6ed5038fa6cc6b12e3, Notional: 1173.89021178373 + {chain: 4, addr: "000000000000000000000000d06716e1ff2e492cc5034c2e81805562dd3b45fa", symbol: "MGP", coinGeckoId: "magpie", decimals: 18, price: 0.131271}, // Addr: 0xd06716e1ff2e492cc5034c2e81805562dd3b45fa, Notional: 16359172.699060624 {chain: 4, addr: "000000000000000000000000d069599e718f963bd84502b49ba8f8657faf5b3a", symbol: "PLAY", coinGeckoId: "xcad-network-play", decimals: 18, price: 0.00022962}, // Addr: 0xd069599e718f963bd84502b49ba8f8657faf5b3a, Notional: 575.783441817958 - {chain: 4, addr: "000000000000000000000000d17479997f34dd9156deef8f95a52d81d265be9c", symbol: "USDD", coinGeckoId: "usdd", decimals: 18, price: 0.994239}, // Addr: 0xd17479997f34dd9156deef8f95a52d81d265be9c, Notional: 0.00401547281886 - {chain: 4, addr: "000000000000000000000000d32d01a43c869edcd1117c640fbdcfcfd97d9d65", symbol: "NMX", coinGeckoId: "nominex", decimals: 18, price: 0.00591385}, // Addr: 0xd32d01a43c869edcd1117c640fbdcfcfd97d9d65, Notional: 0.011801408501362501 - {chain: 4, addr: "000000000000000000000000d3b71117e6c1558c1553305b44988cd944e97300", symbol: "YEL", coinGeckoId: "yel-finance", decimals: 18, price: 0.00285637}, // Addr: 0xd3b71117e6c1558c1553305b44988cd944e97300, Notional: 0.135410743483169 - {chain: 4, addr: "000000000000000000000000d691d9a68c887bdf34da8c36f63487333acfd103", symbol: "MAV", coinGeckoId: "maverick-protocol", decimals: 18, price: 0.290188}, // Addr: 0xd691d9a68c887bdf34da8c36f63487333acfd103, Notional: 3.62828355510916 - {chain: 4, addr: "000000000000000000000000d74b782e05aa25c50e7330af541d46e18f36661c", symbol: "QUACK", coinGeckoId: "richquack", decimals: 9, price: 7.8321e-10}, // Addr: 0xd74b782e05aa25c50e7330af541d46e18f36661c, Notional: 95.05246670709634 + {chain: 4, addr: "000000000000000000000000d17479997f34dd9156deef8f95a52d81d265be9c", symbol: "USDD", coinGeckoId: "usdd", decimals: 18, price: 0.997284}, // Addr: 0xd17479997f34dd9156deef8f95a52d81d265be9c, Notional: 0.00402777078216 + {chain: 4, addr: "000000000000000000000000d32d01a43c869edcd1117c640fbdcfcfd97d9d65", symbol: "NMX", coinGeckoId: "nominex", decimals: 18, price: 0.00489688}, // Addr: 0xd32d01a43c869edcd1117c640fbdcfcfd97d9d65, Notional: 0.00977198969574 + {chain: 4, addr: "000000000000000000000000d3b71117e6c1558c1553305b44988cd944e97300", symbol: "YEL", coinGeckoId: "yel-finance", decimals: 18, price: 0.00154947}, // Addr: 0xd3b71117e6c1558c1553305b44988cd944e97300, Notional: 0.073455079245639 + {chain: 4, addr: "000000000000000000000000d691d9a68c887bdf34da8c36f63487333acfd103", symbol: "MAV", coinGeckoId: "maverick-protocol", decimals: 18, price: 0.196557}, // Addr: 0xd691d9a68c887bdf34da8c36f63487333acfd103, Notional: 2.45759483762799 + {chain: 4, addr: "000000000000000000000000d74b782e05aa25c50e7330af541d46e18f36661c", symbol: "QUACK", coinGeckoId: "richquack", decimals: 9, price: 8.13767e-10}, // Addr: 0xd74b782e05aa25c50e7330af541d46e18f36661c, Notional: 98.76094620195563 {chain: 4, addr: "000000000000000000000000d9907fcda91ac644f70477b8fc1607ad15b2d7a8", symbol: "multiBTC", coinGeckoId: "multibtc", decimals: 8, price: 2084.41}, // Addr: 0xd9907fcda91ac644f70477b8fc1607ad15b2d7a8, Notional: 0.0416882 - {chain: 4, addr: "000000000000000000000000dd325c38b12903b727d16961e61333f4871a70e0", symbol: "TRUNK", coinGeckoId: "elephant-money-trunk", decimals: 18, price: 0.174358}, // Addr: 0xdd325c38b12903b727d16961e61333f4871a70e0, Notional: 4797619.704749784 - {chain: 4, addr: "000000000000000000000000de7d1ce109236b12809c45b23d22f30dba0ef424", symbol: "USDS", coinGeckoId: "spiceusd", decimals: 18, price: 0.118055}, // Addr: 0xde7d1ce109236b12809c45b23d22f30dba0ef424, Notional: 0.118055 - {chain: 4, addr: "000000000000000000000000e2604c9561d490624aa35e156e65e590eb749519", symbol: "GM", coinGeckoId: "goldminer", decimals: 18, price: 9.91158e-7}, // Addr: 0xe2604c9561d490624aa35e156e65e590eb749519, Notional: 53.29341605090662 - {chain: 4, addr: "000000000000000000000000e29142e14e52bdfbb8108076f66f49661f10ec10", symbol: "SEILOR", coinGeckoId: "kryptonite", decimals: 18, price: 0.02086782}, // Addr: 0xe29142e14e52bdfbb8108076f66f49661f10ec10, Notional: 20923.714159221207 - {chain: 4, addr: "000000000000000000000000e2e7329499e8ddb1f2b04ee4b35a8d7f6881e4ea", symbol: "$ANRX", coinGeckoId: "anrkey-x", decimals: 18, price: 0.00011313}, // Addr: 0xe2e7329499e8ddb1f2b04ee4b35a8d7f6881e4ea, Notional: 28.339176998699998 - {chain: 4, addr: "000000000000000000000000e4ca1f75eca6214393fce1c1b316c237664eaa8e", symbol: "ORN", coinGeckoId: "orion-protocol", decimals: 8, price: 1.7}, // Addr: 0xe4ca1f75eca6214393fce1c1b316c237664eaa8e, Notional: 940.217604606 - {chain: 4, addr: "000000000000000000000000e4cc45bb5dbda06db6183e8bf016569f40497aa5", symbol: "GAL", coinGeckoId: "project-galaxy", decimals: 18, price: 2.19}, // Addr: 0xe4cc45bb5dbda06db6183e8bf016569f40497aa5, Notional: 21.75327 - {chain: 4, addr: "000000000000000000000000e4e11e02aa14c7f24db749421986eaec1369e8c9", symbol: "MNTC", coinGeckoId: "minativerse", decimals: 18, price: 0.763277}, // Addr: 0xe4e11e02aa14c7f24db749421986eaec1369e8c9, Notional: 1.5341867699999998 - {chain: 4, addr: "000000000000000000000000e4fae3faa8300810c835970b9187c268f55d998f", symbol: "CATE", coinGeckoId: "catecoin", decimals: 9, price: 2.37529e-7}, // Addr: 0xe4fae3faa8300810c835970b9187c268f55d998f, Notional: 0.0016028998067688916 - {chain: 4, addr: "000000000000000000000000e552fb52a4f19e44ef5a967632dbc320b0820639", symbol: "Metis", coinGeckoId: "metis-token", decimals: 18, price: 58.02}, // Addr: 0xe552fb52a4f19e44ef5a967632dbc320b0820639, Notional: 491131.2511888446 - {chain: 4, addr: "000000000000000000000000e60eaf5a997dfae83739e035b005a33afdcc6df5", symbol: "DERI", coinGeckoId: "deri-protocol", decimals: 18, price: 0.00898319}, // Addr: 0xe60eaf5a997dfae83739e035b005a33afdcc6df5, Notional: 0.004491595 - {chain: 4, addr: "000000000000000000000000e7c9c6bc87b86f9e5b57072f907ee6460b593924", symbol: "TOWER", coinGeckoId: "tower", decimals: 18, price: 0.00180963}, // Addr: 0xe7c9c6bc87b86f9e5b57072f907ee6460b593924, Notional: 2.7253506345976684 - {chain: 4, addr: "000000000000000000000000e8670901e86818745b28c8b30b17986958fce8cc", symbol: "XCT", coinGeckoId: "citadel-one", decimals: 6, price: 0.00113352}, // Addr: 0xe8670901e86818745b28c8b30b17986958fce8cc, Notional: 0.00113352 - {chain: 4, addr: "000000000000000000000000e9c803f48dffe50180bd5b01dc04da939e3445fc", symbol: "VLX", coinGeckoId: "velas", decimals: 18, price: 0.01752049}, // Addr: 0xe9c803f48dffe50180bd5b01dc04da939e3445fc, Notional: 0.1222616061366349 - {chain: 4, addr: "000000000000000000000000e9e7cea3dedca5984780bafc599bd69add087d56", symbol: "BUSD", coinGeckoId: "binance-usd", decimals: 18, price: 0.991874}, // Addr: 0xe9e7cea3dedca5984780bafc599bd69add087d56, Notional: 117867.71900013703 - {chain: 4, addr: "000000000000000000000000ebbaeff6217d22e7744394061d874015709b8141", symbol: "WAM", coinGeckoId: "wam", decimals: 18, price: 0.00364388}, // Addr: 0xebbaeff6217d22e7744394061d874015709b8141, Notional: 66173.8239353784 - {chain: 4, addr: "000000000000000000000000eca41281c24451168a37211f0bc2b8645af45092", symbol: "TPT", coinGeckoId: "token-pocket", decimals: 4, price: 0.00782978}, // Addr: 0xeca41281c24451168a37211f0bc2b8645af45092, Notional: 1.565956 - {chain: 4, addr: "000000000000000000000000ed28a457a5a76596ac48d87c0f577020f6ea1c4c", symbol: "pBTC", coinGeckoId: "ptokens-btc", decimals: 18, price: 1340.33}, // Addr: 0xed28a457a5a76596ac48d87c0f577020f6ea1c4c, Notional: 0.26815982309999997 - {chain: 4, addr: "000000000000000000000000f16e81dce15b08f326220742020379b855b87df9", symbol: "ICE", coinGeckoId: "ice-token", decimals: 18, price: 0.485954}, // Addr: 0xf16e81dce15b08f326220742020379b855b87df9, Notional: 2.9081389481146798 - {chain: 4, addr: "000000000000000000000000f21768ccbc73ea5b6fd3c687208a7c2def2d966e", symbol: "REEF", coinGeckoId: "reef", decimals: 18, price: 0.00166238}, // Addr: 0xf21768ccbc73ea5b6fd3c687208a7c2def2d966e, Notional: 690.8406168646986 - {chain: 4, addr: "000000000000000000000000f218184af829cf2b0019f8e6f0b2423498a36983", symbol: "MATH", coinGeckoId: "math", decimals: 18, price: 0.312206}, // Addr: 0xf218184af829cf2b0019f8e6f0b2423498a36983, Notional: 283.82436576710825 + {chain: 4, addr: "000000000000000000000000dd325c38b12903b727d16961e61333f4871a70e0", symbol: "TRUNK", coinGeckoId: "elephant-money-trunk", decimals: 18, price: 0.133907}, // Addr: 0xdd325c38b12903b727d16961e61333f4871a70e0, Notional: 3603105.5534415026 + {chain: 4, addr: "000000000000000000000000de7d1ce109236b12809c45b23d22f30dba0ef424", symbol: "USDS", coinGeckoId: "spiceusd", decimals: 18, price: 0.112356}, // Addr: 0xde7d1ce109236b12809c45b23d22f30dba0ef424, Notional: 0.112356 + {chain: 4, addr: "000000000000000000000000e2604c9561d490624aa35e156e65e590eb749519", symbol: "GM", coinGeckoId: "goldminer", decimals: 18, price: 0.000001}, // Addr: 0xe2604c9561d490624aa35e156e65e590eb749519, Notional: 53.76884013538368 + {chain: 4, addr: "000000000000000000000000e29142e14e52bdfbb8108076f66f49661f10ec10", symbol: "SEILOR", coinGeckoId: "kryptonite", decimals: 18, price: 0.01182767}, // Addr: 0xe29142e14e52bdfbb8108076f66f49661f10ec10, Notional: 11859.350245957456 + {chain: 4, addr: "000000000000000000000000e2e7329499e8ddb1f2b04ee4b35a8d7f6881e4ea", symbol: "$ANRX", coinGeckoId: "anrkey-x", decimals: 18, price: 0.00011762}, // Addr: 0xe2e7329499e8ddb1f2b04ee4b35a8d7f6881e4ea, Notional: 29.4639264438 + {chain: 4, addr: "000000000000000000000000e4ca1f75eca6214393fce1c1b316c237664eaa8e", symbol: "ORN", coinGeckoId: "orion-protocol", decimals: 8, price: 1.45}, // Addr: 0xe4ca1f75eca6214393fce1c1b316c237664eaa8e, Notional: 801.950309811 + {chain: 4, addr: "000000000000000000000000e4cc45bb5dbda06db6183e8bf016569f40497aa5", symbol: "GAL", coinGeckoId: "project-galaxy", decimals: 18, price: 1.94}, // Addr: 0xe4cc45bb5dbda06db6183e8bf016569f40497aa5, Notional: 19.27002 + {chain: 4, addr: "000000000000000000000000e4e11e02aa14c7f24db749421986eaec1369e8c9", symbol: "MNTC", coinGeckoId: "minativerse", decimals: 18, price: 0.788096}, // Addr: 0xe4e11e02aa14c7f24db749421986eaec1369e8c9, Notional: 1.5840729599999999 + {chain: 4, addr: "000000000000000000000000e4fae3faa8300810c835970b9187c268f55d998f", symbol: "CATE", coinGeckoId: "catecoin", decimals: 9, price: 2.13572e-7}, // Addr: 0xe4fae3faa8300810c835970b9187c268f55d998f, Notional: 0.0014412325127931567 + {chain: 4, addr: "000000000000000000000000e552fb52a4f19e44ef5a967632dbc320b0820639", symbol: "Metis", coinGeckoId: "metis-token", decimals: 18, price: 42.28}, // Addr: 0xe552fb52a4f19e44ef5a967632dbc320b0820639, Notional: 357894.3347167244 + {chain: 4, addr: "000000000000000000000000e60eaf5a997dfae83739e035b005a33afdcc6df5", symbol: "DERI", coinGeckoId: "deri-protocol", decimals: 18, price: 0.01981173}, // Addr: 0xe60eaf5a997dfae83739e035b005a33afdcc6df5, Notional: 0.009905865 + {chain: 4, addr: "000000000000000000000000e7c9c6bc87b86f9e5b57072f907ee6460b593924", symbol: "TOWER", coinGeckoId: "tower", decimals: 18, price: 0.00163846}, // Addr: 0xe7c9c6bc87b86f9e5b57072f907ee6460b593924, Notional: 2.4675640881080088 + {chain: 4, addr: "000000000000000000000000e8670901e86818745b28c8b30b17986958fce8cc", symbol: "XCT", coinGeckoId: "citadel-one", decimals: 6, price: 0.00079445}, // Addr: 0xe8670901e86818745b28c8b30b17986958fce8cc, Notional: 0.00079445 + {chain: 4, addr: "000000000000000000000000e9c803f48dffe50180bd5b01dc04da939e3445fc", symbol: "VLX", coinGeckoId: "velas", decimals: 18, price: 0.01016328}, // Addr: 0xe9c803f48dffe50180bd5b01dc04da939e3445fc, Notional: 0.07092147174059281 + {chain: 4, addr: "000000000000000000000000e9e7cea3dedca5984780bafc599bd69add087d56", symbol: "BUSD", coinGeckoId: "binance-usd", decimals: 18, price: 0.994995}, // Addr: 0xe9e7cea3dedca5984780bafc599bd69add087d56, Notional: 113139.08821374403 + {chain: 4, addr: "000000000000000000000000ebbaeff6217d22e7744394061d874015709b8141", symbol: "WAM", coinGeckoId: "wam", decimals: 18, price: 0.00256847}, // Addr: 0xebbaeff6217d22e7744394061d874015709b8141, Notional: 48011.660359224195 + {chain: 4, addr: "000000000000000000000000eca41281c24451168a37211f0bc2b8645af45092", symbol: "TPT", coinGeckoId: "token-pocket", decimals: 4, price: 0.00711216}, // Addr: 0xeca41281c24451168a37211f0bc2b8645af45092, Notional: 1.4224320000000001 + {chain: 4, addr: "000000000000000000000000ed28a457a5a76596ac48d87c0f577020f6ea1c4c", symbol: "pBTC", coinGeckoId: "ptokens-btc", decimals: 18, price: 2162.93}, // Addr: 0xed28a457a5a76596ac48d87c0f577020f6ea1c4c, Notional: 0.43273740509999997 + {chain: 4, addr: "000000000000000000000000f16e81dce15b08f326220742020379b855b87df9", symbol: "ICE", coinGeckoId: "ice-token", decimals: 18, price: 0.302589}, // Addr: 0xf16e81dce15b08f326220742020379b855b87df9, Notional: 1.81081101538638 + {chain: 4, addr: "000000000000000000000000f21768ccbc73ea5b6fd3c687208a7c2def2d966e", symbol: "REEF", coinGeckoId: "reef", decimals: 18, price: 0.0010211}, // Addr: 0xf21768ccbc73ea5b6fd3c687208a7c2def2d966e, Notional: 424.3684744707404 + {chain: 4, addr: "000000000000000000000000f218184af829cf2b0019f8e6f0b2423498a36983", symbol: "MATH", coinGeckoId: "math", decimals: 18, price: 0.261832}, // Addr: 0xf218184af829cf2b0019f8e6f0b2423498a36983, Notional: 238.02970262433615 {chain: 4, addr: "000000000000000000000000f2c9c8e016a511eb0bf4823e340c3567d6de1390", symbol: "LAIKA", coinGeckoId: "laikaverse", decimals: 18, price: 0.00000686}, // Addr: 0xf2c9c8e016a511eb0bf4823e340c3567d6de1390, Notional: 6.86e-14 - {chain: 4, addr: "000000000000000000000000f486ad071f3bee968384d2e39e2d8af0fcf6fd46", symbol: "VELO", coinGeckoId: "velo", decimals: 18, price: 0.01852156}, // Addr: 0xf486ad071f3bee968384d2e39e2d8af0fcf6fd46, Notional: 92.1103420146208 - {chain: 4, addr: "000000000000000000000000f585b5b4f22816baf7629aea55b701662630397b", symbol: "VOW", coinGeckoId: "vow", decimals: 18, price: 0.095688}, // Addr: 0xf585b5b4f22816baf7629aea55b701662630397b, Notional: 5.21921353280544 - {chain: 4, addr: "000000000000000000000000f64ed9ad397a1ae657f31131d4b189220a7f1cc7", symbol: "DFIAT", coinGeckoId: "defiato", decimals: 18, price: 0.00135615}, // Addr: 0xf64ed9ad397a1ae657f31131d4b189220a7f1cc7, Notional: 0.6219981975 - {chain: 4, addr: "000000000000000000000000f7844cb890f4c339c497aeab599abdc3c874b67a", symbol: "NFTART", coinGeckoId: "nft-art-finance", decimals: 9, price: 1.6538e-11}, // Addr: 0xf7844cb890f4c339c497aeab599abdc3c874b67a, Notional: 1.05686973783e-11 - {chain: 4, addr: "000000000000000000000000f7de7e8a6bd59ed41a4b5fe50278b3b7f31384df", symbol: "RDNT", coinGeckoId: "radiant-capital", decimals: 18, price: 0.083389}, // Addr: 0xf7de7e8a6bd59ed41a4b5fe50278b3b7f31384df, Notional: 8.99460802806541 - {chain: 4, addr: "000000000000000000000000f915fdda4c882731c0456a4214548cd13a822886", symbol: "UNV", coinGeckoId: "unvest", decimals: 18, price: 0.00287415}, // Addr: 0xf915fdda4c882731c0456a4214548cd13a822886, Notional: 33.5183373 - {chain: 4, addr: "000000000000000000000000f92d62ed69242d655e685c96b98f32f1409c3262", symbol: "A4M", coinGeckoId: "alienform", decimals: 9, price: 0.00002495}, // Addr: 0xf92d62ed69242d655e685c96b98f32f1409c3262, Notional: 1.0027703432735904 - {chain: 4, addr: "000000000000000000000000f952fc3ca7325cc27d15885d37117676d25bfda6", symbol: "EGG", coinGeckoId: "goose-finance", decimals: 18, price: 0.01084224}, // Addr: 0xf952fc3ca7325cc27d15885d37117676d25bfda6, Notional: 0.2168448 - {chain: 4, addr: "000000000000000000000000fa40d8fc324bcdd6bbae0e086de886c571c225d4", symbol: "WZRD", coinGeckoId: "wizardia", decimals: 18, price: 0.00262162}, // Addr: 0xfa40d8fc324bcdd6bbae0e086de886c571c225d4, Notional: 8048.016476452033 - {chain: 4, addr: "000000000000000000000000fafd4cb703b25cb22f43d017e7e0d75febc26743", symbol: "WEYU", coinGeckoId: "weyu", decimals: 18, price: 0.00004931}, // Addr: 0xfafd4cb703b25cb22f43d017e7e0d75febc26743, Notional: 187355.2921628152 - {chain: 4, addr: "000000000000000000000000fb288d60d3b66f9c3e231a9a39ed3f158a4269aa", symbol: "PPAY", coinGeckoId: "plasma-finance", decimals: 18, price: 0.00010068}, // Addr: 0xfb288d60d3b66f9c3e231a9a39ed3f158a4269aa, Notional: 0.005189541563970001 - {chain: 4, addr: "000000000000000000000000fb5b838b6cfeedc2873ab27866079ac55363d37e", symbol: "FLOKI", coinGeckoId: "floki", decimals: 9, price: 0.00022274}, // Addr: 0xfb5b838b6cfeedc2873ab27866079ac55363d37e, Notional: 677.7909327733339 - {chain: 4, addr: "000000000000000000000000fb6115445bff7b52feb98650c87f44907e58f802", symbol: "AAVE", coinGeckoId: "aave", decimals: 18, price: 221.33}, // Addr: 0xfb6115445bff7b52feb98650c87f44907e58f802, Notional: 144.644201324 - {chain: 4, addr: "000000000000000000000000fb9c339b4bace4fe63ccc1dd9a3c3c531441d5fe", symbol: "SHILL", coinGeckoId: "shill-token", decimals: 18, price: 0.00081203}, // Addr: 0xfb9c339b4bace4fe63ccc1dd9a3c3c531441d5fe, Notional: 4.730610435537167 - {chain: 4, addr: "000000000000000000000000fbc4f3f645c4003a2e4f4e9b51077d2daa9a9341", symbol: "ZEDXION", coinGeckoId: "zedxion", decimals: 18, price: 0.344933}, // Addr: 0xfbc4f3f645c4003a2e4f4e9b51077d2daa9a9341, Notional: 99930.87538973702 - {chain: 4, addr: "000000000000000000000000fce146bf3146100cfe5db4129cf6c82b0ef4ad8c", symbol: "renBTC", coinGeckoId: "renbtc", decimals: 8, price: 91170}, // Addr: 0xfce146bf3146100cfe5db4129cf6c82b0ef4ad8c, Notional: 73.9470753 - {chain: 4, addr: "000000000000000000000000fd7b3a77848f1c2d67e05e54d78d174a0c850335", symbol: "ONT", coinGeckoId: "binance-peg-ontology", decimals: 18, price: 0.287467}, // Addr: 0xfd7b3a77848f1c2d67e05e54d78d174a0c850335, Notional: 0.0287467 - {chain: 4, addr: "000000000000000000000000fdfd27ae39cebefdbaac8615f18aa68ddd0f15f5", symbol: "GHD", coinGeckoId: "giftedhands", decimals: 18, price: 0.00000229}, // Addr: 0xfdfd27ae39cebefdbaac8615f18aa68ddd0f15f5, Notional: 0.00022671 - {chain: 4, addr: "000000000000000000000000fe19f0b51438fd612f6fd59c1dbb3ea319f433ba", symbol: "MIM", coinGeckoId: "magic-internet-money", decimals: 18, price: 0.99491}, // Addr: 0xfe19f0b51438fd612f6fd59c1dbb3ea319f433ba, Notional: 1000.3365794987109 - {chain: 4, addr: "000000000000000000000000fe56d5892bdffc7bf58f2e84be1b2c32d21c308b", symbol: "KNC", coinGeckoId: "kyber-network-crystal", decimals: 18, price: 0.663511}, // Addr: 0xfe56d5892bdffc7bf58f2e84be1b2c32d21c308b, Notional: 2.69428900093571 - {chain: 4, addr: "000000000000000000000000ffba7529ac181c2ee1844548e6d7061c9a597df4", symbol: "CAPS", coinGeckoId: "coin-capsule", decimals: 18, price: 0.00440586}, // Addr: 0xffba7529ac181c2ee1844548e6d7061c9a597df4, Notional: 0.0660879 - {chain: 5, addr: "000000000000000000000000011734f6ed20e8d011d85cf7894814b897420acf", symbol: "ACRE", coinGeckoId: "arable-protocol", decimals: 18, price: 0.00016442}, // Addr: 0x011734f6ed20e8d011d85cf7894814b897420acf, Notional: 0.005734008810085799 - {chain: 5, addr: "0000000000000000000000000308a3a9c433256ad7ef24dbef9c49c8cb01300a", symbol: "GPO", coinGeckoId: "goldpesa-option", decimals: 18, price: 0.84812}, // Addr: 0x0308a3a9c433256ad7ef24dbef9c49c8cb01300a, Notional: 20.35488 - {chain: 5, addr: "000000000000000000000000039d2e8f097331278bd6c1415d839310e0d5ece4", symbol: "LINDA", coinGeckoId: "linda-2", decimals: 18, price: 0.00000854}, // Addr: 0x039d2e8f097331278bd6c1415d839310e0d5ece4, Notional: 9.68663289381291 - {chain: 5, addr: "00000000000000000000000003b54a6e9a984069379fae1a4fc4dbae93b3bccd", symbol: "wstETH", coinGeckoId: "wrapped-steth", decimals: 18, price: 4258.57}, // Addr: 0x03b54a6e9a984069379fae1a4fc4dbae93b3bccd, Notional: 39.7528140646 - {chain: 5, addr: "00000000000000000000000004429fbb948bbd09327763214b45e505a5293346", symbol: "ABR", coinGeckoId: "allbridge", decimals: 18, price: 0.116295}, // Addr: 0x04429fbb948bbd09327763214b45e505a5293346, Notional: 42.50535463474845 - {chain: 5, addr: "00000000000000000000000008e175a1eac9744a0f1ccaeb8f669af6a2bda3ce", symbol: "E8", coinGeckoId: "energy8", decimals: 9, price: 1.8706e-8}, // Addr: 0x08e175a1eac9744a0f1ccaeb8f669af6a2bda3ce, Notional: 239.19637688142734 - {chain: 5, addr: "0000000000000000000000000b3f868e0be5597d5db7feb59e1cadbb0fdda50a", symbol: "SUSHI", coinGeckoId: "sushi", decimals: 18, price: 1.35}, // Addr: 0x0b3f868e0be5597d5db7feb59e1cadbb0fdda50a, Notional: 507.5881672095 - {chain: 5, addr: "0000000000000000000000000d500b1d8e8ef31e21c99d1db9a6444d3adf1270", symbol: "WMATIC", coinGeckoId: "wmatic", decimals: 18, price: 0.586493}, // Addr: 0x0d500b1d8e8ef31e21c99d1db9a6444d3adf1270, Notional: 447716.77908307884 - {chain: 5, addr: "0000000000000000000000000d6ae2a429df13e44a07cd2969e085e4833f64a0", symbol: "PBR", coinGeckoId: "polkabridge", decimals: 18, price: 0.03818387}, // Addr: 0x0d6ae2a429df13e44a07cd2969e085e4833f64a0, Notional: 401.0369684552685 - {chain: 5, addr: "0000000000000000000000000df0f72ee0e5c9b7ca761ecec42754992b2da5bf", symbol: "ATA", coinGeckoId: "automata", decimals: 18, price: 0.121332}, // Addr: 0x0df0f72ee0e5c9b7ca761ecec42754992b2da5bf, Notional: 5925.592246314342 - {chain: 5, addr: "000000000000000000000000111111517e4929d3dcbdfa7cce55d30d4b6bc4d6", symbol: "ICHI", coinGeckoId: "ichi-farm", decimals: 18, price: 1.13}, // Addr: 0x111111517e4929d3dcbdfa7cce55d30d4b6bc4d6, Notional: 0.0280041233 - {chain: 5, addr: "0000000000000000000000001379e8886a944d2d9d440b3d88df536aea08d9f3", symbol: "MYST", coinGeckoId: "mysterium", decimals: 18, price: 0.233114}, // Addr: 0x1379e8886a944d2d9d440b3d88df536aea08d9f3, Notional: 0.37717448439972 - {chain: 5, addr: "00000000000000000000000018e73a5333984549484348a94f4d219f4fab7b81", symbol: "DUCKIES", coinGeckoId: "duckies", decimals: 8, price: 0.00327135}, // Addr: 0x18e73a5333984549484348a94f4d219f4fab7b81, Notional: 0.0327135 - {chain: 5, addr: "00000000000000000000000018ec0a6e18e5bc3784fdd3a3634b31245ab704f6", symbol: "EURe", coinGeckoId: "monerium-eur-money", decimals: 18, price: 1.049}, // Addr: 0x18ec0a6e18e5bc3784fdd3a3634b31245ab704f6, Notional: 0.3147 - {chain: 5, addr: "0000000000000000000000001a13f4ca1d028320a707d99520abfefca3998b7f", symbol: "amUSDC", coinGeckoId: "aave-polygon-usdc", decimals: 6, price: 1}, // Addr: 0x1a13f4ca1d028320a707d99520abfefca3998b7f, Notional: 19.576248 - {chain: 5, addr: "0000000000000000000000001b815d120b3ef02039ee11dc2d33de7aa4a8c603", symbol: "WOO", coinGeckoId: "woo-network", decimals: 18, price: 0.294151}, // Addr: 0x1b815d120b3ef02039ee11dc2d33de7aa4a8c603, Notional: 20.396430340000002 - {chain: 5, addr: "0000000000000000000000001bfd67037b42cf73acf2047067bd4f2c47d9bfd6", symbol: "WBTC", coinGeckoId: "wrapped-bitcoin", decimals: 8, price: 94688}, // Addr: 0x1bfd67037b42cf73acf2047067bd4f2c47d9bfd6, Notional: 35368.62683904 - {chain: 5, addr: "0000000000000000000000001d734a02ef1e1f5886e66b0673b71af5b53ffa94", symbol: "SD", coinGeckoId: "stader", decimals: 18, price: 1.026}, // Addr: 0x1d734a02ef1e1f5886e66b0673b71af5b53ffa94, Notional: 155.78957413494 - {chain: 5, addr: "000000000000000000000000200c234721b5e549c3693ccc93cf191f90dc2af9", symbol: "METAL", coinGeckoId: "drunk-robots", decimals: 18, price: 0.01704866}, // Addr: 0x200c234721b5e549c3693ccc93cf191f90dc2af9, Notional: 1.9760941557120328 - {chain: 5, addr: "000000000000000000000000229b1b6c23ff8953d663c4cbb519717e323a0a84", symbol: "BLOK", coinGeckoId: "bloktopia", decimals: 18, price: 0.00084917}, // Addr: 0x229b1b6c23ff8953d663c4cbb519717e323a0a84, Notional: 0.0669603096063776 - {chain: 5, addr: "00000000000000000000000022e3f02f86bc8ea0d73718a2ae8851854e62adc5", symbol: "FLAME", coinGeckoId: "firestarter", decimals: 18, price: 0.02861002}, // Addr: 0x22e3f02f86bc8ea0d73718a2ae8851854e62adc5, Notional: 4284.563624980929 - {chain: 5, addr: "000000000000000000000000236aa50979d5f3de3bd1eeb40e81137f22ab794b", symbol: "tBTC", coinGeckoId: "tbtc", decimals: 18, price: 94760}, // Addr: 0x236aa50979d5f3de3bd1eeb40e81137f22ab794b, Notional: 0.025585200000000002 - {chain: 5, addr: "00000000000000000000000023d29d30e35c5e8d321e1dc9a8a61bfd846d4c5c", symbol: "HEX", coinGeckoId: "hex", decimals: 8, price: 0.00436553}, // Addr: 0x23d29d30e35c5e8d321e1dc9a8a61bfd846d4c5c, Notional: 2.699047423046697 - {chain: 5, addr: "00000000000000000000000023e8b6a3f6891254988b84da3738d2bfe5e703b9", symbol: "WELT", coinGeckoId: "fabwelt", decimals: 18, price: 0.00323882}, // Addr: 0x23e8b6a3f6891254988b84da3738d2bfe5e703b9, Notional: 1.5870218 - {chain: 5, addr: "00000000000000000000000024834bbec7e39ef42f4a75eaf8e5b6486d3f0e57", symbol: "LUNA", coinGeckoId: "wrapped-terra", decimals: 18, price: 0.00004969}, // Addr: 0x24834bbec7e39ef42f4a75eaf8e5b6486d3f0e57, Notional: 17.512859337796943 - {chain: 5, addr: "00000000000000000000000025788a1a171ec66da6502f9975a15b609ff54cf6", symbol: "POOL", coinGeckoId: "pooltogether", decimals: 18, price: 0.894748}, // Addr: 0x25788a1a171ec66da6502f9975a15b609ff54cf6, Notional: 15.210716 - {chain: 5, addr: "0000000000000000000000002598c30330d5771ae9f983979209486ae26de875", symbol: "AI", coinGeckoId: "any-inu", decimals: 18, price: 0.00000789}, // Addr: 0x2598c30330d5771ae9f983979209486ae26de875, Notional: 7.890000000000001 - {chain: 5, addr: "0000000000000000000000002791bca1f2de4661ed88a30c99a7a9449aa84174", symbol: "USDC", coinGeckoId: "usd-coin", decimals: 6, price: 1}, // Addr: 0x2791bca1f2de4661ed88a30c99a7a9449aa84174, Notional: 3725120.001171 - {chain: 5, addr: "0000000000000000000000002ab0e9e4ee70fff1fb9d67031e44f6410170d00e", symbol: "mXEN", coinGeckoId: "xen-crypto-matic", decimals: 18, price: 1.6983e-10}, // Addr: 0x2ab0e9e4ee70fff1fb9d67031e44f6410170d00e, Notional: 17.618991993730845 - {chain: 5, addr: "0000000000000000000000002ab4f9ac80f33071211729e45cfc346c1f8446d5", symbol: "CGG", coinGeckoId: "chain-guardians", decimals: 18, price: 0.01115428}, // Addr: 0x2ab4f9ac80f33071211729e45cfc346c1f8446d5, Notional: 0.01115428 - {chain: 5, addr: "0000000000000000000000002ad2934d5bfb7912304754479dd1f096d5c807da", symbol: "AGC", coinGeckoId: "argocoin", decimals: 18, price: 0.339441}, // Addr: 0x2ad2934d5bfb7912304754479dd1f096d5c807da, Notional: 33.9441 - {chain: 5, addr: "0000000000000000000000002c89bbc92bd86f8075d1decc58c7f4e0107f286b", symbol: "AVAX", coinGeckoId: "wrapped-avax", decimals: 18, price: 47.01}, // Addr: 0x2c89bbc92bd86f8075d1decc58c7f4e0107f286b, Notional: 4828.195713861 - {chain: 5, addr: "0000000000000000000000002d66953fc2eb650f0fd992dbe1e71d743a4e9fee", symbol: "NOTES", coinGeckoId: "backstage-pass-notes", decimals: 9, price: 0.00584443}, // Addr: 0x2d66953fc2eb650f0fd992dbe1e71d743a4e9fee, Notional: 0.584443 - {chain: 5, addr: "0000000000000000000000002e1ad108ff1d8c782fcbbb89aad783ac49586756", symbol: "TUSD", coinGeckoId: "true-usd", decimals: 18, price: 1.001}, // Addr: 0x2e1ad108ff1d8c782fcbbb89aad783ac49586756, Notional: 4.740130685289999 + {chain: 4, addr: "000000000000000000000000f486ad071f3bee968384d2e39e2d8af0fcf6fd46", symbol: "VELO", coinGeckoId: "velo", decimals: 18, price: 0.02465572}, // Addr: 0xf486ad071f3bee968384d2e39e2d8af0fcf6fd46, Notional: 122.61638878240959 + {chain: 4, addr: "000000000000000000000000f585b5b4f22816baf7629aea55b701662630397b", symbol: "VOW", coinGeckoId: "vow", decimals: 18, price: 0.087943}, // Addr: 0xf585b5b4f22816baf7629aea55b701662630397b, Notional: 4.79676966511484 + {chain: 4, addr: "000000000000000000000000f64ed9ad397a1ae657f31131d4b189220a7f1cc7", symbol: "DFIAT", coinGeckoId: "defiato", decimals: 18, price: 0.00113772}, // Addr: 0xf64ed9ad397a1ae657f31131d4b189220a7f1cc7, Notional: 0.521815278 + {chain: 4, addr: "000000000000000000000000f7844cb890f4c339c497aeab599abdc3c874b67a", symbol: "NFTART", coinGeckoId: "nft-art-finance", decimals: 9, price: 1.1931e-11}, // Addr: 0xf7844cb890f4c339c497aeab599abdc3c874b67a, Notional: 7.62456938085e-12 + {chain: 4, addr: "000000000000000000000000f7de7e8a6bd59ed41a4b5fe50278b3b7f31384df", symbol: "RDNT", coinGeckoId: "radiant-capital", decimals: 18, price: 0.057654}, // Addr: 0xf7de7e8a6bd59ed41a4b5fe50278b3b7f31384df, Notional: 6.21874745170326 + {chain: 4, addr: "000000000000000000000000f915fdda4c882731c0456a4214548cd13a822886", symbol: "UNV", coinGeckoId: "unvest", decimals: 18, price: 0.0034131}, // Addr: 0xf915fdda4c882731c0456a4214548cd13a822886, Notional: 39.8035722 + {chain: 4, addr: "000000000000000000000000f92d62ed69242d655e685c96b98f32f1409c3262", symbol: "A4M", coinGeckoId: "alienform", decimals: 9, price: 0.00002415}, // Addr: 0xf92d62ed69242d655e685c96b98f32f1409c3262, Notional: 0.9706173863750385 + {chain: 4, addr: "000000000000000000000000f952fc3ca7325cc27d15885d37117676d25bfda6", symbol: "EGG", coinGeckoId: "goose-finance", decimals: 18, price: 0.0118022}, // Addr: 0xf952fc3ca7325cc27d15885d37117676d25bfda6, Notional: 0.236044 + {chain: 4, addr: "000000000000000000000000fa40d8fc324bcdd6bbae0e086de886c571c225d4", symbol: "WZRD", coinGeckoId: "wizardia", decimals: 18, price: 0.00141731}, // Addr: 0xfa40d8fc324bcdd6bbae0e086de886c571c225d4, Notional: 4339.649985857165 + {chain: 4, addr: "000000000000000000000000fafd4cb703b25cb22f43d017e7e0d75febc26743", symbol: "WEYU", coinGeckoId: "weyu", decimals: 18, price: 0.0000502}, // Addr: 0xfafd4cb703b25cb22f43d017e7e0d75febc26743, Notional: 190736.8823073073 + {chain: 4, addr: "000000000000000000000000fb288d60d3b66f9c3e231a9a39ed3f158a4269aa", symbol: "PPAY", coinGeckoId: "plasma-finance", decimals: 18, price: 0.00010374}, // Addr: 0xfb288d60d3b66f9c3e231a9a39ed3f158a4269aa, Notional: 0.005347268989335001 + {chain: 4, addr: "000000000000000000000000fb5b838b6cfeedc2873ab27866079ac55363d37e", symbol: "FLOKI", coinGeckoId: "floki", decimals: 9, price: 0.00017721}, // Addr: 0xfb5b838b6cfeedc2873ab27866079ac55363d37e, Notional: 539.2445505825738 + {chain: 4, addr: "000000000000000000000000fb6115445bff7b52feb98650c87f44907e58f802", symbol: "AAVE", coinGeckoId: "aave", decimals: 18, price: 309.59}, // Addr: 0xfb6115445bff7b52feb98650c87f44907e58f802, Notional: 202.32412365199997 + {chain: 4, addr: "000000000000000000000000fb9c339b4bace4fe63ccc1dd9a3c3c531441d5fe", symbol: "SHILL", coinGeckoId: "shill-token", decimals: 18, price: 0.00083352}, // Addr: 0xfb9c339b4bace4fe63ccc1dd9a3c3c531441d5fe, Notional: 4.855803862208218 + {chain: 4, addr: "000000000000000000000000fbc4f3f645c4003a2e4f4e9b51077d2daa9a9341", symbol: "ZEDXION", coinGeckoId: "zedxion", decimals: 18, price: 0.387989}, // Addr: 0xfbc4f3f645c4003a2e4f4e9b51077d2daa9a9341, Notional: 112404.67108565627 + {chain: 4, addr: "000000000000000000000000fce146bf3146100cfe5db4129cf6c82b0ef4ad8c", symbol: "renBTC", coinGeckoId: "renbtc", decimals: 8, price: 33929}, // Addr: 0xfce146bf3146100cfe5db4129cf6c82b0ef4ad8c, Notional: 27.51947261 + {chain: 4, addr: "000000000000000000000000fd7b3a77848f1c2d67e05e54d78d174a0c850335", symbol: "ONT", coinGeckoId: "binance-peg-ontology", decimals: 18, price: 0.229375}, // Addr: 0xfd7b3a77848f1c2d67e05e54d78d174a0c850335, Notional: 0.0229375 + {chain: 4, addr: "000000000000000000000000fdfd27ae39cebefdbaac8615f18aa68ddd0f15f5", symbol: "GHD", coinGeckoId: "giftedhands", decimals: 18, price: 4.48473e-7}, // Addr: 0xfdfd27ae39cebefdbaac8615f18aa68ddd0f15f5, Notional: 0.000044398827 + {chain: 4, addr: "000000000000000000000000fe19f0b51438fd612f6fd59c1dbb3ea319f433ba", symbol: "MIM", coinGeckoId: "magic-internet-money", decimals: 18, price: 0.994109}, // Addr: 0xfe19f0b51438fd612f6fd59c1dbb3ea319f433ba, Notional: 999.5312105706889 + {chain: 4, addr: "000000000000000000000000fe56d5892bdffc7bf58f2e84be1b2c32d21c308b", symbol: "KNC", coinGeckoId: "kyber-network-crystal", decimals: 18, price: 0.524853}, // Addr: 0xfe56d5892bdffc7bf58f2e84be1b2c32d21c308b, Notional: 2.1312467540223303 + {chain: 4, addr: "000000000000000000000000ffba7529ac181c2ee1844548e6d7061c9a597df4", symbol: "CAPS", coinGeckoId: "coin-capsule", decimals: 18, price: 0.00491619}, // Addr: 0xffba7529ac181c2ee1844548e6d7061c9a597df4, Notional: 0.07374285 + {chain: 5, addr: "000000000000000000000000011734f6ed20e8d011d85cf7894814b897420acf", symbol: "ACRE", coinGeckoId: "arable-protocol", decimals: 18, price: 0.00003292}, // Addr: 0x011734f6ed20e8d011d85cf7894814b897420acf, Notional: 0.0011480572316508 + {chain: 5, addr: "0000000000000000000000000308a3a9c433256ad7ef24dbef9c49c8cb01300a", symbol: "GPO", coinGeckoId: "goldpesa-option", decimals: 18, price: 0.827797}, // Addr: 0x0308a3a9c433256ad7ef24dbef9c49c8cb01300a, Notional: 19.867128 + {chain: 5, addr: "000000000000000000000000039d2e8f097331278bd6c1415d839310e0d5ece4", symbol: "LINDA", coinGeckoId: "linda-2", decimals: 18, price: 0.00000637}, // Addr: 0x039d2e8f097331278bd6c1415d839310e0d5ece4, Notional: 7.225275355221105 + {chain: 5, addr: "00000000000000000000000003b54a6e9a984069379fae1a4fc4dbae93b3bccd", symbol: "wstETH", coinGeckoId: "wrapped-steth", decimals: 18, price: 3961.06}, // Addr: 0x03b54a6e9a984069379fae1a4fc4dbae93b3bccd, Notional: 36.975623666800004 + {chain: 5, addr: "00000000000000000000000004429fbb948bbd09327763214b45e505a5293346", symbol: "ABR", coinGeckoId: "allbridge", decimals: 18, price: 0.096751}, // Addr: 0x04429fbb948bbd09327763214b45e505a5293346, Notional: 35.362101262019415 + {chain: 5, addr: "00000000000000000000000008e175a1eac9744a0f1ccaeb8f669af6a2bda3ce", symbol: "E8", coinGeckoId: "energy8", decimals: 9, price: 1.159e-8}, // Addr: 0x08e175a1eac9744a0f1ccaeb8f669af6a2bda3ce, Notional: 148.2030368895404 + {chain: 5, addr: "0000000000000000000000000b3f868e0be5597d5db7feb59e1cadbb0fdda50a", symbol: "SUSHI", coinGeckoId: "sushi", decimals: 18, price: 1.36}, // Addr: 0x0b3f868e0be5597d5db7feb59e1cadbb0fdda50a, Notional: 511.3480795592 + {chain: 5, addr: "0000000000000000000000000d500b1d8e8ef31e21c99d1db9a6444d3adf1270", symbol: "WPOL", coinGeckoId: "wmatic", decimals: 18, price: 0.450504}, // Addr: 0x0d500b1d8e8ef31e21c99d1db9a6444d3adf1270, Notional: 350149.986047658 + {chain: 5, addr: "0000000000000000000000000d6ae2a429df13e44a07cd2969e085e4833f64a0", symbol: "PBR", coinGeckoId: "polkabridge", decimals: 18, price: 0.03113037}, // Addr: 0x0d6ae2a429df13e44a07cd2969e085e4833f64a0, Notional: 326.95557605058985 + {chain: 5, addr: "0000000000000000000000000df0f72ee0e5c9b7ca761ecec42754992b2da5bf", symbol: "ATA", coinGeckoId: "automata", decimals: 18, price: 0.176101}, // Addr: 0x0df0f72ee0e5c9b7ca761ecec42754992b2da5bf, Notional: 8726.129347658985 + {chain: 5, addr: "000000000000000000000000111111517e4929d3dcbdfa7cce55d30d4b6bc4d6", symbol: "ICHI", coinGeckoId: "ichi-farm", decimals: 18, price: 0.673047}, // Addr: 0x111111517e4929d3dcbdfa7cce55d30d4b6bc4d6, Notional: 0.01667972670327 + {chain: 5, addr: "0000000000000000000000001379e8886a944d2d9d440b3d88df536aea08d9f3", symbol: "MYST", coinGeckoId: "mysterium", decimals: 18, price: 0.220917}, // Addr: 0x1379e8886a944d2d9d440b3d88df536aea08d9f3, Notional: 0.35743994599266005 + {chain: 5, addr: "00000000000000000000000018e73a5333984549484348a94f4d219f4fab7b81", symbol: "DUCKIES", coinGeckoId: "duckies", decimals: 8, price: 0.0039499}, // Addr: 0x18e73a5333984549484348a94f4d219f4fab7b81, Notional: 0.039499 + {chain: 5, addr: "00000000000000000000000018ec0a6e18e5bc3784fdd3a3634b31245ab704f6", symbol: "EURe", coinGeckoId: "monerium-eur-money", decimals: 18, price: 1.018}, // Addr: 0x18ec0a6e18e5bc3784fdd3a3634b31245ab704f6, Notional: 0.3054 + {chain: 5, addr: "0000000000000000000000001a13f4ca1d028320a707d99520abfefca3998b7f", symbol: "amUSDC", coinGeckoId: "aave-polygon-usdc", decimals: 6, price: 0.999204}, // Addr: 0x1a13f4ca1d028320a707d99520abfefca3998b7f, Notional: 19.560665306592 + {chain: 5, addr: "0000000000000000000000001b815d120b3ef02039ee11dc2d33de7aa4a8c603", symbol: "WOO", coinGeckoId: "woo-network", decimals: 18, price: 0.207659}, // Addr: 0x1b815d120b3ef02039ee11dc2d33de7aa4a8c603, Notional: 14.399075060000001 + {chain: 5, addr: "0000000000000000000000001bfd67037b42cf73acf2047067bd4f2c47d9bfd6", symbol: "WBTC", coinGeckoId: "wrapped-bitcoin", decimals: 8, price: 93245}, // Addr: 0x1bfd67037b42cf73acf2047067bd4f2c47d9bfd6, Notional: 34829.6258196 + {chain: 5, addr: "0000000000000000000000001d734a02ef1e1f5886e66b0673b71af5b53ffa94", symbol: "SD", coinGeckoId: "stader", decimals: 18, price: 1.38}, // Addr: 0x1d734a02ef1e1f5886e66b0673b71af5b53ffa94, Notional: 209.5415324622 + {chain: 5, addr: "000000000000000000000000200c234721b5e549c3693ccc93cf191f90dc2af9", symbol: "METAL", coinGeckoId: "drunk-robots", decimals: 18, price: 0.0122432}, // Addr: 0x200c234721b5e549c3693ccc93cf191f90dc2af9, Notional: 1.4190978040041597 + {chain: 5, addr: "000000000000000000000000229b1b6c23ff8953d663c4cbb519717e323a0a84", symbol: "BLOK", coinGeckoId: "bloktopia", decimals: 18, price: 0.00067727}, // Addr: 0x229b1b6c23ff8953d663c4cbb519717e323a0a84, Notional: 0.0534053356655456 + {chain: 5, addr: "00000000000000000000000022e3f02f86bc8ea0d73718a2ae8851854e62adc5", symbol: "FLAME", coinGeckoId: "firestarter", decimals: 18, price: 0.0251002}, // Addr: 0x22e3f02f86bc8ea0d73718a2ae8851854e62adc5, Notional: 3661.980730339697 + {chain: 5, addr: "000000000000000000000000236aa50979d5f3de3bd1eeb40e81137f22ab794b", symbol: "tBTC", coinGeckoId: "tbtc", decimals: 18, price: 93127}, // Addr: 0x236aa50979d5f3de3bd1eeb40e81137f22ab794b, Notional: 0.02514429 + {chain: 5, addr: "00000000000000000000000023d29d30e35c5e8d321e1dc9a8a61bfd846d4c5c", symbol: "HEX", coinGeckoId: "hex", decimals: 8, price: 0.00316472}, // Addr: 0x23d29d30e35c5e8d321e1dc9a8a61bfd846d4c5c, Notional: 1.9566305490202434 + {chain: 5, addr: "00000000000000000000000023e8b6a3f6891254988b84da3738d2bfe5e703b9", symbol: "WELT", coinGeckoId: "fabwelt", decimals: 18, price: 0.00286349}, // Addr: 0x23e8b6a3f6891254988b84da3738d2bfe5e703b9, Notional: 1.4031101 + {chain: 5, addr: "00000000000000000000000024834bbec7e39ef42f4a75eaf8e5b6486d3f0e57", symbol: "LUNA", coinGeckoId: "wrapped-terra", decimals: 18, price: 0.00004537}, // Addr: 0x24834bbec7e39ef42f4a75eaf8e5b6486d3f0e57, Notional: 15.990308475666076 + {chain: 5, addr: "00000000000000000000000025788a1a171ec66da6502f9975a15b609ff54cf6", symbol: "POOL", coinGeckoId: "pooltogether", decimals: 18, price: 0.961451}, // Addr: 0x25788a1a171ec66da6502f9975a15b609ff54cf6, Notional: 16.344666999999998 + {chain: 5, addr: "0000000000000000000000002598c30330d5771ae9f983979209486ae26de875", symbol: "AI", coinGeckoId: "any-inu", decimals: 18, price: 0.00000937}, // Addr: 0x2598c30330d5771ae9f983979209486ae26de875, Notional: 9.37 + {chain: 5, addr: "0000000000000000000000002791bca1f2de4661ed88a30c99a7a9449aa84174", symbol: "USDC", coinGeckoId: "usd-coin", decimals: 6, price: 0.999339}, // Addr: 0x2791bca1f2de4661ed88a30c99a7a9449aa84174, Notional: 3708143.747442428 + {chain: 5, addr: "0000000000000000000000002ab0e9e4ee70fff1fb9d67031e44f6410170d00e", symbol: "mXEN", coinGeckoId: "xen-crypto-matic", decimals: 18, price: 1.83776e-10}, // Addr: 0x2ab0e9e4ee70fff1fb9d67031e44f6410170d00e, Notional: 19.065818010009302 + {chain: 5, addr: "0000000000000000000000002ab4f9ac80f33071211729e45cfc346c1f8446d5", symbol: "CGG", coinGeckoId: "chain-guardians", decimals: 18, price: 0.00987065}, // Addr: 0x2ab4f9ac80f33071211729e45cfc346c1f8446d5, Notional: 0.00987065 + {chain: 5, addr: "0000000000000000000000002ad2934d5bfb7912304754479dd1f096d5c807da", symbol: "AGC", coinGeckoId: "argocoin", decimals: 18, price: 0.141377}, // Addr: 0x2ad2934d5bfb7912304754479dd1f096d5c807da, Notional: 14.1377 + {chain: 5, addr: "0000000000000000000000002c89bbc92bd86f8075d1decc58c7f4e0107f286b", symbol: "AVAX", coinGeckoId: "wrapped-avax", decimals: 18, price: 35.57}, // Addr: 0x2c89bbc92bd86f8075d1decc58c7f4e0107f286b, Notional: 3653.277891677 + {chain: 5, addr: "0000000000000000000000002d66953fc2eb650f0fd992dbe1e71d743a4e9fee", symbol: "NOTES", coinGeckoId: "backstage-pass-notes", decimals: 9, price: 0.00421375}, // Addr: 0x2d66953fc2eb650f0fd992dbe1e71d743a4e9fee, Notional: 0.42137499999999994 + {chain: 5, addr: "0000000000000000000000002e1ad108ff1d8c782fcbbb89aad783ac49586756", symbol: "TUSD", coinGeckoId: "true-usd", decimals: 18, price: 0.996888}, // Addr: 0x2e1ad108ff1d8c782fcbbb89aad783ac49586756, Notional: 4.7206587398575195 {chain: 5, addr: "0000000000000000000000002f25d402829ca4085b8ea4d3bc68bf203f5a9fab", symbol: "Eagon", coinGeckoId: "eagonswap-token", decimals: 18, price: 0.00007782}, // Addr: 0x2f25d402829ca4085b8ea4d3bc68bf203f5a9fab, Notional: 0.2225516283530874 - {chain: 5, addr: "0000000000000000000000002f6f07cdcf3588944bf4c42ac74ff24bf56e7590", symbol: "STG", coinGeckoId: "stargate-finance", decimals: 18, price: 0.382194}, // Addr: 0x2f6f07cdcf3588944bf4c42ac74ff24bf56e7590, Notional: 86.68102317249095 - {chain: 5, addr: "00000000000000000000000030ea765d4dda26e0f89e1b23a7c7b2526b7d29ec", symbol: "POLYPAD", coinGeckoId: "polypad", decimals: 18, price: 0.00073073}, // Addr: 0x30ea765d4dda26e0f89e1b23a7c7b2526b7d29ec, Notional: 114.6933548008227 - {chain: 5, addr: "000000000000000000000000323665443cef804a3b5206103304bd4872ea4253", symbol: "USDV", coinGeckoId: "verified-usd-foundation-usdv", decimals: 6, price: 0.999897}, // Addr: 0x323665443cef804a3b5206103304bd4872ea4253, Notional: 3.002299731273 - {chain: 5, addr: "00000000000000000000000034c1b299a74588d6abdc1b85a53345a48428a521", symbol: "EZ", coinGeckoId: "easyfi", decimals: 18, price: 0.01002764}, // Addr: 0x34c1b299a74588d6abdc1b85a53345a48428a521, Notional: 0.04011056 - {chain: 5, addr: "0000000000000000000000003a9a81d576d83ff21f26f325066054540720fc34", symbol: "DATA", coinGeckoId: "streamr", decimals: 18, price: 0.04723956}, // Addr: 0x3a9a81d576d83ff21f26f325066054540720fc34, Notional: 0.37791648 - {chain: 5, addr: "0000000000000000000000003c499c542cef5e3811e1192ce70d8cc03d5c3359", symbol: "USDC", coinGeckoId: "usd-coin", decimals: 6, price: 1}, // Addr: 0x3c499c542cef5e3811e1192ce70d8cc03d5c3359, Notional: 78038.508963 - {chain: 5, addr: "0000000000000000000000003c69d114664d48357d820dbdd121a8071eac99bf", symbol: "GALAXIS", coinGeckoId: "galaxis-token", decimals: 18, price: 0.00112234}, // Addr: 0x3c69d114664d48357d820dbdd121a8071eac99bf, Notional: 168.53299237670345 - {chain: 5, addr: "000000000000000000000000411bc96881a62572ff33c9d8ce60df99e3d96cd8", symbol: "MRST", coinGeckoId: "the-mars", decimals: 18, price: 0.00105999}, // Addr: 0x411bc96881a62572ff33c9d8ce60df99e3d96cd8, Notional: 0.17383836 - {chain: 5, addr: "00000000000000000000000042d61d766b85431666b39b89c43011f24451bff6", symbol: "PSP", coinGeckoId: "paraswap", decimals: 18, price: 0.02058788}, // Addr: 0x42d61d766b85431666b39b89c43011f24451bff6, Notional: 0.04117576 - {chain: 5, addr: "000000000000000000000000430ef9263e76dae63c84292c3409d61c598e9682", symbol: "PYR", coinGeckoId: "vulcan-forged", decimals: 18, price: 3.87}, // Addr: 0x430ef9263e76dae63c84292c3409d61c598e9682, Notional: 42.457770000000004 - {chain: 5, addr: "000000000000000000000000431d5dff03120afa4bdf332c61a6e1766ef37bdb", symbol: "JPYC", coinGeckoId: "jpy-coin", decimals: 18, price: 0.00623013}, // Addr: 0x431d5dff03120afa4bdf332c61a6e1766ef37bdb, Notional: 0.6853143 - {chain: 5, addr: "000000000000000000000000444444444444c1a66f394025ac839a535246fcc8", symbol: "GENI", coinGeckoId: "genius", decimals: 9, price: 8.20707e-7}, // Addr: 0x444444444444c1a66f394025ac839a535246fcc8, Notional: 1.968185377490018 - {chain: 5, addr: "00000000000000000000000045c32fa6df82ead1e2ef74d17b76547eddfaff89", symbol: "FRAX", coinGeckoId: "frax", decimals: 18, price: 0.996303}, // Addr: 0x45c32fa6df82ead1e2ef74d17b76547eddfaff89, Notional: 9.97110246535326 - {chain: 5, addr: "00000000000000000000000046d502fac9aea7c5bc7b13c8ec9d02378c33d36f", symbol: "WSPP", coinGeckoId: "wolfsafepoorpeople-polygon", decimals: 18, price: 1.32e-8}, // Addr: 0x46d502fac9aea7c5bc7b13c8ec9d02378c33d36f, Notional: 0.396 - {chain: 5, addr: "00000000000000000000000049a0400587a7f65072c87c4910449fdcc5c47242", symbol: "MIM", coinGeckoId: "magic-internet-money", decimals: 18, price: 0.99491}, // Addr: 0x49a0400587a7f65072c87c4910449fdcc5c47242, Notional: 51.247714609 - {chain: 5, addr: "0000000000000000000000004a81f8796e0c6ad4877a51c86693b0de8093f2ef", symbol: "ICE", coinGeckoId: "iron-finance", decimals: 18, price: 0.00000418}, // Addr: 0x4a81f8796e0c6ad4877a51c86693b0de8093f2ef, Notional: 0.5498162999999999 - {chain: 5, addr: "0000000000000000000000004c9f66b2806538cf00ef596e09fb05bcb0d17dc8", symbol: "MNTO", coinGeckoId: "minato", decimals: 18, price: 1.21}, // Addr: 0x4c9f66b2806538cf00ef596e09fb05bcb0d17dc8, Notional: 2.42 - {chain: 5, addr: "0000000000000000000000004e1581f01046efdd7a1a2cdb0f82cdd7f71f2e59", symbol: "ICE", coinGeckoId: "ice-token", decimals: 18, price: 0.485954}, // Addr: 0x4e1581f01046efdd7a1a2cdb0f82cdd7f71f2e59, Notional: 50.31903802272354 - {chain: 5, addr: "0000000000000000000000004e78011ce80ee02d2c3e649fb657e45898257815", symbol: "KLIMA", coinGeckoId: "klima-dao", decimals: 9, price: 1.13}, // Addr: 0x4e78011ce80ee02d2c3e649fb657e45898257815, Notional: 0.7639403645999999 - {chain: 5, addr: "0000000000000000000000004fb71290ac171e1d144f7221d882becac7196eb5", symbol: "TRYB", coinGeckoId: "bilira", decimals: 6, price: 0.02884969}, // Addr: 0x4fb71290ac171e1d144f7221d882becac7196eb5, Notional: 9.05797000024722 - {chain: 5, addr: "00000000000000000000000050b728d8d964fd00c2d0aad81718b71311fef68a", symbol: "SNX", coinGeckoId: "havven", decimals: 18, price: 2.45}, // Addr: 0x50b728d8d964fd00c2d0aad81718b71311fef68a, Notional: 4.400947936 - {chain: 5, addr: "00000000000000000000000052ede6bba83b7b4ba1d738df0df713d6a2036b71", symbol: "0xMR", coinGeckoId: "0xmonero", decimals: 18, price: 0.02902815}, // Addr: 0x52ede6bba83b7b4ba1d738df0df713d6a2036b71, Notional: 1.033787943272079 - {chain: 5, addr: "00000000000000000000000053e0bca35ec356bd5dddfebbd1fc0fd03fabad39", symbol: "LINK", coinGeckoId: "chainlink", decimals: 18, price: 19.89}, // Addr: 0x53e0bca35ec356bd5dddfebbd1fc0fd03fabad39, Notional: 1229.4523094841002 - {chain: 5, addr: "000000000000000000000000554cd6bdd03214b10aafa3e0d4d42de0c5d2937b", symbol: "IDRT", coinGeckoId: "rupiah-token", decimals: 6, price: 0.00006287}, // Addr: 0x554cd6bdd03214b10aafa3e0d4d42de0c5d2937b, Notional: 3.40399636833143 - {chain: 5, addr: "000000000000000000000000590eb2920486486c2d9bb3eb651f73b81df87bcf", symbol: "BOBC", coinGeckoId: "bobcoin", decimals: 18, price: 0.186345}, // Addr: 0x590eb2920486486c2d9bb3eb651f73b81df87bcf, Notional: 0.186345 - {chain: 5, addr: "000000000000000000000000596ebe76e2db4470966ea395b0d063ac6197a8c5", symbol: "JRT", coinGeckoId: "jarvis-reward-token", decimals: 18, price: 0.00451893}, // Addr: 0x596ebe76e2db4470966ea395b0d063ac6197a8c5, Notional: 451.89751893 - {chain: 5, addr: "0000000000000000000000005d47baba0d66083c52009271faf3f50dcc01023c", symbol: "BANANA", coinGeckoId: "apeswap-finance", decimals: 18, price: 0.00058152}, // Addr: 0x5d47baba0d66083c52009271faf3f50dcc01023c, Notional: 4.13510498112 - {chain: 5, addr: "00000000000000000000000061299774020da444af134c82fa83e3810b309991", symbol: "RNDR", coinGeckoId: "render-token", decimals: 18, price: 8.23}, // Addr: 0x61299774020da444af134c82fa83e3810b309991, Notional: 253.1039049393 - {chain: 5, addr: "000000000000000000000000613a489785c95afeb3b404cc41565ccff107b6e0", symbol: "RADIO", coinGeckoId: "radioshack", decimals: 18, price: 0.000064}, // Addr: 0x613a489785c95afeb3b404cc41565ccff107b6e0, Notional: 0.00250359680768 - {chain: 5, addr: "00000000000000000000000065a05db8322701724c197af82c9cae41195b0aa8", symbol: "FOX", coinGeckoId: "shapeshift-fox-token", decimals: 18, price: 0.05751}, // Addr: 0x65a05db8322701724c197af82c9cae41195b0aa8, Notional: 0.028755 - {chain: 5, addr: "000000000000000000000000692597b009d13c4049a947cab2239b7d6517875f", symbol: "UST", coinGeckoId: "wrapped-ust", decimals: 18, price: 0.02485643}, // Addr: 0x692597b009d13c4049a947cab2239b7d6517875f, Notional: 395.86339186274114 - {chain: 5, addr: "0000000000000000000000006a3e7c3c6ef65ee26975b12293ca1aad7e1daed2", symbol: "ALPHA", coinGeckoId: "aavegotchi-alpha", decimals: 18, price: 0.00048106}, // Addr: 0x6a3e7c3c6ef65ee26975b12293ca1aad7e1daed2, Notional: 0.0002020452 - {chain: 5, addr: "0000000000000000000000006ae7dfc73e0dde2aa99ac063dcf7e8a63265108c", symbol: "JPYC", coinGeckoId: "jpyc", decimals: 18, price: 0.00758084}, // Addr: 0x6ae7dfc73e0dde2aa99ac063dcf7e8a63265108c, Notional: 6.064672 - {chain: 5, addr: "0000000000000000000000006ccf12b480a99c54b23647c995f4525d544a7e72", symbol: "START", coinGeckoId: "bscstarter", decimals: 18, price: 0.056166}, // Addr: 0x6ccf12b480a99c54b23647c995f4525d544a7e72, Notional: 155.10317750758315 - {chain: 5, addr: "000000000000000000000000709a4b6217584188ddb93c82f5d716d969acce1c", symbol: "HANU", coinGeckoId: "hanu-yokia", decimals: 12, price: 2.78793e-7}, // Addr: 0x709a4b6217584188ddb93c82f5d716d969acce1c, Notional: 1.0540432742781773 - {chain: 5, addr: "00000000000000000000000070c006878a5a50ed185ac4c87d837633923de296", symbol: "REVV", coinGeckoId: "revv", decimals: 18, price: 0.00425741}, // Addr: 0x70c006878a5a50ed185ac4c87d837633923de296, Notional: 3.79510864842541 - {chain: 5, addr: "000000000000000000000000714db550b574b3e927af3d93e26127d15721d4c2", symbol: "GMT", coinGeckoId: "stepn", decimals: 8, price: 0.207966}, // Addr: 0x714db550b574b3e927af3d93e26127d15721d4c2, Notional: 8.214657 - {chain: 5, addr: "000000000000000000000000723b17718289a91af252d616de2c77944962d122", symbol: "GAIA", coinGeckoId: "gaia-everworld", decimals: 18, price: 0.00200102}, // Addr: 0x723b17718289a91af252d616de2c77944962d122, Notional: 0.0193669790045088 - {chain: 5, addr: "000000000000000000000000750e4c4984a9e0f12978ea6742bc1c5d248f40ed", symbol: "axlUSDC", coinGeckoId: "axlusdc", decimals: 6, price: 0.99899}, // Addr: 0x750e4c4984a9e0f12978ea6742bc1c5d248f40ed, Notional: 81.49582699679 - {chain: 5, addr: "0000000000000000000000007844f79fc841e4f92d974c417031c76f8578c2d5", symbol: "OPN", coinGeckoId: "open-ticketing-ecosystem", decimals: 18, price: 0.0014495}, // Addr: 0x7844f79fc841e4f92d974c417031c76f8578c2d5, Notional: 1.6408340000000001 - {chain: 5, addr: "00000000000000000000000078a0a62fba6fb21a83fe8a3433d44c73a4017a6f", symbol: "OX", coinGeckoId: "open-exchange-token", decimals: 18, price: 0.00431491}, // Addr: 0x78a0a62fba6fb21a83fe8a3433d44c73a4017a6f, Notional: 0.2944476583058462 - {chain: 5, addr: "0000000000000000000000007bebd226154e865954a87650faefa8f485d36081", symbol: "ZIG", coinGeckoId: "zignaly", decimals: 18, price: 0.14653}, // Addr: 0x7bebd226154e865954a87650faefa8f485d36081, Notional: 1.9787879832245998 - {chain: 5, addr: "0000000000000000000000007ceb23fd6bc0add59e62ac25578270cff1b9f619", symbol: "WETH", coinGeckoId: "weth", decimals: 18, price: 3594.89}, // Addr: 0x7ceb23fd6bc0add59e62ac25578270cff1b9f619, Notional: 209576.8273523899 - {chain: 5, addr: "0000000000000000000000007e4c577ca35913af564ee2a24d882a4946ec492b", symbol: "MOONED", coinGeckoId: "moonedge", decimals: 18, price: 0.0042198}, // Addr: 0x7e4c577ca35913af564ee2a24d882a4946ec492b, Notional: 0.053549265502434 - {chain: 5, addr: "00000000000000000000000081382e9693de2afc33f69b70a6c12ca9b3a73f47", symbol: "DOSE", coinGeckoId: "dose-token", decimals: 18, price: 0.00024306}, // Addr: 0x81382e9693de2afc33f69b70a6c12ca9b3a73f47, Notional: 0.0218754 - {chain: 5, addr: "000000000000000000000000831753dd7087cac61ab5644b308642cc1c33dc13", symbol: "QUICK", coinGeckoId: "quick", decimals: 18, price: 51.96}, // Addr: 0x831753dd7087cac61ab5644b308642cc1c33dc13, Notional: 8.101520583600001 - {chain: 5, addr: "0000000000000000000000008765f05adce126d70bcdf1b0a48db573316662eb", symbol: "PLA", coinGeckoId: "playdapp", decimals: 18, price: 0.052764}, // Addr: 0x8765f05adce126d70bcdf1b0a48db573316662eb, Notional: 82.04802 - {chain: 5, addr: "00000000000000000000000088c949b4eb85a90071f2c0bef861bddee1a7479d", symbol: "mSHEESHA", coinGeckoId: "sheesha-finance-polygon", decimals: 18, price: 0.00017621}, // Addr: 0x88c949b4eb85a90071f2c0bef861bddee1a7479d, Notional: 0.008810499999999999 - {chain: 5, addr: "0000000000000000000000008d1566569d5b695d44a9a234540f68d393cdc40d", symbol: "GAME", coinGeckoId: "gamecredits", decimals: 18, price: 0.00075972}, // Addr: 0x8d1566569d5b695d44a9a234540f68d393cdc40d, Notional: 0.00607776 - {chain: 5, addr: "0000000000000000000000008eef5a82e6aa222a60f009ac18c24ee12dbf4b41", symbol: "TXL", coinGeckoId: "autobahn-network", decimals: 18, price: 0.00243036}, // Addr: 0x8eef5a82e6aa222a60f009ac18c24ee12dbf4b41, Notional: 0.0000243036 - {chain: 5, addr: "0000000000000000000000008f36cc333f55b09bb71091409a3d7ade399e3b1c", symbol: "CHER", coinGeckoId: "cherry-network", decimals: 18, price: 0.00120436}, // Addr: 0x8f36cc333f55b09bb71091409a3d7ade399e3b1c, Notional: 0.0120436 - {chain: 5, addr: "0000000000000000000000008f3cf7ad23cd3cadbd9735aff958023239c6a063", symbol: "DAI", coinGeckoId: "dai", decimals: 18, price: 1}, // Addr: 0x8f3cf7ad23cd3cadbd9735aff958023239c6a063, Notional: 2480.07724967 - {chain: 5, addr: "0000000000000000000000009085b4d52c3e0b8b6f9af6213e85a433c7d76f19", symbol: "OWL", coinGeckoId: "owldao", decimals: 18, price: 0.00487263}, // Addr: 0x9085b4d52c3e0b8b6f9af6213e85a433c7d76f19, Notional: 1.0507344865358628 - {chain: 5, addr: "00000000000000000000000091c5a5488c0decde1eacd8a4f10e0942fb925067", symbol: "AUDT", coinGeckoId: "auditchain", decimals: 18, price: 0.03348153}, // Addr: 0x91c5a5488c0decde1eacd8a4f10e0942fb925067, Notional: 334.81530000000004 + {chain: 5, addr: "0000000000000000000000002f6f07cdcf3588944bf4c42ac74ff24bf56e7590", symbol: "STG", coinGeckoId: "stargate-finance", decimals: 18, price: 0.36685}, // Addr: 0x2f6f07cdcf3588944bf4c42ac74ff24bf56e7590, Notional: 83.201027098354 + {chain: 5, addr: "00000000000000000000000030ea765d4dda26e0f89e1b23a7c7b2526b7d29ec", symbol: "POLYPAD", coinGeckoId: "polypad", decimals: 18, price: 0.00068785}, // Addr: 0x30ea765d4dda26e0f89e1b23a7c7b2526b7d29ec, Notional: 107.96302888857157 + {chain: 5, addr: "000000000000000000000000323665443cef804a3b5206103304bd4872ea4253", symbol: "USDV", coinGeckoId: "verified-usd-foundation-usdv", decimals: 6, price: 0.994502}, // Addr: 0x323665443cef804a3b5206103304bd4872ea4253, Notional: 2.986100655718 + {chain: 5, addr: "00000000000000000000000034c1b299a74588d6abdc1b85a53345a48428a521", symbol: "EZ", coinGeckoId: "easyfi", decimals: 18, price: 0.01091411}, // Addr: 0x34c1b299a74588d6abdc1b85a53345a48428a521, Notional: 0.04365644 + {chain: 5, addr: "0000000000000000000000003a9a81d576d83ff21f26f325066054540720fc34", symbol: "DATA", coinGeckoId: "streamr", decimals: 18, price: 0.04873106}, // Addr: 0x3a9a81d576d83ff21f26f325066054540720fc34, Notional: 0.38984848 + {chain: 5, addr: "0000000000000000000000003c499c542cef5e3811e1192ce70d8cc03d5c3359", symbol: "USDC", coinGeckoId: "usd-coin", decimals: 6, price: 0.999339}, // Addr: 0x3c499c542cef5e3811e1192ce70d8cc03d5c3359, Notional: 78215.20297036802 + {chain: 5, addr: "0000000000000000000000003c69d114664d48357d820dbdd121a8071eac99bf", symbol: "GALAXIS", coinGeckoId: "galaxis-token", decimals: 18, price: 0.00094369}, // Addr: 0x3c69d114664d48357d820dbdd121a8071eac99bf, Notional: 141.70652349196433 + {chain: 5, addr: "000000000000000000000000411bc96881a62572ff33c9d8ce60df99e3d96cd8", symbol: "MRST", coinGeckoId: "the-mars", decimals: 18, price: 0.00109884}, // Addr: 0x411bc96881a62572ff33c9d8ce60df99e3d96cd8, Notional: 0.18020976 + {chain: 5, addr: "00000000000000000000000042d61d766b85431666b39b89c43011f24451bff6", symbol: "PSP", coinGeckoId: "paraswap", decimals: 18, price: 0.02347798}, // Addr: 0x42d61d766b85431666b39b89c43011f24451bff6, Notional: 0.04695596 + {chain: 5, addr: "000000000000000000000000430ef9263e76dae63c84292c3409d61c598e9682", symbol: "PYR", coinGeckoId: "vulcan-forged", decimals: 18, price: 3.04}, // Addr: 0x430ef9263e76dae63c84292c3409d61c598e9682, Notional: 33.35184 + {chain: 5, addr: "000000000000000000000000431d5dff03120afa4bdf332c61a6e1766ef37bdb", symbol: "JPYC", coinGeckoId: "jpy-coin", decimals: 18, price: 0.0062165}, // Addr: 0x431d5dff03120afa4bdf332c61a6e1766ef37bdb, Notional: 0.683815 + {chain: 5, addr: "000000000000000000000000444444444444c1a66f394025ac839a535246fcc8", symbol: "GENI", coinGeckoId: "genius", decimals: 9, price: 5.7398e-7}, // Addr: 0x444444444444c1a66f394025ac839a535246fcc8, Notional: 1.3764949524881844 + {chain: 5, addr: "00000000000000000000000045c32fa6df82ead1e2ef74d17b76547eddfaff89", symbol: "FRAX", coinGeckoId: "frax", decimals: 18, price: 0.993202}, // Addr: 0x45c32fa6df82ead1e2ef74d17b76547eddfaff89, Notional: 9.94006733974884 + {chain: 5, addr: "00000000000000000000000046d502fac9aea7c5bc7b13c8ec9d02378c33d36f", symbol: "WSPP", coinGeckoId: "wolfsafepoorpeople-polygon", decimals: 18, price: 7.986e-9}, // Addr: 0x46d502fac9aea7c5bc7b13c8ec9d02378c33d36f, Notional: 0.23958 + {chain: 5, addr: "00000000000000000000000049a0400587a7f65072c87c4910449fdcc5c47242", symbol: "MIM", coinGeckoId: "magic-internet-money", decimals: 18, price: 0.994109}, // Addr: 0x49a0400587a7f65072c87c4910449fdcc5c47242, Notional: 51.206455179100004 + {chain: 5, addr: "0000000000000000000000004a81f8796e0c6ad4877a51c86693b0de8093f2ef", symbol: "ICE", coinGeckoId: "iron-finance", decimals: 18, price: 0.00000371}, // Addr: 0x4a81f8796e0c6ad4877a51c86693b0de8093f2ef, Notional: 0.48799485 + {chain: 5, addr: "0000000000000000000000004c9f66b2806538cf00ef596e09fb05bcb0d17dc8", symbol: "MNTO", coinGeckoId: "minato", decimals: 18, price: 0.799733}, // Addr: 0x4c9f66b2806538cf00ef596e09fb05bcb0d17dc8, Notional: 1.599466 + {chain: 5, addr: "0000000000000000000000004e1581f01046efdd7a1a2cdb0f82cdd7f71f2e59", symbol: "ICE", coinGeckoId: "ice-token", decimals: 18, price: 0.302589}, // Addr: 0x4e1581f01046efdd7a1a2cdb0f82cdd7f71f2e59, Notional: 31.33215776854989 + {chain: 5, addr: "0000000000000000000000004e78011ce80ee02d2c3e649fb657e45898257815", symbol: "KLIMA", coinGeckoId: "klima-dao", decimals: 9, price: 0.790339}, // Addr: 0x4e78011ce80ee02d2c3e649fb657e45898257815, Notional: 0.53431138390938 + {chain: 5, addr: "0000000000000000000000004fb71290ac171e1d144f7221d882becac7196eb5", symbol: "TRYB", coinGeckoId: "bilira", decimals: 6, price: 0.0279144}, // Addr: 0x4fb71290ac171e1d144f7221d882becac7196eb5, Notional: 8.7643159345872 + {chain: 5, addr: "00000000000000000000000050b728d8d964fd00c2d0aad81718b71311fef68a", symbol: "SNX", coinGeckoId: "havven", decimals: 18, price: 1.9}, // Addr: 0x50b728d8d964fd00c2d0aad81718b71311fef68a, Notional: 3.4129800319999997 + {chain: 5, addr: "00000000000000000000000052ede6bba83b7b4ba1d738df0df713d6a2036b71", symbol: "0xMR", coinGeckoId: "0xmonero", decimals: 18, price: 0.0195011}, // Addr: 0x52ede6bba83b7b4ba1d738df0df713d6a2036b71, Notional: 0.694498342489726 + {chain: 5, addr: "00000000000000000000000053e0bca35ec356bd5dddfebbd1fc0fd03fabad39", symbol: "LINK", coinGeckoId: "chainlink", decimals: 18, price: 19.87}, // Addr: 0x53e0bca35ec356bd5dddfebbd1fc0fd03fabad39, Notional: 1228.2160577903 + {chain: 5, addr: "000000000000000000000000554cd6bdd03214b10aafa3e0d4d42de0c5d2937b", symbol: "IDRT", coinGeckoId: "rupiah-token", decimals: 6, price: 0.00006121}, // Addr: 0x554cd6bdd03214b10aafa3e0d4d42de0c5d2937b, Notional: 3.3141183029356904 + {chain: 5, addr: "000000000000000000000000590eb2920486486c2d9bb3eb651f73b81df87bcf", symbol: "BOBC", coinGeckoId: "bobcoin", decimals: 18, price: 0.194728}, // Addr: 0x590eb2920486486c2d9bb3eb651f73b81df87bcf, Notional: 0.194728 + {chain: 5, addr: "000000000000000000000000596ebe76e2db4470966ea395b0d063ac6197a8c5", symbol: "JRT", coinGeckoId: "jarvis-reward-token", decimals: 18, price: 0.00427984}, // Addr: 0x596ebe76e2db4470966ea395b0d063ac6197a8c5, Notional: 427.98827984 + {chain: 5, addr: "0000000000000000000000005d47baba0d66083c52009271faf3f50dcc01023c", symbol: "BANANA", coinGeckoId: "apeswap-finance", decimals: 18, price: 0.00058826}, // Addr: 0x5d47baba0d66083c52009271faf3f50dcc01023c, Notional: 4.18303215056 + {chain: 5, addr: "0000000000000000000000005f0197ba06860dac7e31258bdf749f92b6a636d4", symbol: "1FLR", coinGeckoId: "flare-token", decimals: 18, price: 0.00003819}, // Addr: 0x5f0197ba06860dac7e31258bdf749f92b6a636d4, Notional: 1.9095 + {chain: 5, addr: "00000000000000000000000061299774020da444af134c82fa83e3810b309991", symbol: "RNDR", coinGeckoId: "render-token", decimals: 18, price: 6.79}, // Addr: 0x61299774020da444af134c82fa83e3810b309991, Notional: 208.8184100289 + {chain: 5, addr: "000000000000000000000000613a489785c95afeb3b404cc41565ccff107b6e0", symbol: "RADIO", coinGeckoId: "radioshack", decimals: 18, price: 0.0000557}, // Addr: 0x613a489785c95afeb3b404cc41565ccff107b6e0, Notional: 0.002178911596684 + {chain: 5, addr: "00000000000000000000000065a05db8322701724c197af82c9cae41195b0aa8", symbol: "FOX", coinGeckoId: "shapeshift-fox-token", decimals: 18, price: 0.055658}, // Addr: 0x65a05db8322701724c197af82c9cae41195b0aa8, Notional: 0.027829 + {chain: 5, addr: "000000000000000000000000692597b009d13c4049a947cab2239b7d6517875f", symbol: "UST", coinGeckoId: "wrapped-ust", decimals: 18, price: 0.01958015}, // Addr: 0x692597b009d13c4049a947cab2239b7d6517875f, Notional: 311.833380424351 + {chain: 5, addr: "0000000000000000000000006a3e7c3c6ef65ee26975b12293ca1aad7e1daed2", symbol: "ALPHA", coinGeckoId: "aavegotchi-alpha", decimals: 18, price: 0.00035775}, // Addr: 0x6a3e7c3c6ef65ee26975b12293ca1aad7e1daed2, Notional: 0.000150255 + {chain: 5, addr: "0000000000000000000000006ae7dfc73e0dde2aa99ac063dcf7e8a63265108c", symbol: "JPYC", coinGeckoId: "jpyc", decimals: 18, price: 0.00714334}, // Addr: 0x6ae7dfc73e0dde2aa99ac063dcf7e8a63265108c, Notional: 5.714672 + {chain: 5, addr: "0000000000000000000000006ccf12b480a99c54b23647c995f4525d544a7e72", symbol: "START", coinGeckoId: "bscstarter", decimals: 18, price: 0.407304}, // Addr: 0x6ccf12b480a99c54b23647c995f4525d544a7e72, Notional: 1124.7755690550982 + {chain: 5, addr: "000000000000000000000000709a4b6217584188ddb93c82f5d716d969acce1c", symbol: "HANU", coinGeckoId: "hanu-yokia", decimals: 12, price: 2.26565e-7}, // Addr: 0x709a4b6217584188ddb93c82f5d716d969acce1c, Notional: 0.8565828928159431 + {chain: 5, addr: "00000000000000000000000070c006878a5a50ed185ac4c87d837633923de296", symbol: "REVV", coinGeckoId: "revv", decimals: 18, price: 0.00430643}, // Addr: 0x70c006878a5a50ed185ac4c87d837633923de296, Notional: 3.838805690980817 + {chain: 5, addr: "000000000000000000000000714db550b574b3e927af3d93e26127d15721d4c2", symbol: "GMT", coinGeckoId: "stepn", decimals: 8, price: 0.151428}, // Addr: 0x714db550b574b3e927af3d93e26127d15721d4c2, Notional: 5.981406000000001 + {chain: 5, addr: "000000000000000000000000723b17718289a91af252d616de2c77944962d122", symbol: "GAIA", coinGeckoId: "gaia-everworld", decimals: 18, price: 0.00264914}, // Addr: 0x723b17718289a91af252d616de2c77944962d122, Notional: 0.0256398430600416 + {chain: 5, addr: "000000000000000000000000750e4c4984a9e0f12978ea6742bc1c5d248f40ed", symbol: "axlUSDC", coinGeckoId: "axlusdc", decimals: 6, price: 0.998424}, // Addr: 0x750e4c4984a9e0f12978ea6742bc1c5d248f40ed, Notional: 81.449653723704 + {chain: 5, addr: "0000000000000000000000007844f79fc841e4f92d974c417031c76f8578c2d5", symbol: "OPN", coinGeckoId: "open-ticketing-ecosystem", decimals: 18, price: 0.00071188}, // Addr: 0x7844f79fc841e4f92d974c417031c76f8578c2d5, Notional: 0.80584816 + {chain: 5, addr: "00000000000000000000000078a0a62fba6fb21a83fe8a3433d44c73a4017a6f", symbol: "OX", coinGeckoId: "open-exchange-token", decimals: 18, price: 0.00540563}, // Addr: 0x78a0a62fba6fb21a83fe8a3433d44c73a4017a6f, Notional: 0.36887793607927655 + {chain: 5, addr: "0000000000000000000000007bebd226154e865954a87650faefa8f485d36081", symbol: "ZIG", coinGeckoId: "zignaly", decimals: 18, price: 0.112528}, // Addr: 0x7bebd226154e865954a87650faefa8f485d36081, Notional: 1.51961410070496 + {chain: 5, addr: "0000000000000000000000007ceb23fd6bc0add59e62ac25578270cff1b9f619", symbol: "WETH", coinGeckoId: "weth", decimals: 18, price: 3332.06}, // Addr: 0x7ceb23fd6bc0add59e62ac25578270cff1b9f619, Notional: 194290.4537175386 + {chain: 5, addr: "0000000000000000000000007e4c577ca35913af564ee2a24d882a4946ec492b", symbol: "MOONED", coinGeckoId: "moonedge", decimals: 18, price: 0.00484457}, // Addr: 0x7e4c577ca35913af564ee2a24d882a4946ec492b, Notional: 0.06147759732099311 + {chain: 5, addr: "00000000000000000000000081382e9693de2afc33f69b70a6c12ca9b3a73f47", symbol: "DOSE", coinGeckoId: "dose-token", decimals: 18, price: 0.00082455}, // Addr: 0x81382e9693de2afc33f69b70a6c12ca9b3a73f47, Notional: 0.0742095 + {chain: 5, addr: "000000000000000000000000831753dd7087cac61ab5644b308642cc1c33dc13", symbol: "QUICK", coinGeckoId: "quick", decimals: 18, price: 42.44}, // Addr: 0x831753dd7087cac61ab5644b308642cc1c33dc13, Notional: 6.6171773204 + {chain: 5, addr: "0000000000000000000000008765f05adce126d70bcdf1b0a48db573316662eb", symbol: "PLA", coinGeckoId: "playdapp", decimals: 18, price: 0.04400515}, // Addr: 0x8765f05adce126d70bcdf1b0a48db573316662eb, Notional: 68.42800825 + {chain: 5, addr: "00000000000000000000000088c949b4eb85a90071f2c0bef861bddee1a7479d", symbol: "mSHEESHA", coinGeckoId: "sheesha-finance-polygon", decimals: 18, price: 0.00020833}, // Addr: 0x88c949b4eb85a90071f2c0bef861bddee1a7479d, Notional: 0.0104165 + {chain: 5, addr: "0000000000000000000000008d1566569d5b695d44a9a234540f68d393cdc40d", symbol: "GAME", coinGeckoId: "gamecredits", decimals: 18, price: 0.0046127}, // Addr: 0x8d1566569d5b695d44a9a234540f68d393cdc40d, Notional: 0.0369016 + {chain: 5, addr: "0000000000000000000000008eef5a82e6aa222a60f009ac18c24ee12dbf4b41", symbol: "TXL", coinGeckoId: "autobahn-network", decimals: 18, price: 0.00424944}, // Addr: 0x8eef5a82e6aa222a60f009ac18c24ee12dbf4b41, Notional: 0.000042494400000000004 + {chain: 5, addr: "0000000000000000000000008f36cc333f55b09bb71091409a3d7ade399e3b1c", symbol: "CHER", coinGeckoId: "cherry-network", decimals: 18, price: 0.00100311}, // Addr: 0x8f36cc333f55b09bb71091409a3d7ade399e3b1c, Notional: 0.0100311 + {chain: 5, addr: "0000000000000000000000008f3cf7ad23cd3cadbd9735aff958023239c6a063", symbol: "DAI", coinGeckoId: "dai", decimals: 18, price: 0.99899}, // Addr: 0x8f3cf7ad23cd3cadbd9735aff958023239c6a063, Notional: 2477.5723716478337 + {chain: 5, addr: "0000000000000000000000009085b4d52c3e0b8b6f9af6213e85a433c7d76f19", symbol: "OWL", coinGeckoId: "owldao", decimals: 18, price: 0.00481548}, // Addr: 0x9085b4d52c3e0b8b6f9af6213e85a433c7d76f19, Notional: 1.0384106540459088 + {chain: 5, addr: "00000000000000000000000091c5a5488c0decde1eacd8a4f10e0942fb925067", symbol: "AUDT", coinGeckoId: "auditchain", decimals: 18, price: 0.05012}, // Addr: 0x91c5a5488c0decde1eacd8a4f10e0942fb925067, Notional: 501.2 {chain: 5, addr: "000000000000000000000000930a7dc10ae084fbbddc6537d7df7d4c65a40944", symbol: "UNLOCK", coinGeckoId: "unlock", decimals: 18, price: 0.00176187}, // Addr: 0x930a7dc10ae084fbbddc6537d7df7d4c65a40944, Notional: 0.176187 - {chain: 5, addr: "0000000000000000000000009c2c5fd7b07e95ee044ddeba0e97a665f142394f", symbol: "1INCH", coinGeckoId: "1inch", decimals: 18, price: 0.450082}, // Addr: 0x9c2c5fd7b07e95ee044ddeba0e97a665f142394f, Notional: 1.41318986418114 - {chain: 5, addr: "0000000000000000000000009c891326fd8b1a713974f73bb604677e1e63396d", symbol: "ISLAMI", coinGeckoId: "islamicoin", decimals: 7, price: 0.00013496}, // Addr: 0x9c891326fd8b1a713974f73bb604677e1e63396d, Notional: 0.13496 + {chain: 5, addr: "0000000000000000000000009c2c5fd7b07e95ee044ddeba0e97a665f142394f", symbol: "1INCH", coinGeckoId: "1inch", decimals: 18, price: 0.381911}, // Addr: 0x9c2c5fd7b07e95ee044ddeba0e97a665f142394f, Notional: 1.19914316551047 + {chain: 5, addr: "0000000000000000000000009c891326fd8b1a713974f73bb604677e1e63396d", symbol: "ISLAMI", coinGeckoId: "islamicoin", decimals: 7, price: 0.00009769}, // Addr: 0x9c891326fd8b1a713974f73bb604677e1e63396d, Notional: 0.09769 {chain: 5, addr: "0000000000000000000000009c9e5fd8bbc25984b178fdce6117defa39d2db39", symbol: "BUSD", coinGeckoId: "binance-peg-busd", decimals: 18, price: 1}, // Addr: 0x9c9e5fd8bbc25984b178fdce6117defa39d2db39, Notional: 8.09733836 - {chain: 5, addr: "0000000000000000000000009ca6a77c8b38159fd2da9bd25bc3e259c33f5e39", symbol: "SPORK", coinGeckoId: "sporkdao", decimals: 18, price: 0.01452623}, // Addr: 0x9ca6a77c8b38159fd2da9bd25bc3e259c33f5e39, Notional: 0.14526229999999998 - {chain: 5, addr: "0000000000000000000000009cb74c8032b007466865f060ad2c46145d45553d", symbol: "IDEX", coinGeckoId: "aurora-dao", decimals: 18, price: 0.050802}, // Addr: 0x9cb74c8032b007466865f060ad2c46145d45553d, Notional: 0.3082659873384 - {chain: 5, addr: "0000000000000000000000009e20461bc2c4c980f62f1b279d71734207a6a356", symbol: "OMNI", coinGeckoId: "omnicat", decimals: 18, price: 0.00004722}, // Addr: 0x9e20461bc2c4c980f62f1b279d71734207a6a356, Notional: 65.45073912434296 - {chain: 5, addr: "0000000000000000000000009ff62d1fc52a907b6dcba8077c2ddca6e6a9d3e1", symbol: "FORT", coinGeckoId: "forta", decimals: 18, price: 0.131661}, // Addr: 0x9ff62d1fc52a907b6dcba8077c2ddca6e6a9d3e1, Notional: 398.87787369402656 - {chain: 5, addr: "000000000000000000000000a1c57f48f0deb89f569dfbe6e2b7f46d33606fd4", symbol: "MANA", coinGeckoId: "decentraland", decimals: 18, price: 0.605668}, // Addr: 0xa1c57f48f0deb89f569dfbe6e2b7f46d33606fd4, Notional: 1013.7367796532155 - {chain: 5, addr: "000000000000000000000000a3fa99a148fa48d14ed51d610c367c61876997f1", symbol: "miMATIC", coinGeckoId: "mimatic", decimals: 18, price: 0.993831}, // Addr: 0xa3fa99a148fa48d14ed51d610c367c61876997f1, Notional: 29.72935340895651 - {chain: 5, addr: "000000000000000000000000a5eb60ca85898f8b26e18ff7c7e43623ccba772c", symbol: "COSMIC", coinGeckoId: "cosmicswap", decimals: 18, price: 0.0273851}, // Addr: 0xa5eb60ca85898f8b26e18ff7c7e43623ccba772c, Notional: 19.64271859344243 - {chain: 5, addr: "000000000000000000000000a649325aa7c5093d12d6f98eb4378deae68ce23f", symbol: "BNB", coinGeckoId: "wbnb", decimals: 18, price: 632.16}, // Addr: 0xa649325aa7c5093d12d6f98eb4378deae68ce23f, Notional: 3390.4949819904 - {chain: 5, addr: "000000000000000000000000a7051c5a22d963b81d71c2ba64d46a877fbc1821", symbol: "EROWAN", coinGeckoId: "sifchain", decimals: 18, price: 0.00000507}, // Addr: 0xa7051c5a22d963b81d71c2ba64d46a877fbc1821, Notional: 0.00004928298179609999 - {chain: 5, addr: "000000000000000000000000aa404804ba583c025fa64c9a276a6127ceb355c6", symbol: "CPR", coinGeckoId: "cipher-2", decimals: 2, price: 0.00121227}, // Addr: 0xaa404804ba583c025fa64c9a276a6127ceb355c6, Notional: 40346.84338535341 - {chain: 5, addr: "000000000000000000000000aaa5b9e6c589642f98a1cda99b9d024b8407285a", symbol: "TITAN", coinGeckoId: "iron-titanium-token", decimals: 18, price: 1.7209e-8}, // Addr: 0xaaa5b9e6c589642f98a1cda99b9d024b8407285a, Notional: 10.41414991238872 - {chain: 5, addr: "000000000000000000000000adbe0eac80f955363f4ff47b0f70189093908c04", symbol: "XMT", coinGeckoId: "metalswap", decimals: 18, price: 0.01288097}, // Addr: 0xadbe0eac80f955363f4ff47b0f70189093908c04, Notional: 12.4945409 - {chain: 5, addr: "000000000000000000000000b140665dde25c644c6b418e417c930de8a8a6ac9", symbol: "ATRI", coinGeckoId: "atari", decimals: 0, price: 0.0002562}, // Addr: 0xb140665dde25c644c6b418e417c930de8a8a6ac9, Notional: 0.0163968 - {chain: 5, addr: "000000000000000000000000b25e20de2f2ebb4cffd4d16a55c7b395e8a94762", symbol: "REQ", coinGeckoId: "request-network", decimals: 18, price: 0.125665}, // Addr: 0xb25e20de2f2ebb4cffd4d16a55c7b395e8a94762, Notional: 6.28325 - {chain: 5, addr: "000000000000000000000000b33eaad8d922b1083446dc23f610c2567fb5180f", symbol: "UNI", coinGeckoId: "uniswap", decimals: 18, price: 14.02}, // Addr: 0xb33eaad8d922b1083446dc23f610c2567fb5180f, Notional: 7.666087631000001 - {chain: 5, addr: "000000000000000000000000b6a5ae40e79891e4deadad06c8a7ca47396df21c", symbol: "CBY", coinGeckoId: "carbify", decimals: 18, price: 0.294663}, // Addr: 0xb6a5ae40e79891e4deadad06c8a7ca47396df21c, Notional: 0.1473315 - {chain: 5, addr: "000000000000000000000000b7b31a6bc18e48888545ce79e83e06003be70930", symbol: "APE", coinGeckoId: "apecoin", decimals: 18, price: 1.47}, // Addr: 0xb7b31a6bc18e48888545ce79e83e06003be70930, Notional: 0.2728283544 - {chain: 5, addr: "000000000000000000000000b87904db461005fc716a6bf9f2d451c33b10b80b", symbol: "AMKT", coinGeckoId: "alongside-crypto-market-index", decimals: 18, price: 253.98}, // Addr: 0xb87904db461005fc716a6bf9f2d451c33b10b80b, Notional: 13.086052821 - {chain: 5, addr: "000000000000000000000000ba777ae3a3c91fcd83ef85bfe65410592bdd0f7c", symbol: "CONE", coinGeckoId: "bitcone", decimals: 18, price: 0.00000117}, // Addr: 0xba777ae3a3c91fcd83ef85bfe65410592bdd0f7c, Notional: 6.1195329 - {chain: 5, addr: "000000000000000000000000bac3368b5110f3a3dda8b5a0f7b66edb37c47afe", symbol: "AIPEPE", coinGeckoId: "ai-pepe-king", decimals: 18, price: 8.67498e-10}, // Addr: 0xbac3368b5110f3a3dda8b5a0f7b66edb37c47afe, Notional: 0.00008674980000000001 - {chain: 5, addr: "000000000000000000000000bbba073c31bf03b8acf7c28ef0738decf3695683", symbol: "SAND", coinGeckoId: "the-sandbox", decimals: 18, price: 0.618816}, // Addr: 0xbbba073c31bf03b8acf7c28ef0738decf3695683, Notional: 157.15187957886914 - {chain: 5, addr: "000000000000000000000000bbbbbbbbb7949dcc7d1539c91b81a5bf09e37bdb", symbol: "CAW", coinGeckoId: "crow-with-knife", decimals: 18, price: 3.9789e-8}, // Addr: 0xbbbbbbbbb7949dcc7d1539c91b81a5bf09e37bdb, Notional: 2005.9588213707339 - {chain: 5, addr: "000000000000000000000000bbfe0b60de96a189bf09079de86a2db7bf0c7883", symbol: "eLunr", coinGeckoId: "lunr-token", decimals: 4, price: 0.02584591}, // Addr: 0xbbfe0b60de96a189bf09079de86a2db7bf0c7883, Notional: 52.738302803763 - {chain: 5, addr: "000000000000000000000000bc5eb84c052fd012bb902c258c9fd241b17c0005", symbol: "XNET", coinGeckoId: "xnet-mobile", decimals: 18, price: 0.03238179}, // Addr: 0xbc5eb84c052fd012bb902c258c9fd241b17c0005, Notional: 1936235.7724264346 - {chain: 5, addr: "000000000000000000000000c2132d05d31c914a87c6611c10748aeb04b58e8f", symbol: "USDT", coinGeckoId: "tether", decimals: 6, price: 1}, // Addr: 0xc2132d05d31c914a87c6611c10748aeb04b58e8f, Notional: 251749.892702 + {chain: 5, addr: "0000000000000000000000009ca6a77c8b38159fd2da9bd25bc3e259c33f5e39", symbol: "SPORK", coinGeckoId: "sporkdao", decimals: 18, price: 0.01064656}, // Addr: 0x9ca6a77c8b38159fd2da9bd25bc3e259c33f5e39, Notional: 0.1064656 + {chain: 5, addr: "0000000000000000000000009cb74c8032b007466865f060ad2c46145d45553d", symbol: "IDEX", coinGeckoId: "aurora-dao", decimals: 18, price: 0.065654}, // Addr: 0x9cb74c8032b007466865f060ad2c46145d45553d, Notional: 0.39838776293680006 + {chain: 5, addr: "0000000000000000000000009e20461bc2c4c980f62f1b279d71734207a6a356", symbol: "OMNI", coinGeckoId: "omnicat", decimals: 18, price: 0.00002616}, // Addr: 0x9e20461bc2c4c980f62f1b279d71734207a6a356, Notional: 36.25987580459153 + {chain: 5, addr: "0000000000000000000000009ff62d1fc52a907b6dcba8077c2ddca6e6a9d3e1", symbol: "FORT", coinGeckoId: "forta", decimals: 18, price: 0.109425}, // Addr: 0x9ff62d1fc52a907b6dcba8077c2ddca6e6a9d3e1, Notional: 331.5120751700872 + {chain: 5, addr: "000000000000000000000000a1c57f48f0deb89f569dfbe6e2b7f46d33606fd4", symbol: "MANA", coinGeckoId: "decentraland", decimals: 18, price: 0.464509}, // Addr: 0xa1c57f48f0deb89f569dfbe6e2b7f46d33606fd4, Notional: 777.4719116412548 + {chain: 5, addr: "000000000000000000000000a3fa99a148fa48d14ed51d610c367c61876997f1", symbol: "miMATIC", coinGeckoId: "mimatic", decimals: 18, price: 0.994558}, // Addr: 0xa3fa99a148fa48d14ed51d610c367c61876997f1, Notional: 29.751100808593183 + {chain: 5, addr: "000000000000000000000000a5eb60ca85898f8b26e18ff7c7e43623ccba772c", symbol: "COSMIC", coinGeckoId: "cosmicswap", decimals: 18, price: 0.02697684}, // Addr: 0xa5eb60ca85898f8b26e18ff7c7e43623ccba772c, Notional: 19.34988284360187 + {chain: 5, addr: "000000000000000000000000a649325aa7c5093d12d6f98eb4378deae68ce23f", symbol: "BNB", coinGeckoId: "wbnb", decimals: 18, price: 699.48}, // Addr: 0xa649325aa7c5093d12d6f98eb4378deae68ce23f, Notional: 3751.5556662912004 + {chain: 5, addr: "000000000000000000000000a7051c5a22d963b81d71c2ba64d46a877fbc1821", symbol: "EROWAN", coinGeckoId: "sifchain", decimals: 18, price: 0.00000561}, // Addr: 0xa7051c5a22d963b81d71c2ba64d46a877fbc1821, Notional: 0.00005453205678029999 + {chain: 5, addr: "000000000000000000000000aa404804ba583c025fa64c9a276a6127ceb355c6", symbol: "CPR", coinGeckoId: "cipher-2", decimals: 2, price: 0.00029895}, // Addr: 0xaa404804ba583c025fa64c9a276a6127ceb355c6, Notional: 9949.671962559 + {chain: 5, addr: "000000000000000000000000aaa5b9e6c589642f98a1cda99b9d024b8407285a", symbol: "TITAN", coinGeckoId: "iron-titanium-token", decimals: 18, price: 1.2845e-8}, // Addr: 0xaaa5b9e6c589642f98a1cda99b9d024b8407285a, Notional: 7.773243978420194 + {chain: 5, addr: "000000000000000000000000adbe0eac80f955363f4ff47b0f70189093908c04", symbol: "XMT", coinGeckoId: "metalswap", decimals: 18, price: 0.01107415}, // Addr: 0xadbe0eac80f955363f4ff47b0f70189093908c04, Notional: 10.741925499999999 + {chain: 5, addr: "000000000000000000000000b140665dde25c644c6b418e417c930de8a8a6ac9", symbol: "ATRI", coinGeckoId: "atari", decimals: 0, price: 0.00024964}, // Addr: 0xb140665dde25c644c6b418e417c930de8a8a6ac9, Notional: 0.01597696 + {chain: 5, addr: "000000000000000000000000b25e20de2f2ebb4cffd4d16a55c7b395e8a94762", symbol: "REQ", coinGeckoId: "request-network", decimals: 18, price: 0.135704}, // Addr: 0xb25e20de2f2ebb4cffd4d16a55c7b395e8a94762, Notional: 6.7852 + {chain: 5, addr: "000000000000000000000000b33eaad8d922b1083446dc23f610c2567fb5180f", symbol: "UNI", coinGeckoId: "uniswap", decimals: 18, price: 13.19}, // Addr: 0xb33eaad8d922b1083446dc23f610c2567fb5180f, Notional: 7.2122464945 + {chain: 5, addr: "000000000000000000000000b6a5ae40e79891e4deadad06c8a7ca47396df21c", symbol: "CBY", coinGeckoId: "carbify", decimals: 18, price: 0.647582}, // Addr: 0xb6a5ae40e79891e4deadad06c8a7ca47396df21c, Notional: 0.323791 + {chain: 5, addr: "000000000000000000000000b7b31a6bc18e48888545ce79e83e06003be70930", symbol: "APE", coinGeckoId: "apecoin", decimals: 18, price: 1.2}, // Addr: 0xb7b31a6bc18e48888545ce79e83e06003be70930, Notional: 0.22271702399999999 + {chain: 5, addr: "000000000000000000000000b87904db461005fc716a6bf9f2d451c33b10b80b", symbol: "AMKT", coinGeckoId: "alongside-crypto-market-index", decimals: 18, price: 267.16}, // Addr: 0xb87904db461005fc716a6bf9f2d451c33b10b80b, Notional: 13.765138482000001 + {chain: 5, addr: "000000000000000000000000ba777ae3a3c91fcd83ef85bfe65410592bdd0f7c", symbol: "CONE", coinGeckoId: "bitcone", decimals: 18, price: 9.64083e-7}, // Addr: 0xba777ae3a3c91fcd83ef85bfe65410592bdd0f7c, Notional: 5.04251080071 + {chain: 5, addr: "000000000000000000000000bac3368b5110f3a3dda8b5a0f7b66edb37c47afe", symbol: "AIPEPE", coinGeckoId: "ai-pepe-king", decimals: 18, price: 6.51071e-10}, // Addr: 0xbac3368b5110f3a3dda8b5a0f7b66edb37c47afe, Notional: 0.0000651071 + {chain: 5, addr: "000000000000000000000000bbba073c31bf03b8acf7c28ef0738decf3695683", symbol: "SAND", coinGeckoId: "the-sandbox", decimals: 18, price: 0.546103}, // Addr: 0xbbba073c31bf03b8acf7c28ef0738decf3695683, Notional: 138.77538930140318 + {chain: 5, addr: "000000000000000000000000bbbbbbbbb7949dcc7d1539c91b81a5bf09e37bdb", symbol: "CAW", coinGeckoId: "crow-with-knife", decimals: 18, price: 3.6612e-8}, // Addr: 0xbbbbbbbbb7949dcc7d1539c91b81a5bf09e37bdb, Notional: 1824.8416553931597 + {chain: 5, addr: "000000000000000000000000bbfe0b60de96a189bf09079de86a2db7bf0c7883", symbol: "eLunr", coinGeckoId: "lunr-token", decimals: 4, price: 0.00862433}, // Addr: 0xbbfe0b60de96a189bf09079de86a2db7bf0c7883, Notional: 17.597853084668998 + {chain: 5, addr: "000000000000000000000000bc5eb84c052fd012bb902c258c9fd241b17c0005", symbol: "XNET", coinGeckoId: "xnet-mobile", decimals: 18, price: 0.02740488}, // Addr: 0xbc5eb84c052fd012bb902c258c9fd241b17c0005, Notional: 1638545.8671314663 + {chain: 5, addr: "000000000000000000000000bd1463f02f61676d53fd183c2b19282bff93d099", symbol: "jCHF", coinGeckoId: "jarvis-synthetic-swiss-franc", decimals: 18, price: 0.268218}, // Addr: 0xbd1463f02f61676d53fd183c2b19282bff93d099, Notional: 5.04440064497088 + {chain: 5, addr: "000000000000000000000000c2132d05d31c914a87c6611c10748aeb04b58e8f", symbol: "USDT", coinGeckoId: "tether", decimals: 6, price: 0.99789}, // Addr: 0xc2132d05d31c914a87c6611c10748aeb04b58e8f, Notional: 270641.46859960945 {chain: 5, addr: "000000000000000000000000c3c7d422809852031b44ab29eec9f1eff2a58756", symbol: "LDO", coinGeckoId: "lido-dao", decimals: 18, price: 1.75}, // Addr: 0xc3c7d422809852031b44ab29eec9f1eff2a58756, Notional: 17.5175 - {chain: 5, addr: "000000000000000000000000cf32822ff397ef82425153a9dcb726e5ff61dca7", symbol: "GMEE", coinGeckoId: "gamee", decimals: 18, price: 0.01186076}, // Addr: 0xcf32822ff397ef82425153a9dcb726e5ff61dca7, Notional: 160.26229549051834 - {chain: 5, addr: "000000000000000000000000d3b71117e6c1558c1553305b44988cd944e97300", symbol: "YEL", coinGeckoId: "yel-finance", decimals: 18, price: 0.00285637}, // Addr: 0xd3b71117e6c1558c1553305b44988cd944e97300, Notional: 2.85637 - {chain: 5, addr: "000000000000000000000000d60deba014459f07bbcc077a5b817f31dafd5229", symbol: "VATRENI", coinGeckoId: "croatian-ff-fan-token", decimals: 18, price: 0.100804}, // Addr: 0xd60deba014459f07bbcc077a5b817f31dafd5229, Notional: 0.100804 - {chain: 5, addr: "000000000000000000000000d6df932a45c0f255f85145f286ea0b292b21c90b", symbol: "AAVE", coinGeckoId: "aave", decimals: 18, price: 221.33}, // Addr: 0xd6df932a45c0f255f85145f286ea0b292b21c90b, Notional: 1159.2293694901 - {chain: 5, addr: "000000000000000000000000d838290e877e0188a4a44700463419ed96c16107", symbol: "NCT", coinGeckoId: "toucan-protocol-base-carbon-tonne", decimals: 18, price: 0.539934}, // Addr: 0xd838290e877e0188a4a44700463419ed96c16107, Notional: 24.29703 - {chain: 5, addr: "000000000000000000000000d86b5923f3ad7b585ed81b448170ae026c65ae9a", symbol: "IRON", coinGeckoId: "iron-stablecoin", decimals: 18, price: 0.00020411}, // Addr: 0xd86b5923f3ad7b585ed81b448170ae026c65ae9a, Notional: 41.085562554246316 - {chain: 5, addr: "000000000000000000000000d8ca34fd379d9ca3c6ee3b3905678320f5b45195", symbol: "gOHM", coinGeckoId: "governance-ohm", decimals: 18, price: 4856.15}, // Addr: 0xd8ca34fd379d9ca3c6ee3b3905678320f5b45195, Notional: 35.90399358649999 - {chain: 5, addr: "000000000000000000000000dab529f40e671a1d4bf91361c21bf9f0c9712ab7", symbol: "BUSD", coinGeckoId: "binance-usd", decimals: 18, price: 0.991874}, // Addr: 0xdab529f40e671a1d4bf91361c21bf9f0c9712ab7, Notional: 351.81920082825724 - {chain: 5, addr: "000000000000000000000000dc3326e71d45186f113a2f448984ca0e8d201995", symbol: "XSGD", coinGeckoId: "xsgd", decimals: 6, price: 0.744945}, // Addr: 0xdc3326e71d45186f113a2f448984ca0e8d201995, Notional: 1.48989 - {chain: 5, addr: "000000000000000000000000e0339c80ffde91f3e20494df88d4206d86024cdf", symbol: "ELON", coinGeckoId: "dogelon-mars", decimals: 18, price: 2.12852e-7}, // Addr: 0xe0339c80ffde91f3e20494df88d4206d86024cdf, Notional: 204.43278823444166 - {chain: 5, addr: "000000000000000000000000e0bceef36f3a6efdd5eebfacd591423f8549b9d5", symbol: "FACTR", coinGeckoId: "defactor", decimals: 18, price: 0.050527}, // Addr: 0xe0bceef36f3a6efdd5eebfacd591423f8549b9d5, Notional: 1.9460252281944301 - {chain: 5, addr: "000000000000000000000000e20b9e246db5a0d21bf9209e4858bc9a3ff7a034", symbol: "wBAN", coinGeckoId: "banano", decimals: 18, price: 0.00433194}, // Addr: 0xe20b9e246db5a0d21bf9209e4858bc9a3ff7a034, Notional: 44.686046739327715 - {chain: 5, addr: "000000000000000000000000e261d618a959afffd53168cd07d12e37b26761db", symbol: "DIMO", coinGeckoId: "dimo", decimals: 18, price: 0.224073}, // Addr: 0xe261d618a959afffd53168cd07d12e37b26761db, Notional: 5446.085027778797 - {chain: 5, addr: "000000000000000000000000e5417af564e4bfda1c483642db72007871397896", symbol: "GNS", coinGeckoId: "gains-network", decimals: 18, price: 2.47}, // Addr: 0xe5417af564e4bfda1c483642db72007871397896, Notional: 56.81013832000001 - {chain: 5, addr: "000000000000000000000000e78aee6ccb05471a69677fb74da80f5d251c042b", symbol: "TAKI", coinGeckoId: "taki", decimals: 18, price: 0.00192391}, // Addr: 0xe78aee6ccb05471a69677fb74da80f5d251c042b, Notional: 0.7417736232678996 - {chain: 5, addr: "000000000000000000000000e8d17b127ba8b9899a160d9a07b69bca8e08bfc6", symbol: "NSDX", coinGeckoId: "nasdex-token", decimals: 18, price: 0.02443761}, // Addr: 0xe8d17b127ba8b9899a160d9a07b69bca8e08bfc6, Notional: 1.09969245 - {chain: 5, addr: "000000000000000000000000e9993763e0b7f7d915a62a5f22a6e151f91d98a8", symbol: "TORG", coinGeckoId: "torg", decimals: 18, price: 2.7513e-8}, // Addr: 0xe9993763e0b7f7d915a62a5f22a6e151f91d98a8, Notional: 0.0085339378109485 - {chain: 5, addr: "000000000000000000000000e9e7c09e82328c3107d367f6c617cf9977e63ed0", symbol: "A51", coinGeckoId: "a51-finance", decimals: 18, price: 0.131096}, // Addr: 0xe9e7c09e82328c3107d367f6c617cf9977e63ed0, Notional: 44838.04065342803 + {chain: 5, addr: "000000000000000000000000cf32822ff397ef82425153a9dcb726e5ff61dca7", symbol: "GMEE", coinGeckoId: "gamee", decimals: 18, price: 0.01098331}, // Addr: 0xcf32822ff397ef82425153a9dcb726e5ff61dca7, Notional: 148.40621281300398 + {chain: 5, addr: "000000000000000000000000d3b71117e6c1558c1553305b44988cd944e97300", symbol: "YEL", coinGeckoId: "yel-finance", decimals: 18, price: 0.00154947}, // Addr: 0xd3b71117e6c1558c1553305b44988cd944e97300, Notional: 1.5494700000000001 + {chain: 5, addr: "000000000000000000000000d60deba014459f07bbcc077a5b817f31dafd5229", symbol: "VATRENI", coinGeckoId: "croatian-ff-fan-token", decimals: 18, price: 0.423296}, // Addr: 0xd60deba014459f07bbcc077a5b817f31dafd5229, Notional: 0.423296 + {chain: 5, addr: "000000000000000000000000d6df932a45c0f255f85145f286ea0b292b21c90b", symbol: "AAVE", coinGeckoId: "aave", decimals: 18, price: 309.59}, // Addr: 0xd6df932a45c0f255f85145f286ea0b292b21c90b, Notional: 1621.4965007022997 + {chain: 5, addr: "000000000000000000000000d838290e877e0188a4a44700463419ed96c16107", symbol: "NCT", coinGeckoId: "toucan-protocol-base-carbon-tonne", decimals: 18, price: 0.385738}, // Addr: 0xd838290e877e0188a4a44700463419ed96c16107, Notional: 17.35821 + {chain: 5, addr: "000000000000000000000000d86b5923f3ad7b585ed81b448170ae026c65ae9a", symbol: "IRON", coinGeckoId: "iron-stablecoin", decimals: 18, price: 0.00019314}, // Addr: 0xd86b5923f3ad7b585ed81b448170ae026c65ae9a, Notional: 38.87739724524587 + {chain: 5, addr: "000000000000000000000000d8ca34fd379d9ca3c6ee3b3905678320f5b45195", symbol: "gOHM", coinGeckoId: "governance-ohm", decimals: 18, price: 5398.41}, // Addr: 0xd8ca34fd379d9ca3c6ee3b3905678320f5b45195, Notional: 39.9131983191 + {chain: 5, addr: "000000000000000000000000dab529f40e671a1d4bf91361c21bf9f0c9712ab7", symbol: "BUSD", coinGeckoId: "binance-usd", decimals: 18, price: 0.994995}, // Addr: 0xdab529f40e671a1d4bf91361c21bf9f0c9712ab7, Notional: 352.92622422617364 + {chain: 5, addr: "000000000000000000000000dc3326e71d45186f113a2f448984ca0e8d201995", symbol: "XSGD", coinGeckoId: "xsgd", decimals: 6, price: 0.732155}, // Addr: 0xdc3326e71d45186f113a2f448984ca0e8d201995, Notional: 1.467970775 + {chain: 5, addr: "000000000000000000000000e0339c80ffde91f3e20494df88d4206d86024cdf", symbol: "ELON", coinGeckoId: "dogelon-mars", decimals: 18, price: 2.03255e-7}, // Addr: 0xe0339c80ffde91f3e20494df88d4206d86024cdf, Notional: 195.2153908471212 + {chain: 5, addr: "000000000000000000000000e0bceef36f3a6efdd5eebfacd591423f8549b9d5", symbol: "FACTR", coinGeckoId: "defactor", decimals: 18, price: 0.03985116}, // Addr: 0xe0bceef36f3a6efdd5eebfacd591423f8549b9d5, Notional: 2.1326173363273644 + {chain: 5, addr: "000000000000000000000000e20b9e246db5a0d21bf9209e4858bc9a3ff7a034", symbol: "wBAN", coinGeckoId: "banano", decimals: 18, price: 0.00389031}, // Addr: 0xe20b9e246db5a0d21bf9209e4858bc9a3ff7a034, Notional: 40.13042066383052 + {chain: 5, addr: "000000000000000000000000e261d618a959afffd53168cd07d12e37b26761db", symbol: "DIMO", coinGeckoId: "dimo", decimals: 18, price: 0.165445}, // Addr: 0xe261d618a959afffd53168cd07d12e37b26761db, Notional: 4021.133904668849 + {chain: 5, addr: "000000000000000000000000e4bf2864ebec7b7fdf6eeca9bacae7cdfdaffe78", symbol: "DODO", coinGeckoId: "dodo", decimals: 18, price: 0.151651}, // Addr: 0xe4bf2864ebec7b7fdf6eeca9bacae7cdfdaffe78, Notional: 0.00007440604664 + {chain: 5, addr: "000000000000000000000000e5417af564e4bfda1c483642db72007871397896", symbol: "GNS", coinGeckoId: "gains-network", decimals: 18, price: 1.79}, // Addr: 0xe5417af564e4bfda1c483642db72007871397896, Notional: 41.170100240000004 + {chain: 5, addr: "000000000000000000000000e78aee6ccb05471a69677fb74da80f5d251c042b", symbol: "TAKI", coinGeckoId: "taki", decimals: 18, price: 0.0021849}, // Addr: 0xe78aee6ccb05471a69677fb74da80f5d251c042b, Notional: 0.842399690982444 + {chain: 5, addr: "000000000000000000000000e8d17b127ba8b9899a160d9a07b69bca8e08bfc6", symbol: "NSDX", coinGeckoId: "nasdex-token", decimals: 18, price: 0.0203546}, // Addr: 0xe8d17b127ba8b9899a160d9a07b69bca8e08bfc6, Notional: 0.915957 + {chain: 5, addr: "000000000000000000000000e9993763e0b7f7d915a62a5f22a6e151f91d98a8", symbol: "TORG", coinGeckoId: "torg", decimals: 18, price: 5.3253e-8}, // Addr: 0xe9993763e0b7f7d915a62a5f22a6e151f91d98a8, Notional: 0.016517929351449877 + {chain: 5, addr: "000000000000000000000000e9e7c09e82328c3107d367f6c617cf9977e63ed0", symbol: "A51", coinGeckoId: "a51-finance", decimals: 18, price: 0.097421}, // Addr: 0xe9e7c09e82328c3107d367f6c617cf9977e63ed0, Notional: 38741.864634659956 {chain: 5, addr: "000000000000000000000000edcfb6984a3c70501baa8b7f5421ae795ecc1496", symbol: "META", coinGeckoId: "abcmeta", decimals: 8, price: 2.29278e-7}, // Addr: 0xedcfb6984a3c70501baa8b7f5421ae795ecc1496, Notional: 0.007008799182 - {chain: 5, addr: "000000000000000000000000ee327f889d5947c1dc1934bb208a1e792f953e96", symbol: "frxETH", coinGeckoId: "frax-ether", decimals: 18, price: 3585}, // Addr: 0xee327f889d5947c1dc1934bb208a1e792f953e96, Notional: 228.1306146 - {chain: 5, addr: "000000000000000000000000ee7666aacaefaa6efeef62ea40176d3eb21953b9", symbol: "MCHC", coinGeckoId: "mch-coin", decimals: 18, price: 0.057176}, // Addr: 0xee7666aacaefaa6efeef62ea40176d3eb21953b9, Notional: 35.02469201617848 - {chain: 5, addr: "000000000000000000000000ee9801669c6138e84bd50deb500827b776777d28", symbol: "O3", coinGeckoId: "o3-swap", decimals: 18, price: 0.0101476}, // Addr: 0xee9801669c6138e84bd50deb500827b776777d28, Notional: 14.446125158357672 - {chain: 5, addr: "000000000000000000000000eee3371b89fc43ea970e908536fcddd975135d8a", symbol: "DOG", coinGeckoId: "the-doge-nft", decimals: 18, price: 0.00464939}, // Addr: 0xeee3371b89fc43ea970e908536fcddd975135d8a, Notional: 0.00464939 - {chain: 5, addr: "000000000000000000000000eeeeeb57642040be42185f49c52f7e9b38f8eeee", symbol: "ELK", coinGeckoId: "elk-finance", decimals: 18, price: 0.092026}, // Addr: 0xeeeeeb57642040be42185f49c52f7e9b38f8eeee, Notional: 0.184052 - {chain: 5, addr: "000000000000000000000000efee2de82343be622dcb4e545f75a3b9f50c272d", symbol: "TRY", coinGeckoId: "tryhards", decimals: 18, price: 0.00025119}, // Addr: 0xefee2de82343be622dcb4e545f75a3b9f50c272d, Notional: 0.3183617663645481 - {chain: 5, addr: "000000000000000000000000f21441f9ec4c1fe69cb7cf186eceab31af2b658d", symbol: "VENT", coinGeckoId: "vent-finance", decimals: 18, price: 0.00168383}, // Addr: 0xf21441f9ec4c1fe69cb7cf186eceab31af2b658d, Notional: 10.271363000000001 + {chain: 5, addr: "000000000000000000000000ee327f889d5947c1dc1934bb208a1e792f953e96", symbol: "frxETH", coinGeckoId: "frax-ether", decimals: 18, price: 3345.67}, // Addr: 0xee327f889d5947c1dc1934bb208a1e792f953e96, Notional: 212.9009074892 + {chain: 5, addr: "000000000000000000000000ee7666aacaefaa6efeef62ea40176d3eb21953b9", symbol: "MCHC", coinGeckoId: "mch-coin", decimals: 18, price: 0.04931065}, // Addr: 0xee7666aacaefaa6efeef62ea40176d3eb21953b9, Notional: 30.206560958576524 + {chain: 5, addr: "000000000000000000000000ee9801669c6138e84bd50deb500827b776777d28", symbol: "O3", coinGeckoId: "o3-swap", decimals: 18, price: 0.00953653}, // Addr: 0xee9801669c6138e84bd50deb500827b776777d28, Notional: 13.576205798063846 + {chain: 5, addr: "000000000000000000000000eee3371b89fc43ea970e908536fcddd975135d8a", symbol: "DOG", coinGeckoId: "the-doge-nft", decimals: 18, price: 0.00399146}, // Addr: 0xeee3371b89fc43ea970e908536fcddd975135d8a, Notional: 0.00399146 + {chain: 5, addr: "000000000000000000000000eeeeeb57642040be42185f49c52f7e9b38f8eeee", symbol: "ELK", coinGeckoId: "elk-finance", decimals: 18, price: 0.077467}, // Addr: 0xeeeeeb57642040be42185f49c52f7e9b38f8eeee, Notional: 0.154934 + {chain: 5, addr: "000000000000000000000000efee2de82343be622dcb4e545f75a3b9f50c272d", symbol: "TRY", coinGeckoId: "tryhards", decimals: 18, price: 0.00000877}, // Addr: 0xefee2de82343be622dcb4e545f75a3b9f50c272d, Notional: 0.011115222305892302 + {chain: 5, addr: "000000000000000000000000f21441f9ec4c1fe69cb7cf186eceab31af2b658d", symbol: "VENT", coinGeckoId: "vent-finance", decimals: 18, price: 0.00155177}, // Addr: 0xf21441f9ec4c1fe69cb7cf186eceab31af2b658d, Notional: 9.465797 {chain: 5, addr: "000000000000000000000000f28164a485b0b2c90639e47b0f377b4a438a16b1", symbol: "dQUICK", coinGeckoId: "dragons-quick", decimals: 18, price: 0.068364}, // Addr: 0xf28164a485b0b2c90639e47b0f377b4a438a16b1, Notional: 0.0001664253216 - {chain: 5, addr: "000000000000000000000000fbdd194376de19a88118e84e279b977f165d01b8", symbol: "BIFI", coinGeckoId: "beefy-finance", decimals: 18, price: 332.12}, // Addr: 0xfbdd194376de19a88118e84e279b977f165d01b8, Notional: 26420.7301193712 - {chain: 6, addr: "0000000000000000000000000da67235dd5787d67955420c84ca1cecd4e5bb3b", symbol: "wMEMO", coinGeckoId: "wrapped-memory", decimals: 18, price: 233.76}, // Addr: 0x0da67235dd5787d67955420c84ca1cecd4e5bb3b, Notional: 0.7413908784000001 - {chain: 6, addr: "000000000000000000000000130966628846bfd36ff31a822705796e8cb8c18d", symbol: "MIM", coinGeckoId: "magic-internet-money", decimals: 18, price: 0.99491}, // Addr: 0x130966628846bfd36ff31a822705796e8cb8c18d, Notional: 135.0606699825726 - {chain: 6, addr: "000000000000000000000000152b9d0fdc40c096757f570a51e494bd4b943e50", symbol: "BTC.b", coinGeckoId: "bitcoin-avalanche-bridged-btc-b", decimals: 8, price: 94905}, // Addr: 0x152b9d0fdc40c096757f570a51e494bd4b943e50, Notional: 789.16449555 - {chain: 6, addr: "0000000000000000000000001f1e7c893855525b303f99bdf5c3c05be09ca251", symbol: "SYN", coinGeckoId: "synapse-2", decimals: 18, price: 0.673714}, // Addr: 0x1f1e7c893855525b303f99bdf5c3c05be09ca251, Notional: 186.04466587776 - {chain: 6, addr: "00000000000000000000000020cf1b6e9d856321ed4686877cf4538f2c84b4de", symbol: "ANKR", coinGeckoId: "ankr", decimals: 18, price: 0.04128546}, // Addr: 0x20cf1b6e9d856321ed4686877cf4538f2c84b4de, Notional: 4.128546 - {chain: 6, addr: "0000000000000000000000002598c30330d5771ae9f983979209486ae26de875", symbol: "AI", coinGeckoId: "any-inu", decimals: 18, price: 0.00000789}, // Addr: 0x2598c30330d5771ae9f983979209486ae26de875, Notional: 37.773999088523425 - {chain: 6, addr: "000000000000000000000000264c1383ea520f73dd837f915ef3a732e204a493", symbol: "BNB", coinGeckoId: "wbnb", decimals: 18, price: 632.16}, // Addr: 0x264c1383ea520f73dd837f915ef3a732e204a493, Notional: 7968.399292252799 - {chain: 6, addr: "0000000000000000000000002b2c81e08f1af8835a78bb2a90ae924ace0ea4be", symbol: "sAVAX", coinGeckoId: "benqi-liquid-staked-avax", decimals: 18, price: 54.69}, // Addr: 0x2b2c81e08f1af8835a78bb2a90ae924ace0ea4be, Notional: 1156000.2352268447 - {chain: 6, addr: "0000000000000000000000002f6f07cdcf3588944bf4c42ac74ff24bf56e7590", symbol: "STG", coinGeckoId: "stargate-finance", decimals: 18, price: 0.382194}, // Addr: 0x2f6f07cdcf3588944bf4c42ac74ff24bf56e7590, Notional: 5.0717640461102995 - {chain: 6, addr: "00000000000000000000000031c994ac062c1970c086260bc61babb708643fac", symbol: "XETA", coinGeckoId: "xana", decimals: 18, price: 0.0032103}, // Addr: 0x31c994ac062c1970c086260bc61babb708643fac, Notional: 0.032103 - {chain: 6, addr: "000000000000000000000000321e7092a180bb43555132ec53aaa65a5bf84251", symbol: "gOHM", coinGeckoId: "governance-ohm", decimals: 18, price: 4856.15}, // Addr: 0x321e7092a180bb43555132ec53aaa65a5bf84251, Notional: 21.758271444 - {chain: 6, addr: "000000000000000000000000323665443cef804a3b5206103304bd4872ea4253", symbol: "USDV", coinGeckoId: "verified-usd-foundation-usdv", decimals: 6, price: 0.999897}, // Addr: 0x323665443cef804a3b5206103304bd4872ea4253, Notional: 7.521449210928 - {chain: 6, addr: "0000000000000000000000003419875b4d3bca7f3fdda2db7a476a79fd31b4fe", symbol: "DZHV", coinGeckoId: "dizzyhavoc", decimals: 18, price: 0.00084136}, // Addr: 0x3419875b4d3bca7f3fdda2db7a476a79fd31b4fe, Notional: 0.6304281749070447 - {chain: 6, addr: "0000000000000000000000003eefb18003d033661f84e48360ebecd181a84709", symbol: "ISA", coinGeckoId: "islander", decimals: 18, price: 0.00002321}, // Addr: 0x3eefb18003d033661f84e48360ebecd181a84709, Notional: 0.0017753798350299 - {chain: 6, addr: "000000000000000000000000431d5dff03120afa4bdf332c61a6e1766ef37bdb", symbol: "JPYC", coinGeckoId: "jpy-coin", decimals: 18, price: 0.00623013}, // Addr: 0x431d5dff03120afa4bdf332c61a6e1766ef37bdb, Notional: 2.1457128552564524 - {chain: 6, addr: "000000000000000000000000444444444444c1a66f394025ac839a535246fcc8", symbol: "GENI", coinGeckoId: "genius", decimals: 9, price: 8.20707e-7}, // Addr: 0x444444444444c1a66f394025ac839a535246fcc8, Notional: 0.4707464835272925 - {chain: 6, addr: "000000000000000000000000491a4eb4f1fc3bff8e1d2fc856a6a46663ad556f", symbol: "BRZ", coinGeckoId: "brz", decimals: 4, price: 0.159991}, // Addr: 0x491a4eb4f1fc3bff8e1d2fc856a6a46663ad556f, Notional: 0.159991 - {chain: 6, addr: "00000000000000000000000049d5c2bdffac6ce2bfdb6640f4f80f226bc10bab", symbol: "WETH.e", coinGeckoId: "weth", decimals: 18, price: 3594.89}, // Addr: 0x49d5c2bdffac6ce2bfdb6640f4f80f226bc10bab, Notional: 18231.3012596611 - {chain: 6, addr: "0000000000000000000000004bfc90322dd638f81f034517359bd447f8e0235a", symbol: "NEWO", coinGeckoId: "new-order", decimals: 18, price: 0.00456828}, // Addr: 0x4bfc90322dd638f81f034517359bd447f8e0235a, Notional: 37232.0557344496 - {chain: 6, addr: "000000000000000000000000502580fc390606b47fc3b741d6d49909383c28a9", symbol: "HATCHY", coinGeckoId: "hatchypocket", decimals: 18, price: 0.00142558}, // Addr: 0x502580fc390606b47fc3b741d6d49909383c28a9, Notional: 0.0070851326 - {chain: 6, addr: "0000000000000000000000005085434227ab73151fad2de546210cbc8663df96", symbol: "DBY", coinGeckoId: "metaderby", decimals: 18, price: 0.00217262}, // Addr: 0x5085434227ab73151fad2de546210cbc8663df96, Notional: 19336.52222628 - {chain: 6, addr: "00000000000000000000000050b7545627a5162f82a992c33b87adc75187b218", symbol: "WBTC.e", coinGeckoId: "wrapped-bitcoin", decimals: 8, price: 94688}, // Addr: 0x50b7545627a5162f82a992c33b87adc75187b218, Notional: 2825.9728288 - {chain: 6, addr: "000000000000000000000000564a341df6c126f90cf3ecb92120fd7190acb401", symbol: "TRYB", coinGeckoId: "bilira", decimals: 6, price: 0.02884969}, // Addr: 0x564a341df6c126f90cf3ecb92120fd7190acb401, Notional: 0.02884969 - {chain: 6, addr: "0000000000000000000000005947bb275c521040051d82396192181b413227a3", symbol: "LINK.e", coinGeckoId: "chainlink", decimals: 18, price: 19.89}, // Addr: 0x5947bb275c521040051d82396192181b413227a3, Notional: 1.989 - {chain: 6, addr: "00000000000000000000000062edc0692bd897d2295872a9ffcac5425011c661", symbol: "GMX", coinGeckoId: "gmx", decimals: 18, price: 30.25}, // Addr: 0x62edc0692bd897d2295872a9ffcac5425011c661, Notional: 109.90429395 - {chain: 6, addr: "00000000000000000000000063682bdc5f875e9bf69e201550658492c9763f89", symbol: "BSGG", coinGeckoId: "betswap-gg", decimals: 18, price: 0.00070246}, // Addr: 0x63682bdc5f875e9bf69e201550658492c9763f89, Notional: 0.5285131195251468 - {chain: 6, addr: "00000000000000000000000063a72806098bd3d9520cc43356dd78afe5d386d9", symbol: "AAVE.e", coinGeckoId: "aave", decimals: 18, price: 221.33}, // Addr: 0x63a72806098bd3d9520cc43356dd78afe5d386d9, Notional: 2.0825249562 - {chain: 6, addr: "00000000000000000000000068ee0d0aad9e1984af85ca224117e4d20eaf68be", symbol: "ROY", coinGeckoId: "crypto-royale", decimals: 18, price: 0.00293374}, // Addr: 0x68ee0d0aad9e1984af85ca224117e4d20eaf68be, Notional: 0.20242806 - {chain: 6, addr: "0000000000000000000000006e84a6216ea6dacc71ee8e6b0a5b7322eebc0fdd", symbol: "JOE", coinGeckoId: "joe", decimals: 18, price: 0.530655}, // Addr: 0x6e84a6216ea6dacc71ee8e6b0a5b7322eebc0fdd, Notional: 0.05837205530654999 - {chain: 6, addr: "000000000000000000000000714f020c54cc9d104b6f4f6998c63ce2a31d1888", symbol: "FITFI", coinGeckoId: "step-app-fitfi", decimals: 18, price: 0.00358223}, // Addr: 0x714f020c54cc9d104b6f4f6998c63ce2a31d1888, Notional: 0.0003582230358223 - {chain: 6, addr: "000000000000000000000000820802fa8a99901f52e39acd21177b0be6ee2974", symbol: "EUROe", coinGeckoId: "euroe-stablecoin", decimals: 6, price: 1.056}, // Addr: 0x820802fa8a99901f52e39acd21177b0be6ee2974, Notional: 1.393031904 - {chain: 6, addr: "0000000000000000000000008729438eb15e2c8b576fcc6aecda6a148776c0f5", symbol: "QI", coinGeckoId: "benqi", decimals: 18, price: 0.01964962}, // Addr: 0x8729438eb15e2c8b576fcc6aecda6a148776c0f5, Notional: 0.01964962 - {chain: 6, addr: "0000000000000000000000008929e9dbd2785e3ba16175e596cdd61520fee0d1", symbol: "ALTD", coinGeckoId: "altitude", decimals: 18, price: 0.00074529}, // Addr: 0x8929e9dbd2785e3ba16175e596cdd61520fee0d1, Notional: 0.0539046270423297 - {chain: 6, addr: "0000000000000000000000008f47416cae600bccf9530e9f3aeaa06bdd1caa79", symbol: "THOR", coinGeckoId: "thor", decimals: 18, price: 0.216127}, // Addr: 0x8f47416cae600bccf9530e9f3aeaa06bdd1caa79, Notional: 0.97030222269302 + {chain: 5, addr: "000000000000000000000000fbdd194376de19a88118e84e279b977f165d01b8", symbol: "BIFI", coinGeckoId: "beefy-finance", decimals: 18, price: 337.37}, // Addr: 0xfbdd194376de19a88118e84e279b977f165d01b8, Notional: 26838.376852861198 + {chain: 6, addr: "0000000000000000000000000da67235dd5787d67955420c84ca1cecd4e5bb3b", symbol: "wMEMO", coinGeckoId: "wrapped-memory", decimals: 18, price: 147.88}, // Addr: 0x0da67235dd5787d67955420c84ca1cecd4e5bb3b, Notional: 57.494099574399996 + {chain: 6, addr: "000000000000000000000000130966628846bfd36ff31a822705796e8cb8c18d", symbol: "MIM", coinGeckoId: "magic-internet-money", decimals: 18, price: 0.994109}, // Addr: 0x130966628846bfd36ff31a822705796e8cb8c18d, Notional: 134.95193291423874 + {chain: 6, addr: "000000000000000000000000152b9d0fdc40c096757f570a51e494bd4b943e50", symbol: "BTC.b", coinGeckoId: "bitcoin-avalanche-bridged-btc-b", decimals: 8, price: 93213}, // Addr: 0x152b9d0fdc40c096757f570a51e494bd4b943e50, Notional: 775.09499103 + {chain: 6, addr: "0000000000000000000000001f1e7c893855525b303f99bdf5c3c05be09ca251", symbol: "SYN", coinGeckoId: "synapse-2", decimals: 18, price: 0.621492}, // Addr: 0x1f1e7c893855525b303f99bdf5c3c05be09ca251, Notional: 171.62367337728 + {chain: 6, addr: "00000000000000000000000020cf1b6e9d856321ed4686877cf4538f2c84b4de", symbol: "ANKR", coinGeckoId: "ankr", decimals: 18, price: 0.03341542}, // Addr: 0x20cf1b6e9d856321ed4686877cf4538f2c84b4de, Notional: 3.341542 + {chain: 6, addr: "0000000000000000000000002598c30330d5771ae9f983979209486ae26de875", symbol: "AI", coinGeckoId: "any-inu", decimals: 18, price: 0.00000937}, // Addr: 0x2598c30330d5771ae9f983979209486ae26de875, Notional: 44.85961615455823 + {chain: 6, addr: "000000000000000000000000264c1383ea520f73dd837f915ef3a732e204a493", symbol: "BNB", coinGeckoId: "wbnb", decimals: 18, price: 699.48}, // Addr: 0x264c1383ea520f73dd837f915ef3a732e204a493, Notional: 8817.26208957 + {chain: 6, addr: "0000000000000000000000002b2c81e08f1af8835a78bb2a90ae924ace0ea4be", symbol: "sAVAX", coinGeckoId: "benqi-liquid-staked-avax", decimals: 18, price: 41.91}, // Addr: 0x2b2c81e08f1af8835a78bb2a90ae924ace0ea4be, Notional: 885865.2378562271 + {chain: 6, addr: "0000000000000000000000002f6f07cdcf3588944bf4c42ac74ff24bf56e7590", symbol: "STG", coinGeckoId: "stargate-finance", decimals: 18, price: 0.36685}, // Addr: 0x2f6f07cdcf3588944bf4c42ac74ff24bf56e7590, Notional: 4.8681471721575 + {chain: 6, addr: "00000000000000000000000031c994ac062c1970c086260bc61babb708643fac", symbol: "XETA", coinGeckoId: "xana", decimals: 18, price: 0.00286157}, // Addr: 0x31c994ac062c1970c086260bc61babb708643fac, Notional: 0.0286157 + {chain: 6, addr: "000000000000000000000000321e7092a180bb43555132ec53aaa65a5bf84251", symbol: "gOHM", coinGeckoId: "governance-ohm", decimals: 18, price: 5398.41}, // Addr: 0x321e7092a180bb43555132ec53aaa65a5bf84251, Notional: 24.1878999096 + {chain: 6, addr: "000000000000000000000000323665443cef804a3b5206103304bd4872ea4253", symbol: "USDV", coinGeckoId: "verified-usd-foundation-usdv", decimals: 6, price: 0.994502}, // Addr: 0x323665443cef804a3b5206103304bd4872ea4253, Notional: 7.480866812447999 + {chain: 6, addr: "0000000000000000000000003419875b4d3bca7f3fdda2db7a476a79fd31b4fe", symbol: "DZHV", coinGeckoId: "dizzyhavoc", decimals: 18, price: 0.00053758}, // Addr: 0x3419875b4d3bca7f3fdda2db7a476a79fd31b4fe, Notional: 0.4028068582610643 + {chain: 6, addr: "0000000000000000000000003eefb18003d033661f84e48360ebecd181a84709", symbol: "ISA", coinGeckoId: "islander", decimals: 18, price: 0.00001735}, // Addr: 0x3eefb18003d033661f84e48360ebecd181a84709, Notional: 0.0013271365849965 + {chain: 6, addr: "000000000000000000000000431d5dff03120afa4bdf332c61a6e1766ef37bdb", symbol: "JPYC", coinGeckoId: "jpy-coin", decimals: 18, price: 0.0062165}, // Addr: 0x431d5dff03120afa4bdf332c61a6e1766ef37bdb, Notional: 2.14101856056001 + {chain: 6, addr: "000000000000000000000000444444444444c1a66f394025ac839a535246fcc8", symbol: "GENI", coinGeckoId: "genius", decimals: 9, price: 5.7398e-7}, // Addr: 0x444444444444c1a66f394025ac839a535246fcc8, Notional: 0.32922719876276835 + {chain: 6, addr: "000000000000000000000000491a4eb4f1fc3bff8e1d2fc856a6a46663ad556f", symbol: "BRZ", coinGeckoId: "brz", decimals: 4, price: 0.16085}, // Addr: 0x491a4eb4f1fc3bff8e1d2fc856a6a46663ad556f, Notional: 0.16085 + {chain: 6, addr: "00000000000000000000000049d5c2bdffac6ce2bfdb6640f4f80f226bc10bab", symbol: "WETH.e", coinGeckoId: "weth", decimals: 18, price: 3332.06}, // Addr: 0x49d5c2bdffac6ce2bfdb6640f4f80f226bc10bab, Notional: 16898.3723216194 + {chain: 6, addr: "0000000000000000000000004bfc90322dd638f81f034517359bd447f8e0235a", symbol: "NEWO", coinGeckoId: "new-order", decimals: 18, price: 0.00384881}, // Addr: 0x4bfc90322dd638f81f034517359bd447f8e0235a, Notional: 31423.16247573334 + {chain: 6, addr: "000000000000000000000000502580fc390606b47fc3b741d6d49909383c28a9", symbol: "HATCHY", coinGeckoId: "hatchypocket", decimals: 18, price: 0.00101783}, // Addr: 0x502580fc390606b47fc3b741d6d49909383c28a9, Notional: 0.005058615099999999 + {chain: 6, addr: "0000000000000000000000005085434227ab73151fad2de546210cbc8663df96", symbol: "DBY", coinGeckoId: "metaderby", decimals: 18, price: 0.00163636}, // Addr: 0x5085434227ab73151fad2de546210cbc8663df96, Notional: 14563.75781784 + {chain: 6, addr: "00000000000000000000000050b7545627a5162f82a992c33b87adc75187b218", symbol: "WBTC.e", coinGeckoId: "wrapped-bitcoin", decimals: 8, price: 93245}, // Addr: 0x50b7545627a5162f82a992c33b87adc75187b218, Notional: 2782.9063495 + {chain: 6, addr: "000000000000000000000000564a341df6c126f90cf3ecb92120fd7190acb401", symbol: "TRYB", coinGeckoId: "bilira", decimals: 6, price: 0.0279144}, // Addr: 0x564a341df6c126f90cf3ecb92120fd7190acb401, Notional: 0.0279144 + {chain: 6, addr: "0000000000000000000000005947bb275c521040051d82396192181b413227a3", symbol: "LINK.e", coinGeckoId: "chainlink", decimals: 18, price: 19.87}, // Addr: 0x5947bb275c521040051d82396192181b413227a3, Notional: 1.987 + {chain: 6, addr: "00000000000000000000000062edc0692bd897d2295872a9ffcac5425011c661", symbol: "GMX", coinGeckoId: "gmx", decimals: 18, price: 27.04}, // Addr: 0x62edc0692bd897d2295872a9ffcac5425011c661, Notional: 98.24172259199999 + {chain: 6, addr: "00000000000000000000000063682bdc5f875e9bf69e201550658492c9763f89", symbol: "BSGG", coinGeckoId: "betswap-gg", decimals: 18, price: 0.0007367}, // Addr: 0x63682bdc5f875e9bf69e201550658492c9763f89, Notional: 0.554274428656686 + {chain: 6, addr: "00000000000000000000000063a72806098bd3d9520cc43356dd78afe5d386d9", symbol: "AAVE.e", coinGeckoId: "aave", decimals: 18, price: 309.59}, // Addr: 0x63a72806098bd3d9520cc43356dd78afe5d386d9, Notional: 2.9129756525999997 + {chain: 6, addr: "00000000000000000000000068ee0d0aad9e1984af85ca224117e4d20eaf68be", symbol: "ROY", coinGeckoId: "crypto-royale", decimals: 18, price: 0.00257094}, // Addr: 0x68ee0d0aad9e1984af85ca224117e4d20eaf68be, Notional: 0.17739486 + {chain: 6, addr: "0000000000000000000000006e84a6216ea6dacc71ee8e6b0a5b7322eebc0fdd", symbol: "JOE", coinGeckoId: "joe", decimals: 18, price: 0.363725}, // Addr: 0x6e84a6216ea6dacc71ee8e6b0a5b7322eebc0fdd, Notional: 0.04000975363725 + {chain: 6, addr: "000000000000000000000000714f020c54cc9d104b6f4f6998c63ce2a31d1888", symbol: "FITFI", coinGeckoId: "step-app-fitfi", decimals: 18, price: 0.00288801}, // Addr: 0x714f020c54cc9d104b6f4f6998c63ce2a31d1888, Notional: 0.0002888010288801 + {chain: 6, addr: "000000000000000000000000820802fa8a99901f52e39acd21177b0be6ee2974", symbol: "EUROe", coinGeckoId: "euroe-stablecoin", decimals: 6, price: 1.03}, // Addr: 0x820802fa8a99901f52e39acd21177b0be6ee2974, Notional: 1.35873377 + {chain: 6, addr: "0000000000000000000000008729438eb15e2c8b576fcc6aecda6a148776c0f5", symbol: "QI", coinGeckoId: "benqi", decimals: 18, price: 0.01586698}, // Addr: 0x8729438eb15e2c8b576fcc6aecda6a148776c0f5, Notional: 0.01586698 + {chain: 6, addr: "0000000000000000000000008929e9dbd2785e3ba16175e596cdd61520fee0d1", symbol: "ALTD", coinGeckoId: "altitude", decimals: 18, price: 0.00044128}, // Addr: 0x8929e9dbd2785e3ba16175e596cdd61520fee0d1, Notional: 0.0319164805931104 + {chain: 6, addr: "0000000000000000000000008f47416cae600bccf9530e9f3aeaa06bdd1caa79", symbol: "THOR", coinGeckoId: "thor", decimals: 18, price: 0.123661}, // Addr: 0x8f47416cae600bccf9530e9f3aeaa06bdd1caa79, Notional: 0.55517609165186 {chain: 6, addr: "000000000000000000000000921f99719eb6c01b4b8f0ba7973a7c24891e740a", symbol: "MAGE", coinGeckoId: "metabrands", decimals: 18, price: 0.01934287}, // Addr: 0x921f99719eb6c01b4b8f0ba7973a7c24891e740a, Notional: 536.0410470152927 - {chain: 6, addr: "000000000000000000000000961c8c0b1aad0c0b10a51fef6a867e3091bcef17", symbol: "DYP", coinGeckoId: "defi-yield-protocol", decimals: 18, price: 0.314992}, // Addr: 0x961c8c0b1aad0c0b10a51fef6a867e3091bcef17, Notional: 1910.0030853742524 - {chain: 6, addr: "0000000000000000000000009702230a8ea53601f5cd2dc00fdbc13d4df4a8c7", symbol: "USDt", coinGeckoId: "tether", decimals: 6, price: 1}, // Addr: 0x9702230a8ea53601f5cd2dc00fdbc13d4df4a8c7, Notional: 25781.030248 - {chain: 6, addr: "00000000000000000000000098443b96ea4b0858fdf3219cd13e98c7a4690588", symbol: "BAT.e", coinGeckoId: "basic-attention-token", decimals: 18, price: 0.297146}, // Addr: 0x98443b96ea4b0858fdf3219cd13e98c7a4690588, Notional: 14.71263687381114 - {chain: 6, addr: "000000000000000000000000a4fb4f0ff2431262d236778495145ecbc975c38b", symbol: "INFRA.e", coinGeckoId: "bware-infra", decimals: 18, price: 0.286974}, // Addr: 0xa4fb4f0ff2431262d236778495145ecbc975c38b, Notional: 0.034436879999999996 - {chain: 6, addr: "000000000000000000000000a7d7079b0fead91f3e65f86e8915cb59c1a4c664", symbol: "USDC.e", coinGeckoId: "usd-coin-avalanche-bridged-usdc-e", decimals: 6, price: 1.002}, // Addr: 0xa7d7079b0fead91f3e65f86e8915cb59c1a4c664, Notional: 30257.634371784003 - {chain: 6, addr: "000000000000000000000000b279f8dd152b99ec1d84a489d32c35bc0c7f5674", symbol: "STEAK", coinGeckoId: "steakhut-finance", decimals: 18, price: 0.966098}, // Addr: 0xb279f8dd152b99ec1d84a489d32c35bc0c7f5674, Notional: 5.3360564740497 - {chain: 6, addr: "000000000000000000000000b31f66aa3c1e785363f0875a1b74e27b85fd66c7", symbol: "WAVAX", coinGeckoId: "wrapped-avax", decimals: 18, price: 47.01}, // Addr: 0xb31f66aa3c1e785363f0875a1b74e27b85fd66c7, Notional: 6067966.080012275 - {chain: 6, addr: "000000000000000000000000b97ef9ef8734c71904d8002f8b6bc66dd9c48a6e", symbol: "USDC", coinGeckoId: "usd-coin", decimals: 6, price: 1}, // Addr: 0xb97ef9ef8734c71904d8002f8b6bc66dd9c48a6e, Notional: 176795.723832 - {chain: 6, addr: "000000000000000000000000bbaaa0420d474b34be197f95a323c2ff3829e811", symbol: "LODE", coinGeckoId: "lode-token", decimals: 18, price: 0.087976}, // Addr: 0xbbaaa0420d474b34be197f95a323c2ff3829e811, Notional: 0.00307916 - {chain: 6, addr: "000000000000000000000000bd100d061e120b2c67a24453cf6368e63f1be056", symbol: "iDYP", coinGeckoId: "idefiyieldprotocol", decimals: 18, price: 0.00059256}, // Addr: 0xbd100d061e120b2c67a24453cf6368e63f1be056, Notional: 0.000059256 - {chain: 6, addr: "000000000000000000000000c0c5aa69dbe4d6dddfbc89c0957686ec60f24389", symbol: "aXEN", coinGeckoId: "xen-crypto", decimals: 18, price: 1.12695e-7}, // Addr: 0xc0c5aa69dbe4d6dddfbc89c0957686ec60f24389, Notional: 144.96244373648838 - {chain: 6, addr: "000000000000000000000000c17c30e98541188614df99239cabd40280810ca3", symbol: "RISE", coinGeckoId: "everrise", decimals: 18, price: 0.00008144}, // Addr: 0xc17c30e98541188614df99239cabd40280810ca3, Notional: 1.7343558091006435 - {chain: 6, addr: "000000000000000000000000c7198437980c041c805a1edcba50c1ce5db95118", symbol: "USDT.e", coinGeckoId: "tether-avalanche-bridged-usdt-e", decimals: 6, price: 0.999769}, // Addr: 0xc7198437980c041c805a1edcba50c1ce5db95118, Notional: 6137.245524718564 - {chain: 6, addr: "000000000000000000000000ce1bffbd5374dac86a2893119683f4911a2f7814", symbol: "SPELL", coinGeckoId: "spell-token", decimals: 18, price: 0.00093684}, // Addr: 0xce1bffbd5374dac86a2893119683f4911a2f7814, Notional: 51.46660981864545 - {chain: 6, addr: "000000000000000000000000d24c2ad096400b6fbcd2ad8b24e7acbc21a1da64", symbol: "FRAX", coinGeckoId: "frax", decimals: 18, price: 0.996303}, // Addr: 0xd24c2ad096400b6fbcd2ad8b24e7acbc21a1da64, Notional: 7.46778975420786 - {chain: 6, addr: "000000000000000000000000d402298a793948698b9a63311404fbbee944eafd", symbol: "SHRAP", coinGeckoId: "shrapnel-2", decimals: 18, price: 0.04000954}, // Addr: 0xd402298a793948698b9a63311404fbbee944eafd, Notional: 1.211084774846 - {chain: 6, addr: "000000000000000000000000d586e7f844cea2f87f50152665bcbc2c279d8d70", symbol: "DAI.e", coinGeckoId: "dai", decimals: 18, price: 1}, // Addr: 0xd586e7f844cea2f87f50152665bcbc2c279d8d70, Notional: 873.17756534 - {chain: 6, addr: "000000000000000000000000e8385cecb013561b69beb63ff59f4d10734881f3", symbol: "GEC", coinGeckoId: "gecko-inu", decimals: 18, price: 2.5814e-8}, // Addr: 0xe8385cecb013561b69beb63ff59f4d10734881f3, Notional: 2.6580770162861764 - {chain: 6, addr: "000000000000000000000000ec3492a2508ddf4fdc0cd76f31f340b30d1793e6", symbol: "CLY", coinGeckoId: "colony", decimals: 18, price: 0.177785}, // Addr: 0xec3492a2508ddf4fdc0cd76f31f340b30d1793e6, Notional: 0.177785 - {chain: 6, addr: "000000000000000000000000ed2b42d3c9c6e97e11755bb37df29b6375ede3eb", symbol: "HON", coinGeckoId: "heroes-of-nft", decimals: 18, price: 0.01863263}, // Addr: 0xed2b42d3c9c6e97e11755bb37df29b6375ede3eb, Notional: 0.0563475059824991 - {chain: 6, addr: "000000000000000000000000fab550568c688d5d8a52c7d794cb93edc26ec0ec", symbol: "axlUSDC", coinGeckoId: "axlusdc", decimals: 6, price: 0.99899}, // Addr: 0xfab550568c688d5d8a52c7d794cb93edc26ec0ec, Notional: 0.599394 - {chain: 6, addr: "000000000000000000000000fb98b335551a418cd0737375a2ea0ded62ea213b", symbol: "PENDLE", coinGeckoId: "pendle", decimals: 18, price: 5.52}, // Addr: 0xfb98b335551a418cd0737375a2ea0ded62ea213b, Notional: 861.1167823919999 - {chain: 7, addr: "00000000000000000000000021c718c22d52d0f3a789b752d4c2fd5908a8a733", symbol: "wROSE", coinGeckoId: "oasis-network", decimals: 18, price: 0.102662}, // Addr: 0x21c718c22d52d0f3a789b752d4c2fd5908a8a733, Notional: 174704.1389245905 - {chain: 8, addr: "0000000000000000000000000000000000000000000000000000000000000000", symbol: "ALGO", coinGeckoId: "algorand", decimals: 6, price: 0.475239}, // Addr: 0, Notional: 13362.547498826492 - {chain: 8, addr: "000000000000000000000000000000000000000000000000000000000029fcf5", symbol: "RIO", coinGeckoId: "realio-network", decimals: 7, price: 1.2}, // Addr: 2751733, Notional: 14094.94436196 - {chain: 8, addr: "00000000000000000000000000000000000000000000000000000000019e8502", symbol: "Planets", coinGeckoId: "planetwatch", decimals: 6, price: 0.00001698}, // Addr: 27165954, Notional: 0.01698 - {chain: 8, addr: "0000000000000000000000000000000000000000000000000000000001e1ab70", symbol: "USDC", coinGeckoId: "usd-coin", decimals: 6, price: 1}, // Addr: 31566704, Notional: 14906.679031 - {chain: 8, addr: "0000000000000000000000000000000000000000000000000000000008338636", symbol: "HDL", coinGeckoId: "headline", decimals: 6, price: 0.01389153}, // Addr: 137594422, Notional: 515.4157187354269 - {chain: 8, addr: "000000000000000000000000000000000000000000000000000000000d83314a", symbol: "YLDY", coinGeckoId: "yieldly", decimals: 6, price: 0.00004567}, // Addr: 226701642, Notional: 30.412173638000002 - {chain: 8, addr: "00000000000000000000000000000000000000000000000000000000112883e4", symbol: "OPUL", coinGeckoId: "opulous", decimals: 8, price: 0.103117}, // Addr: 287867876, Notional: 52.90005217 - {chain: 8, addr: "000000000000000000000000000000000000000000000000000000001704d555", symbol: "goBTC", coinGeckoId: "gobtc", decimals: 8, price: 94511}, // Addr: 386192725, Notional: 195.45536377 - {chain: 8, addr: "000000000000000000000000000000000000000000000000000000001704e1e4", symbol: "goETH", coinGeckoId: "goeth", decimals: 8, price: 3539.5}, // Addr: 386195940, Notional: 31.82683005 - {chain: 8, addr: "000000000000000000000000000000000000000000000000000000001729723f", symbol: "chip", coinGeckoId: "algo-casino-chips", decimals: 1, price: 0.00494553}, // Addr: 388592191, Notional: 2.1196541580000003 - {chain: 8, addr: "000000000000000000000000000000000000000000000000000000001a777316", symbol: "ZONE", coinGeckoId: "zone", decimals: 6, price: 0.00066002}, // Addr: 444035862, Notional: 0.00594018 - {chain: 8, addr: "000000000000000000000000000000000000000000000000000000001dc164ef", symbol: "MCOIN", coinGeckoId: "maricoin", decimals: 3, price: 0.00146744}, // Addr: 499213551, Notional: 36039.24082750888 - {chain: 8, addr: "000000000000000000000000000000000000000000000000000000002f461f17", symbol: "gALGO", coinGeckoId: "governance-algo", decimals: 6, price: 0.46694}, // Addr: 793124631, Notional: 0.09338800000000001 - {chain: 8, addr: "000000000000000000000000000000000000000000000000000000002f787b65", symbol: "COOP", coinGeckoId: "coop-coin", decimals: 6, price: 0.061848}, // Addr: 796425061, Notional: 1954.282505081544 - {chain: 8, addr: "000000000000000000000000000000000000000000000000000000003717361a", symbol: "FRY", coinGeckoId: "fryscrypto", decimals: 6, price: 0.00021476}, // Addr: 924268058, Notional: 8939.82285104294 - {chain: 9, addr: "0000000000000000000000004988a896b1227218e4a686fde5eabdcabd91571f", symbol: "USDT", coinGeckoId: "tether", decimals: 6, price: 1}, // Addr: 0x4988a896b1227218e4a686fde5eabdcabd91571f, Notional: 507.188226 - {chain: 9, addr: "0000000000000000000000005ce9f0b6afb36135b5ddbf11705ceb65e634a9dc", symbol: "atUST", coinGeckoId: "wrapped-ust", decimals: 18, price: 0.02485643}, // Addr: 0x5ce9f0b6afb36135b5ddbf11705ceb65e634a9dc, Notional: 0.0246846825084006 - {chain: 9, addr: "0000000000000000000000007ca1c28663b76cfde424a9494555b94846205585", symbol: "XNL", coinGeckoId: "chronicle", decimals: 18, price: 0.01034379}, // Addr: 0x7ca1c28663b76cfde424a9494555b94846205585, Notional: 1.62397503 - {chain: 9, addr: "0000000000000000000000008bec47865ade3b172a928df8f990bc7f2a3b9f79", symbol: "AURORA", coinGeckoId: "aurora-near", decimals: 18, price: 0.206825}, // Addr: 0x8bec47865ade3b172a928df8f990bc7f2a3b9f79, Notional: 0.00001034125 - {chain: 9, addr: "000000000000000000000000b12bfca5a55806aaf64e99521918a4bf0fc40802", symbol: "USDC", coinGeckoId: "usd-coin", decimals: 6, price: 1}, // Addr: 0xb12bfca5a55806aaf64e99521918a4bf0fc40802, Notional: 329.534213 - {chain: 9, addr: "000000000000000000000000c4bdd27c33ec7daa6fcfd8532ddb524bf4038096", symbol: "atLUNA", coinGeckoId: "wrapped-terra", decimals: 18, price: 0.00004969}, // Addr: 0xc4bdd27c33ec7daa6fcfd8532ddb524bf4038096, Notional: 0.0417181273653921 - {chain: 9, addr: "000000000000000000000000c9bdeed33cd01541e1eed10f90519d2c06fe3feb", symbol: "WETH", coinGeckoId: "weth", decimals: 18, price: 3594.89}, // Addr: 0xc9bdeed33cd01541e1eed10f90519d2c06fe3feb, Notional: 9509.4546703 - {chain: 9, addr: "000000000000000000000000dcd6d4e2b3e1d1e1e6fa8c21c8a323dcbecff970", symbol: "ROSE", coinGeckoId: "rose", decimals: 18, price: 0.0001472}, // Addr: 0xdcd6d4e2b3e1d1e1e6fa8c21c8a323dcbecff970, Notional: 0.0148672 - {chain: 10, addr: "00000000000000000000000004068da6c83afcfa0e13ba15a6696662335d5b75", symbol: "USDC", coinGeckoId: "usd-coin", decimals: 6, price: 1}, // Addr: 0x04068da6c83afcfa0e13ba15a6696662335d5b75, Notional: 206568.743175 - {chain: 10, addr: "000000000000000000000000049d68029688eabf473097a2fc38ef61633a3c7a", symbol: "fUSDT", coinGeckoId: "tether", decimals: 6, price: 1}, // Addr: 0x049d68029688eabf473097a2fc38ef61633a3c7a, Notional: 2379.347362 - {chain: 10, addr: "0000000000000000000000000615dbba33fe61a31c7ed131bda6655ed76748b1", symbol: "ANKR", coinGeckoId: "ankr", decimals: 18, price: 0.04128546}, // Addr: 0x0615dbba33fe61a31c7ed131bda6655ed76748b1, Notional: 24.559045002240467 - {chain: 10, addr: "000000000000000000000000174c7106aeecdc11389f7dd21342f05f46ccb40f", symbol: "DEVIL", coinGeckoId: "devil-finance", decimals: 18, price: 0.00008282}, // Addr: 0x174c7106aeecdc11389f7dd21342f05f46ccb40f, Notional: 0.18220400000165637 - {chain: 10, addr: "0000000000000000000000001b6382dbdea11d97f24495c9a90b7c88469134a4", symbol: "axlUSDC", coinGeckoId: "axlusdc", decimals: 6, price: 0.99899}, // Addr: 0x1b6382dbdea11d97f24495c9a90b7c88469134a4, Notional: 10.07409188023 - {chain: 10, addr: "0000000000000000000000001e4f97b9f9f913c46f1632781732927b9019c68b", symbol: "CRV", coinGeckoId: "curve-dao-token", decimals: 18, price: 0.716043}, // Addr: 0x1e4f97b9f9f913c46f1632781732927b9019c68b, Notional: 1891.8989410497456 - {chain: 10, addr: "0000000000000000000000002130d2a1e51112d349ccf78d2a1ee65843ba36e0", symbol: "UNIDX", coinGeckoId: "unidex", decimals: 18, price: 0.372615}, // Addr: 0x2130d2a1e51112d349ccf78d2a1ee65843ba36e0, Notional: 0.4312777617618 - {chain: 10, addr: "00000000000000000000000021ada0d2ac28c3a5fa3cd2ee30882da8812279b6", symbol: "OATH", coinGeckoId: "oath", decimals: 18, price: 0.00408462}, // Addr: 0x21ada0d2ac28c3a5fa3cd2ee30882da8812279b6, Notional: 0.408462 - {chain: 10, addr: "00000000000000000000000021be370d5312f44cb42ce377bc9b8a0cef1a4c83", symbol: "WFTM", coinGeckoId: "wrapped-fantom", decimals: 18, price: 1.003}, // Addr: 0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83, Notional: 115294.85497610364 - {chain: 10, addr: "000000000000000000000000248cb87dda803028dfead98101c9465a2fbda0d4", symbol: "CHARM", coinGeckoId: "charm", decimals: 18, price: 9.51815e-7}, // Addr: 0x248cb87dda803028dfead98101c9465a2fbda0d4, Notional: 0.0038072600000000002 - {chain: 10, addr: "0000000000000000000000002598c30330d5771ae9f983979209486ae26de875", symbol: "AI", coinGeckoId: "any-inu", decimals: 18, price: 0.00000789}, // Addr: 0x2598c30330d5771ae9f983979209486ae26de875, Notional: 0.0631989 + {chain: 6, addr: "000000000000000000000000961c8c0b1aad0c0b10a51fef6a867e3091bcef17", symbol: "DYP", coinGeckoId: "defi-yield-protocol", decimals: 18, price: 0.205661}, // Addr: 0x961c8c0b1aad0c0b10a51fef6a867e3091bcef17, Notional: 1247.0575269884764 + {chain: 6, addr: "0000000000000000000000009702230a8ea53601f5cd2dc00fdbc13d4df4a8c7", symbol: "USDt", coinGeckoId: "tether", decimals: 6, price: 0.99789}, // Addr: 0x9702230a8ea53601f5cd2dc00fdbc13d4df4a8c7, Notional: 25825.609871855704 + {chain: 6, addr: "00000000000000000000000098443b96ea4b0858fdf3219cd13e98c7a4690588", symbol: "BAT.e", coinGeckoId: "basic-attention-token", decimals: 18, price: 0.23073}, // Addr: 0x98443b96ea4b0858fdf3219cd13e98c7a4690588, Notional: 11.424170966105699 + {chain: 6, addr: "000000000000000000000000a4fb4f0ff2431262d236778495145ecbc975c38b", symbol: "INFRA.e", coinGeckoId: "bware-infra", decimals: 18, price: 0.192309}, // Addr: 0xa4fb4f0ff2431262d236778495145ecbc975c38b, Notional: 0.02307708 + {chain: 6, addr: "000000000000000000000000a7d7079b0fead91f3e65f86e8915cb59c1a4c664", symbol: "USDC.e", coinGeckoId: "usd-coin-avalanche-bridged-usdc-e", decimals: 6, price: 0.997079}, // Addr: 0xa7d7079b0fead91f3e65f86e8915cb59c1a4c664, Notional: 30109.03375427547 + {chain: 6, addr: "000000000000000000000000b279f8dd152b99ec1d84a489d32c35bc0c7f5674", symbol: "STEAK", coinGeckoId: "steakhut-finance", decimals: 18, price: 0.781796}, // Addr: 0xb279f8dd152b99ec1d84a489d32c35bc0c7f5674, Notional: 4.3180998275394 + {chain: 6, addr: "000000000000000000000000b31f66aa3c1e785363f0875a1b74e27b85fd66c7", symbol: "WAVAX", coinGeckoId: "wrapped-avax", decimals: 18, price: 35.57}, // Addr: 0xb31f66aa3c1e785363f0875a1b74e27b85fd66c7, Notional: 5124247.859341799 + {chain: 6, addr: "000000000000000000000000b97ef9ef8734c71904d8002f8b6bc66dd9c48a6e", symbol: "USDC", coinGeckoId: "usd-coin", decimals: 6, price: 0.999339}, // Addr: 0xb97ef9ef8734c71904d8002f8b6bc66dd9c48a6e, Notional: 176059.94550984996 + {chain: 6, addr: "000000000000000000000000bbaaa0420d474b34be197f95a323c2ff3829e811", symbol: "LODE", coinGeckoId: "lode-token", decimals: 18, price: 0.062142}, // Addr: 0xbbaaa0420d474b34be197f95a323c2ff3829e811, Notional: 0.0021749700000000005 + {chain: 6, addr: "000000000000000000000000bd100d061e120b2c67a24453cf6368e63f1be056", symbol: "iDYP", coinGeckoId: "idefiyieldprotocol", decimals: 18, price: 0.00071252}, // Addr: 0xbd100d061e120b2c67a24453cf6368e63f1be056, Notional: 0.000071252 + {chain: 6, addr: "000000000000000000000000c0c5aa69dbe4d6dddfbc89c0957686ec60f24389", symbol: "aXEN", coinGeckoId: "xen-crypto", decimals: 18, price: 1.68216e-7}, // Addr: 0xc0c5aa69dbe4d6dddfbc89c0957686ec60f24389, Notional: 216.38051764121857 + {chain: 6, addr: "000000000000000000000000c17c30e98541188614df99239cabd40280810ca3", symbol: "RISE", coinGeckoId: "everrise", decimals: 18, price: 0.00006624}, // Addr: 0xc17c30e98541188614df99239cabd40280810ca3, Notional: 1.4106548231191873 + {chain: 6, addr: "000000000000000000000000c7198437980c041c805a1edcba50c1ce5db95118", symbol: "USDT.e", coinGeckoId: "tether-avalanche-bridged-usdt-e", decimals: 6, price: 0.995144}, // Addr: 0xc7198437980c041c805a1edcba50c1ce5db95118, Notional: 6108.854205772064 + {chain: 6, addr: "000000000000000000000000ce1bffbd5374dac86a2893119683f4911a2f7814", symbol: "SPELL", coinGeckoId: "spell-token", decimals: 18, price: 0.00073482}, // Addr: 0xce1bffbd5374dac86a2893119683f4911a2f7814, Notional: 40.36835983405603 + {chain: 6, addr: "000000000000000000000000d24c2ad096400b6fbcd2ad8b24e7acbc21a1da64", symbol: "FRAX", coinGeckoId: "frax", decimals: 18, price: 0.993202}, // Addr: 0xd24c2ad096400b6fbcd2ad8b24e7acbc21a1da64, Notional: 7.4445462067852395 + {chain: 6, addr: "000000000000000000000000d402298a793948698b9a63311404fbbee944eafd", symbol: "SHRAP", coinGeckoId: "shrapnel-2", decimals: 18, price: 0.02445197}, // Addr: 0xd402298a793948698b9a63311404fbbee944eafd, Notional: 0.740158686703 + {chain: 6, addr: "000000000000000000000000d586e7f844cea2f87f50152665bcbc2c279d8d70", symbol: "DAI.e", coinGeckoId: "dai", decimals: 18, price: 0.99899}, // Addr: 0xd586e7f844cea2f87f50152665bcbc2c279d8d70, Notional: 872.2956559990066 + {chain: 6, addr: "000000000000000000000000e8385cecb013561b69beb63ff59f4d10734881f3", symbol: "GEC", coinGeckoId: "gecko-inu", decimals: 18, price: 1.7427e-8}, // Addr: 0xe8385cecb013561b69beb63ff59f4d10734881f3, Notional: 1.7944645604253195 + {chain: 6, addr: "000000000000000000000000ec3492a2508ddf4fdc0cd76f31f340b30d1793e6", symbol: "CLY", coinGeckoId: "colony", decimals: 18, price: 0.128258}, // Addr: 0xec3492a2508ddf4fdc0cd76f31f340b30d1793e6, Notional: 0.128258 + {chain: 6, addr: "000000000000000000000000ed2b42d3c9c6e97e11755bb37df29b6375ede3eb", symbol: "HON", coinGeckoId: "heroes-of-nft", decimals: 18, price: 0.01439492}, // Addr: 0xed2b42d3c9c6e97e11755bb37df29b6375ede3eb, Notional: 0.0435321176247044 + {chain: 6, addr: "000000000000000000000000fab550568c688d5d8a52c7d794cb93edc26ec0ec", symbol: "axlUSDC", coinGeckoId: "axlusdc", decimals: 6, price: 0.998424}, // Addr: 0xfab550568c688d5d8a52c7d794cb93edc26ec0ec, Notional: 0.5990544 + {chain: 6, addr: "000000000000000000000000fb98b335551a418cd0737375a2ea0ded62ea213b", symbol: "PENDLE", coinGeckoId: "pendle", decimals: 18, price: 4.86}, // Addr: 0xfb98b335551a418cd0737375a2ea0ded62ea213b, Notional: 758.157167106 + {chain: 7, addr: "00000000000000000000000021c718c22d52d0f3a789b752d4c2fd5908a8a733", symbol: "wROSE", coinGeckoId: "oasis-network", decimals: 18, price: 0.079988}, // Addr: 0x21c718c22d52d0f3a789b752d4c2fd5908a8a733, Notional: 144794.24102064854 + {chain: 8, addr: "0000000000000000000000000000000000000000000000000000000000000000", symbol: "ALGO", coinGeckoId: "algorand", decimals: 6, price: 0.332989}, // Addr: 0, Notional: 6676.939385025742 + {chain: 8, addr: "000000000000000000000000000000000000000000000000000000000029fcf5", symbol: "RIO", coinGeckoId: "realio-network", decimals: 7, price: 0.852965}, // Addr: 2751733, Notional: 10018.74518141601 + {chain: 8, addr: "00000000000000000000000000000000000000000000000000000000019e8502", symbol: "Planets", coinGeckoId: "planetwatch", decimals: 6, price: 0.0000263}, // Addr: 27165954, Notional: 0.0263 + {chain: 8, addr: "0000000000000000000000000000000000000000000000000000000001e1ab70", symbol: "USDC", coinGeckoId: "usd-coin", decimals: 6, price: 0.999339}, // Addr: 31566704, Notional: 14976.772836160508 + {chain: 8, addr: "0000000000000000000000000000000000000000000000000000000008338636", symbol: "HDL", coinGeckoId: "headline", decimals: 6, price: 0.00888395}, // Addr: 137594422, Notional: 329.6200976033307 + {chain: 8, addr: "000000000000000000000000000000000000000000000000000000000d83314a", symbol: "YLDY", coinGeckoId: "yieldly", decimals: 6, price: 0.00002083}, // Addr: 226701642, Notional: 13.870934462 + {chain: 8, addr: "00000000000000000000000000000000000000000000000000000000112883e4", symbol: "OPUL", coinGeckoId: "opulous", decimals: 8, price: 0.07032}, // Addr: 287867876, Notional: 36.7780632 + {chain: 8, addr: "000000000000000000000000000000000000000000000000000000001704d555", symbol: "goBTC", coinGeckoId: "gobtc", decimals: 8, price: 93277}, // Addr: 386192725, Notional: 192.90336539 + {chain: 8, addr: "000000000000000000000000000000000000000000000000000000001704e1e4", symbol: "goETH", coinGeckoId: "goeth", decimals: 8, price: 3326.02}, // Addr: 386195940, Notional: 29.907239238000003 + {chain: 8, addr: "000000000000000000000000000000000000000000000000000000001729723f", symbol: "chip", coinGeckoId: "algo-casino-chips", decimals: 1, price: 0.00315102}, // Addr: 388592191, Notional: 1.350527172 + {chain: 8, addr: "000000000000000000000000000000000000000000000000000000001a777316", symbol: "ZONE", coinGeckoId: "zone", decimals: 6, price: 0.0005911}, // Addr: 444035862, Notional: 0.0053199 + {chain: 8, addr: "000000000000000000000000000000000000000000000000000000001dc164ef", symbol: "MCOIN", coinGeckoId: "maricoin", decimals: 3, price: 0.0011706}, // Addr: 499213551, Notional: 28749.070021726202 + {chain: 8, addr: "000000000000000000000000000000000000000000000000000000002f461f17", symbol: "gALGO", coinGeckoId: "governance-algo", decimals: 6, price: 0.334698}, // Addr: 793124631, Notional: 0.0669396 + {chain: 8, addr: "000000000000000000000000000000000000000000000000000000002f787b65", symbol: "COOP", coinGeckoId: "coop-coin", decimals: 6, price: 0.03102441}, // Addr: 796425061, Notional: 980.3140229833932 + {chain: 8, addr: "000000000000000000000000000000000000000000000000000000003717361a", symbol: "FRY", coinGeckoId: "fryscrypto", decimals: 6, price: 0.227442}, // Addr: 924268058, Notional: 9470011.377007395 + {chain: 9, addr: "0000000000000000000000004988a896b1227218e4a686fde5eabdcabd91571f", symbol: "USDT", coinGeckoId: "tether", decimals: 6, price: 0.99789}, // Addr: 0x4988a896b1227218e4a686fde5eabdcabd91571f, Notional: 506.11805884314003 + {chain: 9, addr: "0000000000000000000000005ce9f0b6afb36135b5ddbf11705ceb65e634a9dc", symbol: "atUST", coinGeckoId: "wrapped-ust", decimals: 18, price: 0.01958015}, // Addr: 0x5ce9f0b6afb36135b5ddbf11705ceb65e634a9dc, Notional: 0.019444859387163 + {chain: 9, addr: "0000000000000000000000007ca1c28663b76cfde424a9494555b94846205585", symbol: "XNL", coinGeckoId: "chronicle", decimals: 18, price: 0.00903854}, // Addr: 0x7ca1c28663b76cfde424a9494555b94846205585, Notional: 1.4190507799999998 + {chain: 9, addr: "0000000000000000000000008bec47865ade3b172a928df8f990bc7f2a3b9f79", symbol: "AURORA", coinGeckoId: "aurora-near", decimals: 18, price: 0.204571}, // Addr: 0x8bec47865ade3b172a928df8f990bc7f2a3b9f79, Notional: 0.00001022855 + {chain: 9, addr: "000000000000000000000000b12bfca5a55806aaf64e99521918a4bf0fc40802", symbol: "USDC", coinGeckoId: "usd-coin", decimals: 6, price: 0.999339}, // Addr: 0xb12bfca5a55806aaf64e99521918a4bf0fc40802, Notional: 329.316390885207 + {chain: 9, addr: "000000000000000000000000c4bdd27c33ec7daa6fcfd8532ddb524bf4038096", symbol: "atLUNA", coinGeckoId: "wrapped-terra", decimals: 18, price: 0.00004537}, // Addr: 0xc4bdd27c33ec7daa6fcfd8532ddb524bf4038096, Notional: 0.0380911941752433 + {chain: 9, addr: "000000000000000000000000c9bdeed33cd01541e1eed10f90519d2c06fe3feb", symbol: "WETH", coinGeckoId: "weth", decimals: 18, price: 3332.06}, // Addr: 0xc9bdeed33cd01541e1eed10f90519d2c06fe3feb, Notional: 8814.1983562 + {chain: 9, addr: "000000000000000000000000dcd6d4e2b3e1d1e1e6fa8c21c8a323dcbecff970", symbol: "ROSE", coinGeckoId: "rose", decimals: 18, price: 0.00012795}, // Addr: 0xdcd6d4e2b3e1d1e1e6fa8c21c8a323dcbecff970, Notional: 0.012922949999999999 + {chain: 10, addr: "00000000000000000000000004068da6c83afcfa0e13ba15a6696662335d5b75", symbol: "USDC", coinGeckoId: "usd-coin", decimals: 6, price: 0.999339}, // Addr: 0x04068da6c83afcfa0e13ba15a6696662335d5b75, Notional: 206651.19259672653 + {chain: 10, addr: "000000000000000000000000049d68029688eabf473097a2fc38ef61633a3c7a", symbol: "fUSDT", coinGeckoId: "tether", decimals: 6, price: 0.99789}, // Addr: 0x049d68029688eabf473097a2fc38ef61633a3c7a, Notional: 2456.70069193599 + {chain: 10, addr: "0000000000000000000000000615dbba33fe61a31c7ed131bda6655ed76748b1", symbol: "ANKR", coinGeckoId: "ankr", decimals: 18, price: 0.03341542}, // Addr: 0x0615dbba33fe61a31c7ed131bda6655ed76748b1, Notional: 19.87747753201166 + {chain: 10, addr: "000000000000000000000000174c7106aeecdc11389f7dd21342f05f46ccb40f", symbol: "DEVIL", coinGeckoId: "devil-finance", decimals: 18, price: 0.00006689}, // Addr: 0x174c7106aeecdc11389f7dd21342f05f46ccb40f, Notional: 0.1471580000013378 + {chain: 10, addr: "0000000000000000000000001b6382dbdea11d97f24495c9a90b7c88469134a4", symbol: "axlUSDC", coinGeckoId: "axlusdc", decimals: 6, price: 0.998424}, // Addr: 0x1b6382dbdea11d97f24495c9a90b7c88469134a4, Notional: 10.068384179448 + {chain: 10, addr: "0000000000000000000000001e4f97b9f9f913c46f1632781732927b9019c68b", symbol: "CRV", coinGeckoId: "curve-dao-token", decimals: 18, price: 0.891931}, // Addr: 0x1e4f97b9f9f913c46f1632781732927b9019c68b, Notional: 2356.622876544343 + {chain: 10, addr: "0000000000000000000000002130d2a1e51112d349ccf78d2a1ee65843ba36e0", symbol: "UNIDX", coinGeckoId: "unidex", decimals: 18, price: 0.7031}, // Addr: 0x2130d2a1e51112d349ccf78d2a1ee65843ba36e0, Notional: 0.813792773492 + {chain: 10, addr: "00000000000000000000000021ada0d2ac28c3a5fa3cd2ee30882da8812279b6", symbol: "OATH", coinGeckoId: "oath", decimals: 18, price: 0.00252339}, // Addr: 0x21ada0d2ac28c3a5fa3cd2ee30882da8812279b6, Notional: 0.252339 + {chain: 10, addr: "00000000000000000000000021be370d5312f44cb42ce377bc9b8a0cef1a4c83", symbol: "WFTM", coinGeckoId: "wrapped-fantom", decimals: 18, price: 0.675103}, // Addr: 0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83, Notional: 114486.08141513854 + {chain: 10, addr: "000000000000000000000000248cb87dda803028dfead98101c9465a2fbda0d4", symbol: "CHARM", coinGeckoId: "charm", decimals: 18, price: 7.1773e-7}, // Addr: 0x248cb87dda803028dfead98101c9465a2fbda0d4, Notional: 0.00287092 + {chain: 10, addr: "0000000000000000000000002598c30330d5771ae9f983979209486ae26de875", symbol: "AI", coinGeckoId: "any-inu", decimals: 18, price: 0.00000937}, // Addr: 0x2598c30330d5771ae9f983979209486ae26de875, Notional: 0.0750537 {chain: 10, addr: "000000000000000000000000260b3e40c714ce8196465ec824cd8bb915081812", symbol: "IronICE", coinGeckoId: "iron-bsc", decimals: 18, price: 0.0161403}, // Addr: 0x260b3e40c714ce8196465ec824cd8bb915081812, Notional: 36.837329496 - {chain: 10, addr: "00000000000000000000000027e611fd27b276acbd5ffd632e5eaebec9761e40", symbol: "DAI+USDC", coinGeckoId: "curve-fi-dai-usdc", decimals: 18, price: 1}, // Addr: 0x27e611fd27b276acbd5ffd632e5eaebec9761e40, Notional: 17.51097737 - {chain: 10, addr: "00000000000000000000000028a92dde19d9989f39a49905d7c9c2fac7799bdf", symbol: "USDC", coinGeckoId: "layerzero-usdc", decimals: 6, price: 0.996095}, // Addr: 0x28a92dde19d9989f39a49905d7c9c2fac7799bdf, Notional: 2271.330001992115 - {chain: 10, addr: "00000000000000000000000029b0da86e484e1c0029b56e817912d778ac0ec69", symbol: "YFI", coinGeckoId: "yearn-finance", decimals: 18, price: 7838.88}, // Addr: 0x29b0da86e484e1c0029b56e817912d778ac0ec69, Notional: 2.351664 - {chain: 10, addr: "0000000000000000000000002f6f07cdcf3588944bf4c42ac74ff24bf56e7590", symbol: "STG", coinGeckoId: "stargate-finance", decimals: 18, price: 0.382194}, // Addr: 0x2f6f07cdcf3588944bf4c42ac74ff24bf56e7590, Notional: 5.408237798392859 - {chain: 10, addr: "0000000000000000000000002f733095b80a04b38b0d10cc884524a3d09b836a", symbol: "USDC.e", coinGeckoId: "wormhole-bridged-usdc-fantom", decimals: 6, price: 0.999404}, // Addr: 0x2f733095b80a04b38b0d10cc884524a3d09b836a, Notional: 414.55312399438 - {chain: 10, addr: "000000000000000000000000321162cd933e2be498cd2267a90534a804051b11", symbol: "BTC", coinGeckoId: "wrapped-bitcoin", decimals: 8, price: 94688}, // Addr: 0x321162cd933e2be498cd2267a90534a804051b11, Notional: 101324.83247392 - {chain: 10, addr: "0000000000000000000000003dc57b391262e3aae37a08d91241f9ba9d58b570", symbol: "YOSHI", coinGeckoId: "yoshi-exchange", decimals: 18, price: 0.02597403}, // Addr: 0x3dc57b391262e3aae37a08d91241f9ba9d58b570, Notional: 0.023376627 - {chain: 10, addr: "00000000000000000000000040df1ae6074c35047bff66675488aa2f9f6384f3", symbol: "MATIC", coinGeckoId: "wmatic", decimals: 18, price: 0.586493}, // Addr: 0x40df1ae6074c35047bff66675488aa2f9f6384f3, Notional: 2288.9704729098667 - {chain: 10, addr: "00000000000000000000000042ae8468a1fddb965d420bd71368a87ec3a2b4b8", symbol: "Metti", coinGeckoId: "metti-inu", decimals: 18, price: 2.711e-11}, // Addr: 0x42ae8468a1fddb965d420bd71368a87ec3a2b4b8, Notional: 0.00000309054 - {chain: 10, addr: "00000000000000000000000044f7237df00e386af8e79b817d05ed9f6fe0f296", symbol: "SOL", coinGeckoId: "wrapped-solana", decimals: 18, price: 222.86}, // Addr: 0x44f7237df00e386af8e79b817d05ed9f6fe0f296, Notional: 2843.859808988 - {chain: 10, addr: "000000000000000000000000468003b688943977e6130f4f68f23aad939a1040", symbol: "SPELL", coinGeckoId: "spell-token", decimals: 18, price: 0.00093684}, // Addr: 0x468003b688943977e6130f4f68f23aad939a1040, Notional: 0.1862502579385224 - {chain: 10, addr: "000000000000000000000000511d35c52a3c244e7b8bd92c0c297755fbd89212", symbol: "AVAX", coinGeckoId: "wrapped-avax", decimals: 18, price: 47.01}, // Addr: 0x511d35c52a3c244e7b8bd92c0c297755fbd89212, Notional: 2213.3856029898 - {chain: 10, addr: "000000000000000000000000526f1dc408cfe7fc5330ab9f1e78474ceff2a5dd", symbol: "VEMP", coinGeckoId: "vempire-ddao", decimals: 18, price: 0.0034513}, // Addr: 0x526f1dc408cfe7fc5330ab9f1e78474ceff2a5dd, Notional: 5.6739372 - {chain: 10, addr: "00000000000000000000000056ee926bd8c72b2d5fa1af4d9e4cbb515a1e3adc", symbol: "SNX", coinGeckoId: "havven", decimals: 18, price: 2.45}, // Addr: 0x56ee926bd8c72b2d5fa1af4d9e4cbb515a1e3adc, Notional: 0.4197640125 - {chain: 10, addr: "0000000000000000000000005c4fdfc5233f935f20d2adba572f770c2e377ab0", symbol: "HEC", coinGeckoId: "hector-dao", decimals: 9, price: 0.081686}, // Addr: 0x5c4fdfc5233f935f20d2adba572f770c2e377ab0, Notional: 33.75689059296048 - {chain: 10, addr: "0000000000000000000000005d5530eb3147152fe78d5c4bfeede054c8d1442a", symbol: "FEED", coinGeckoId: "feeder-finance", decimals: 18, price: 0.00030182}, // Addr: 0x5d5530eb3147152fe78d5c4bfeede054c8d1442a, Notional: 1.106299083651255 - {chain: 10, addr: "000000000000000000000000657a1861c15a3ded9af0b6799a195a249ebdcbc6", symbol: "CREAM", coinGeckoId: "cream-2", decimals: 18, price: 18.93}, // Addr: 0x657a1861c15a3ded9af0b6799a195a249ebdcbc6, Notional: 0.13251 - {chain: 10, addr: "0000000000000000000000006626c47c00f1d87902fc13eecfac3ed06d5e8d8a", symbol: "WOO", coinGeckoId: "woo-network", decimals: 18, price: 0.294151}, // Addr: 0x6626c47c00f1d87902fc13eecfac3ed06d5e8d8a, Notional: 26.967098910506042 - {chain: 10, addr: "000000000000000000000000695921034f0387eac4e11620ee91b1b15a6a09fe", symbol: "WETH", coinGeckoId: "bridged-wrapped-ether-stargate", decimals: 18, price: 3596.27}, // Addr: 0x695921034f0387eac4e11620ee91b1b15a6a09fe, Notional: 408.5314170355 - {chain: 10, addr: "0000000000000000000000006a07a792ab2965c72a5b8088d3a069a7ac3a993b", symbol: "AAVE", coinGeckoId: "aave", decimals: 18, price: 221.33}, // Addr: 0x6a07a792ab2965c72a5b8088d3a069a7ac3a993b, Notional: 984.0964161943 - {chain: 10, addr: "00000000000000000000000074b23882a30290451a17c44f4f05243b6b58c76d", symbol: "ETH", coinGeckoId: "weth", decimals: 18, price: 3594.89}, // Addr: 0x74b23882a30290451a17c44f4f05243b6b58c76d, Notional: 59067.039687895194 - {chain: 10, addr: "00000000000000000000000074e23df9110aa9ea0b6ff2faee01e740ca1c642e", symbol: "TOR", coinGeckoId: "tor", decimals: 18, price: 0.00910611}, // Addr: 0x74e23df9110aa9ea0b6ff2faee01e740ca1c642e, Notional: 0.9728702263257472 - {chain: 10, addr: "00000000000000000000000082f0b8b456c1a451378467398982d4834b6829c1", symbol: "MIM", coinGeckoId: "magic-internet-money", decimals: 18, price: 0.99491}, // Addr: 0x82f0b8b456c1a451378467398982d4834b6829c1, Notional: 340.07527862156866 - {chain: 10, addr: "000000000000000000000000841fad6eae12c286d1fd18d1d525dffa75c7effe", symbol: "BOO", coinGeckoId: "spookyswap", decimals: 18, price: 1.38}, // Addr: 0x841fad6eae12c286d1fd18d1d525dffa75c7effe, Notional: 0.026670362999999996 - {chain: 10, addr: "00000000000000000000000085dec8c4b2680793661bca91a8f129607571863d", symbol: "BRUSH", coinGeckoId: "paint-swap", decimals: 18, price: 0.03549674}, // Addr: 0x85dec8c4b2680793661bca91a8f129607571863d, Notional: 0.0850092573941386 - {chain: 10, addr: "0000000000000000000000008d11ec38a3eb5e956b052f67da8bdc9bef8abf3e", symbol: "DAI", coinGeckoId: "dai", decimals: 18, price: 1}, // Addr: 0x8d11ec38a3eb5e956b052f67da8bdc9bef8abf3e, Notional: 24985.8836443 - {chain: 10, addr: "000000000000000000000000904f51a2e7eeaf76aaf0418cbaf0b71149686f4a", symbol: "FAME", coinGeckoId: "fantom-maker", decimals: 18, price: 0.00009078}, // Addr: 0x904f51a2e7eeaf76aaf0418cbaf0b71149686f4a, Notional: 4643.096847488993 - {chain: 10, addr: "00000000000000000000000097bdafe3830734acf12da25359674277fcc33729", symbol: "KIRBY", coinGeckoId: "blue-kirby", decimals: 18, price: 0.00008521}, // Addr: 0x97bdafe3830734acf12da25359674277fcc33729, Notional: 168.42618107346055 - {chain: 10, addr: "0000000000000000000000009879abdea01a879644185341f7af7d8343556b7a", symbol: "TUSD", coinGeckoId: "true-usd", decimals: 18, price: 1.001}, // Addr: 0x9879abdea01a879644185341f7af7d8343556b7a, Notional: 369.53255907567996 - {chain: 10, addr: "0000000000000000000000009fb9a33956351cf4fa040f65a13b835a3c8764e3", symbol: "MULTI", coinGeckoId: "multichain", decimals: 18, price: 0.577897}, // Addr: 0x9fb9a33956351cf4fa040f65a13b835a3c8764e3, Notional: 370.92691506527444 + {chain: 10, addr: "00000000000000000000000027e611fd27b276acbd5ffd632e5eaebec9761e40", symbol: "DAI+USDC", coinGeckoId: "curve-fi-dai-usdc", decimals: 18, price: 0.999945}, // Addr: 0x27e611fd27b276acbd5ffd632e5eaebec9761e40, Notional: 17.51001426624465 + {chain: 10, addr: "00000000000000000000000028a92dde19d9989f39a49905d7c9c2fac7799bdf", symbol: "USDC", coinGeckoId: "layerzero-usdc", decimals: 6, price: 0.993104}, // Addr: 0x28a92dde19d9989f39a49905d7c9c2fac7799bdf, Notional: 2106.7038903904004 + {chain: 10, addr: "00000000000000000000000029b0da86e484e1c0029b56e817912d778ac0ec69", symbol: "YFI", coinGeckoId: "yearn-finance", decimals: 18, price: 7944.41}, // Addr: 0x29b0da86e484e1c0029b56e817912d778ac0ec69, Notional: 81.827423 + {chain: 10, addr: "0000000000000000000000002f6f07cdcf3588944bf4c42ac74ff24bf56e7590", symbol: "STG", coinGeckoId: "stargate-finance", decimals: 18, price: 0.36685}, // Addr: 0x2f6f07cdcf3588944bf4c42ac74ff24bf56e7590, Notional: 5.1911124621015 + {chain: 10, addr: "0000000000000000000000002f733095b80a04b38b0d10cc884524a3d09b836a", symbol: "USDC.e", coinGeckoId: "wormhole-bridged-usdc-fantom", decimals: 6, price: 0.99204}, // Addr: 0x2f733095b80a04b38b0d10cc884524a3d09b836a, Notional: 465.5647142538 + {chain: 10, addr: "000000000000000000000000321162cd933e2be498cd2267a90534a804051b11", symbol: "BTC", coinGeckoId: "wrapped-bitcoin", decimals: 8, price: 93245}, // Addr: 0x321162cd933e2be498cd2267a90534a804051b11, Notional: 100435.2487632 + {chain: 10, addr: "0000000000000000000000003dc57b391262e3aae37a08d91241f9ba9d58b570", symbol: "YOSHI", coinGeckoId: "yoshi-exchange", decimals: 18, price: 0.01812967}, // Addr: 0x3dc57b391262e3aae37a08d91241f9ba9d58b570, Notional: 0.016316703000000002 + {chain: 10, addr: "00000000000000000000000040df1ae6074c35047bff66675488aa2f9f6384f3", symbol: "MATIC", coinGeckoId: "wmatic", decimals: 18, price: 0.450504}, // Addr: 0x40df1ae6074c35047bff66675488aa2f9f6384f3, Notional: 1758.7526759808984 + {chain: 10, addr: "00000000000000000000000042ae8468a1fddb965d420bd71368a87ec3a2b4b8", symbol: "Metti", coinGeckoId: "metti-inu", decimals: 18, price: 2.9959e-11}, // Addr: 0x42ae8468a1fddb965d420bd71368a87ec3a2b4b8, Notional: 0.0000034153259999999996 + {chain: 10, addr: "00000000000000000000000044f7237df00e386af8e79b817d05ed9f6fe0f296", symbol: "SOL", coinGeckoId: "wrapped-solana", decimals: 18, price: 190.69}, // Addr: 0x44f7237df00e386af8e79b817d05ed9f6fe0f296, Notional: 2433.3466166020003 + {chain: 10, addr: "000000000000000000000000468003b688943977e6130f4f68f23aad939a1040", symbol: "SPELL", coinGeckoId: "spell-token", decimals: 18, price: 0.00073482}, // Addr: 0x468003b688943977e6130f4f68f23aad939a1040, Notional: 0.1460872876247652 + {chain: 10, addr: "000000000000000000000000511d35c52a3c244e7b8bd92c0c297755fbd89212", symbol: "AVAX", coinGeckoId: "wrapped-avax", decimals: 18, price: 35.57}, // Addr: 0x511d35c52a3c244e7b8bd92c0c297755fbd89212, Notional: 1692.4743377332 + {chain: 10, addr: "000000000000000000000000526f1dc408cfe7fc5330ab9f1e78474ceff2a5dd", symbol: "VEMP", coinGeckoId: "vempire-ddao", decimals: 18, price: 0.00421204}, // Addr: 0x526f1dc408cfe7fc5330ab9f1e78474ceff2a5dd, Notional: 6.9245937600000005 + {chain: 10, addr: "00000000000000000000000056ee926bd8c72b2d5fa1af4d9e4cbb515a1e3adc", symbol: "SNX", coinGeckoId: "havven", decimals: 18, price: 1.9}, // Addr: 0x56ee926bd8c72b2d5fa1af4d9e4cbb515a1e3adc, Notional: 0.32553127499999995 + {chain: 10, addr: "0000000000000000000000005c4fdfc5233f935f20d2adba572f770c2e377ab0", symbol: "HEC", coinGeckoId: "hector-dao", decimals: 9, price: 0.05066}, // Addr: 0x5c4fdfc5233f935f20d2adba572f770c2e377ab0, Notional: 20.9353387047888 + {chain: 10, addr: "0000000000000000000000005d5530eb3147152fe78d5c4bfeede054c8d1442a", symbol: "FEED", coinGeckoId: "feeder-finance", decimals: 18, price: 0.00037011}, // Addr: 0x5d5530eb3147152fe78d5c4bfeede054c8d1442a, Notional: 1.3566110723284275 + {chain: 10, addr: "000000000000000000000000657a1861c15a3ded9af0b6799a195a249ebdcbc6", symbol: "CREAM", coinGeckoId: "cream-2", decimals: 18, price: 13.16}, // Addr: 0x657a1861c15a3ded9af0b6799a195a249ebdcbc6, Notional: 0.09212000000000001 + {chain: 10, addr: "0000000000000000000000006626c47c00f1d87902fc13eecfac3ed06d5e8d8a", symbol: "WOO", coinGeckoId: "woo-network", decimals: 18, price: 0.207659}, // Addr: 0x6626c47c00f1d87902fc13eecfac3ed06d5e8d8a, Notional: 19.03770781896636 + {chain: 10, addr: "000000000000000000000000695921034f0387eac4e11620ee91b1b15a6a09fe", symbol: "WETH", coinGeckoId: "bridged-wrapped-ether-stargate", decimals: 18, price: 3337.89}, // Addr: 0x695921034f0387eac4e11620ee91b1b15a6a09fe, Notional: 379.17979784849996 + {chain: 10, addr: "0000000000000000000000006a07a792ab2965c72a5b8088d3a069a7ac3a993b", symbol: "AAVE", coinGeckoId: "aave", decimals: 18, price: 309.59}, // Addr: 0x6a07a792ab2965c72a5b8088d3a069a7ac3a993b, Notional: 1376.5255929588998 + {chain: 10, addr: "00000000000000000000000074b23882a30290451a17c44f4f05243b6b58c76d", symbol: "ETH", coinGeckoId: "weth", decimals: 18, price: 3332.06}, // Addr: 0x74b23882a30290451a17c44f4f05243b6b58c76d, Notional: 54748.52367178079 + {chain: 10, addr: "00000000000000000000000074e23df9110aa9ea0b6ff2faee01e740ca1c642e", symbol: "TOR", coinGeckoId: "tor", decimals: 18, price: 0.00618907}, // Addr: 0x74e23df9110aa9ea0b6ff2faee01e740ca1c642e, Notional: 0.6612221828690726 + {chain: 10, addr: "00000000000000000000000082f0b8b456c1a451378467398982d4834b6829c1", symbol: "MIM", coinGeckoId: "magic-internet-money", decimals: 18, price: 0.994109}, // Addr: 0x82f0b8b456c1a451378467398982d4834b6829c1, Notional: 339.8014847123951 + {chain: 10, addr: "000000000000000000000000841fad6eae12c286d1fd18d1d525dffa75c7effe", symbol: "BOO", coinGeckoId: "spookyswap", decimals: 18, price: 0.767801}, // Addr: 0x841fad6eae12c286d1fd18d1d525dffa75c7effe, Notional: 0.014838790856349999 + {chain: 10, addr: "00000000000000000000000085dec8c4b2680793661bca91a8f129607571863d", symbol: "BRUSH", coinGeckoId: "paint-swap", decimals: 18, price: 0.01670095}, // Addr: 0x85dec8c4b2680793661bca91a8f129607571863d, Notional: 0.37401521816754546 + {chain: 10, addr: "0000000000000000000000008d11ec38a3eb5e956b052f67da8bdc9bef8abf3e", symbol: "DAI", coinGeckoId: "dai", decimals: 18, price: 0.99899}, // Addr: 0x8d11ec38a3eb5e956b052f67da8bdc9bef8abf3e, Notional: 26676.811363404755 + {chain: 10, addr: "000000000000000000000000904f51a2e7eeaf76aaf0418cbaf0b71149686f4a", symbol: "FAME", coinGeckoId: "fantom-maker", decimals: 18, price: 0.00006554}, // Addr: 0x904f51a2e7eeaf76aaf0418cbaf0b71149686f4a, Notional: 3352.154300335191 + {chain: 10, addr: "00000000000000000000000097bdafe3830734acf12da25359674277fcc33729", symbol: "KIRBY", coinGeckoId: "blue-kirby", decimals: 18, price: 0.0000204}, // Addr: 0x97bdafe3830734acf12da25359674277fcc33729, Notional: 40.322662761396494 + {chain: 10, addr: "0000000000000000000000009879abdea01a879644185341f7af7d8343556b7a", symbol: "TUSD", coinGeckoId: "true-usd", decimals: 18, price: 0.996888}, // Addr: 0x9879abdea01a879644185341f7af7d8343556b7a, Notional: 368.01455919264384 + {chain: 10, addr: "0000000000000000000000009fb9a33956351cf4fa040f65a13b835a3c8764e3", symbol: "MULTI", coinGeckoId: "multichain", decimals: 18, price: 0.380015}, // Addr: 0x9fb9a33956351cf4fa040f65a13b835a3c8764e3, Notional: 243.91507764970274 {chain: 10, addr: "000000000000000000000000a23c4e69e5eaf4500f2f9301717f12b578b948fb", symbol: "PROTO", coinGeckoId: "protofi", decimals: 18, price: 0.0000271}, // Addr: 0xa23c4e69e5eaf4500f2f9301717f12b578b948fb, Notional: 0.004607 - {chain: 10, addr: "000000000000000000000000ad996a45fd2373ed0b10efa4a8ecb9de445a4302", symbol: "ALPACA", coinGeckoId: "alpaca-finance", decimals: 18, price: 0.235075}, // Addr: 0xad996a45fd2373ed0b10efa4a8ecb9de445a4302, Notional: 0.65465881835575 - {chain: 10, addr: "000000000000000000000000ae75a438b2e0cb8bb01ec1e1e376de11d44477cc", symbol: "SUSHI", coinGeckoId: "sushi", decimals: 18, price: 1.35}, // Addr: 0xae75a438b2e0cb8bb01ec1e1e376de11d44477cc, Notional: 77.15185981650001 - {chain: 10, addr: "000000000000000000000000b3654dc3d10ea7645f8319668e8f54d2574fbdc8", symbol: "LINK", coinGeckoId: "chainlink", decimals: 18, price: 19.89}, // Addr: 0xb3654dc3d10ea7645f8319668e8f54d2574fbdc8, Notional: 5060.9370790485 - {chain: 10, addr: "000000000000000000000000b715f8dce2f0e9b894c753711bd55ee3c04dca4e", symbol: "CONK", coinGeckoId: "shibapoconk", decimals: 18, price: 2.03989e-10}, // Addr: 0xb715f8dce2f0e9b894c753711bd55ee3c04dca4e, Notional: 0.006731637 - {chain: 10, addr: "000000000000000000000000be41772587872a92184873d55b09c6bb6f59f895", symbol: "MARS", coinGeckoId: "projectmars", decimals: 9, price: 4.21487e-7}, // Addr: 0xbe41772587872a92184873d55b09c6bb6f59f895, Notional: 0.04438034721656496 - {chain: 10, addr: "000000000000000000000000cc1b99ddac1a33c201a742a1851662e87bc7f22c", symbol: "USDT", coinGeckoId: "bridged-tether-stargate", decimals: 6, price: 1.004}, // Addr: 0xcc1b99ddac1a33c201a742a1851662e87bc7f22c, Notional: 269.03609394800003 - {chain: 10, addr: "000000000000000000000000d67de0e0a0fd7b15dc8348bb9be742f3c5850454", symbol: "BNB", coinGeckoId: "wbnb", decimals: 18, price: 632.16}, // Addr: 0xd67de0e0a0fd7b15dc8348bb9be742f3c5850454, Notional: 12586.2506905824 - {chain: 10, addr: "000000000000000000000000d8321aa83fb0a4ecd6348d4577431310a6e0814d", symbol: "GEIST", coinGeckoId: "geist-finance", decimals: 18, price: 0.00026744}, // Addr: 0xd8321aa83fb0a4ecd6348d4577431310a6e0814d, Notional: 0.0026743999999999995 - {chain: 10, addr: "000000000000000000000000dc301622e621166bd8e82f2ca0a26c13ad0be355", symbol: "FRAX", coinGeckoId: "frax", decimals: 18, price: 0.996303}, // Addr: 0xdc301622e621166bd8e82f2ca0a26c13ad0be355, Notional: 144.11645654474145 - {chain: 10, addr: "000000000000000000000000de5ed76e7c05ec5e4572cfc88d1acea165109e44", symbol: "DEUS", coinGeckoId: "deus-finance-2", decimals: 18, price: 24.1}, // Addr: 0xde5ed76e7c05ec5e4572cfc88d1acea165109e44, Notional: 2.403913786 - {chain: 10, addr: "000000000000000000000000e2d27f06f63d98b8e11b38b5b08a75d0c8dd62b9", symbol: "UST", coinGeckoId: "wrapped-ust", decimals: 6, price: 0.02485643}, // Addr: 0xe2d27f06f63d98b8e11b38b5b08a75d0c8dd62b9, Notional: 434.9697199912009 - {chain: 10, addr: "000000000000000000000000e47d957f83f8887063150aaf7187411351643392", symbol: "CHILL", coinGeckoId: "chillpill", decimals: 18, price: 5.72156e-10}, // Addr: 0xe47d957f83f8887063150aaf7187411351643392, Notional: 0.2297778496 - {chain: 10, addr: "000000000000000000000000e64b9fd040d1f9d4715c645e0d567ef69958d3d9", symbol: "MOD", coinGeckoId: "modefi", decimals: 18, price: 0.03611367}, // Addr: 0xe64b9fd040d1f9d4715c645e0d567ef69958d3d9, Notional: 0.6073746339791349 - {chain: 10, addr: "000000000000000000000000e705af5f63fcabdcdf5016aa838eaaac35d12890", symbol: "MCRT", coinGeckoId: "magiccraft", decimals: 9, price: 0.00120617}, // Addr: 0xe705af5f63fcabdcdf5016aa838eaaac35d12890, Notional: 1.056675354453952 - {chain: 10, addr: "000000000000000000000000ee9801669c6138e84bd50deb500827b776777d28", symbol: "O3", coinGeckoId: "o3-swap", decimals: 18, price: 0.0101476}, // Addr: 0xee9801669c6138e84bd50deb500827b776777d28, Notional: 5.905428564478632 - {chain: 10, addr: "000000000000000000000000ef4b763385838fffc708000f884026b8c0434275", symbol: "fmXEN", coinGeckoId: "xen-crypto-fantom", decimals: 18, price: 8.041e-11}, // Addr: 0xef4b763385838fffc708000f884026b8c0434275, Notional: 0.001543706310788913 - {chain: 10, addr: "000000000000000000000000fb98b335551a418cd0737375a2ea0ded62ea213b", symbol: "miMATIC", coinGeckoId: "mimatic", decimals: 18, price: 0.993831}, // Addr: 0xfb98b335551a418cd0737375a2ea0ded62ea213b, Notional: 25.78423403002992 + {chain: 10, addr: "000000000000000000000000ad996a45fd2373ed0b10efa4a8ecb9de445a4302", symbol: "ALPACA", coinGeckoId: "alpaca-finance", decimals: 18, price: 0.164656}, // Addr: 0xad996a45fd2373ed0b10efa4a8ecb9de445a4302, Notional: 0.45854940931696 + {chain: 10, addr: "000000000000000000000000ae75a438b2e0cb8bb01ec1e1e376de11d44477cc", symbol: "SUSHI", coinGeckoId: "sushi", decimals: 18, price: 1.36}, // Addr: 0xae75a438b2e0cb8bb01ec1e1e376de11d44477cc, Notional: 91.3233550744 + {chain: 10, addr: "000000000000000000000000b3654dc3d10ea7645f8319668e8f54d2574fbdc8", symbol: "LINK", coinGeckoId: "chainlink", decimals: 18, price: 19.87}, // Addr: 0xb3654dc3d10ea7645f8319668e8f54d2574fbdc8, Notional: 4736.3412108854 + {chain: 10, addr: "000000000000000000000000b715f8dce2f0e9b894c753711bd55ee3c04dca4e", symbol: "CONK", coinGeckoId: "shibapoconk", decimals: 18, price: 9.0155e-11}, // Addr: 0xb715f8dce2f0e9b894c753711bd55ee3c04dca4e, Notional: 0.002975115 + {chain: 10, addr: "000000000000000000000000be41772587872a92184873d55b09c6bb6f59f895", symbol: "MARS", coinGeckoId: "projectmars", decimals: 9, price: 1.42964e-7}, // Addr: 0xbe41772587872a92184873d55b09c6bb6f59f895, Notional: 0.01505335149000798 + {chain: 10, addr: "000000000000000000000000cc1b99ddac1a33c201a742a1851662e87bc7f22c", symbol: "USDT", coinGeckoId: "bridged-tether-stargate", decimals: 6, price: 1.0}, // Addr: 0xcc1b99ddac1a33c201a742a1851662e87bc7f22c, Notional: 196.51130523971304 + {chain: 10, addr: "000000000000000000000000d67de0e0a0fd7b15dc8348bb9be742f3c5850454", symbol: "BNB", coinGeckoId: "wbnb", decimals: 18, price: 699.48}, // Addr: 0xd67de0e0a0fd7b15dc8348bb9be742f3c5850454, Notional: 13928.060106334802 + {chain: 10, addr: "000000000000000000000000d8321aa83fb0a4ecd6348d4577431310a6e0814d", symbol: "GEIST", coinGeckoId: "geist-finance", decimals: 18, price: 0.0001642}, // Addr: 0xd8321aa83fb0a4ecd6348d4577431310a6e0814d, Notional: 0.001642 + {chain: 10, addr: "000000000000000000000000dc301622e621166bd8e82f2ca0a26c13ad0be355", symbol: "FRAX", coinGeckoId: "frax", decimals: 18, price: 0.993202}, // Addr: 0xdc301622e621166bd8e82f2ca0a26c13ad0be355, Notional: 143.6678930738443 + {chain: 10, addr: "000000000000000000000000de5ed76e7c05ec5e4572cfc88d1acea165109e44", symbol: "DEUS", coinGeckoId: "deus-finance-2", decimals: 18, price: 23.59}, // Addr: 0xde5ed76e7c05ec5e4572cfc88d1acea165109e44, Notional: 2.3530425814 + {chain: 10, addr: "000000000000000000000000e2d27f06f63d98b8e11b38b5b08a75d0c8dd62b9", symbol: "UST", coinGeckoId: "wrapped-ust", decimals: 6, price: 0.01958015}, // Addr: 0xe2d27f06f63d98b8e11b38b5b08a75d0c8dd62b9, Notional: 342.6385994644329 + {chain: 10, addr: "000000000000000000000000e47d957f83f8887063150aaf7187411351643392", symbol: "CHILL", coinGeckoId: "chillpill", decimals: 18, price: 1.9588e-11}, // Addr: 0xe47d957f83f8887063150aaf7187411351643392, Notional: 0.0078665408 + {chain: 10, addr: "000000000000000000000000e64b9fd040d1f9d4715c645e0d567ef69958d3d9", symbol: "MOD", coinGeckoId: "modefi", decimals: 18, price: 0.01292186}, // Addr: 0xe64b9fd040d1f9d4715c645e0d567ef69958d3d9, Notional: 0.2173251842814542 + {chain: 10, addr: "000000000000000000000000e705af5f63fcabdcdf5016aa838eaaac35d12890", symbol: "MCRT", coinGeckoId: "magiccraft", decimals: 9, price: 0.00101283}, // Addr: 0xe705af5f63fcabdcdf5016aa838eaaac35d12890, Notional: 0.8872982243395179 + {chain: 10, addr: "000000000000000000000000ee9801669c6138e84bd50deb500827b776777d28", symbol: "O3", coinGeckoId: "o3-swap", decimals: 18, price: 0.00953653}, // Addr: 0xee9801669c6138e84bd50deb500827b776777d28, Notional: 5.549814406165735 + {chain: 10, addr: "000000000000000000000000ef4b763385838fffc708000f884026b8c0434275", symbol: "fmXEN", coinGeckoId: "xen-crypto-fantom", decimals: 18, price: 8.2685e-11}, // Addr: 0xef4b763385838fffc708000f884026b8c0434275, Notional: 0.0015873816230267538 + {chain: 10, addr: "000000000000000000000000fb98b335551a418cd0737375a2ea0ded62ea213b", symbol: "miMATIC", coinGeckoId: "mimatic", decimals: 18, price: 0.994558}, // Addr: 0xfb98b335551a418cd0737375a2ea0ded62ea213b, Notional: 25.803095524730562 {chain: 11, addr: "0000000000000000000000000000000000000000000100000000000000000081", symbol: "aUSD", coinGeckoId: "acala-dollar", decimals: 12, price: 0.51763}, // Addr: 0x0000000000000000000100000000000000000081, Notional: 5.1058603195018 - {chain: 12, addr: "0000000000000000000000000000000000000000000100000000000000000001", symbol: "aUSD", coinGeckoId: "acala-dollar-acala", decimals: 12, price: 0.57053}, // Addr: 0x0000000000000000000100000000000000000001, Notional: 232.7780802559256 - {chain: 13, addr: "00000000000000000000000034d21b1e550d73cee41151c77f3c73359527a396", symbol: "oETH", coinGeckoId: "orbit-bridge-klaytn-ethereum", decimals: 18, price: 655.01}, // Addr: 0x34d21b1e550d73cee41151c77f3c73359527a396, Notional: 1.31002 - {chain: 13, addr: "0000000000000000000000005c74070fdea071359b86082bd9f9b3deaafbe32b", symbol: "KDAI", coinGeckoId: "klaytn-dai", decimals: 18, price: 0.216855}, // Addr: 0x5c74070fdea071359b86082bd9f9b3deaafbe32b, Notional: 0.0043371 - {chain: 13, addr: "0000000000000000000000006270b58be569a7c0b8f47594f191631ae5b2c86c", symbol: "USDC", coinGeckoId: "usd-coin", decimals: 6, price: 1}, // Addr: 0x6270b58be569a7c0b8f47594f191631ae5b2c86c, Notional: 45571.559055 - {chain: 13, addr: "000000000000000000000000754288077d0ff82af7a5317c7cb8c444d421d103", symbol: "oUSDC", coinGeckoId: "orbit-bridge-klaytn-usdc", decimals: 6, price: 0.345274}, // Addr: 0x754288077d0ff82af7a5317c7cb8c444d421d103, Notional: 1.450555461128 - {chain: 13, addr: "0000000000000000000000009eaefb09fe4aabfbe6b1ca316a3c36afc83a393f", symbol: "oXRP", coinGeckoId: "orbit-bridge-klaytn-ripple", decimals: 6, price: 2.37}, // Addr: 0x9eaefb09fe4aabfbe6b1ca316a3c36afc83a393f, Notional: 0.11850000000000001 - {chain: 13, addr: "000000000000000000000000c6a2ad8cc6e4a7e08fc37cc5954be07d499e7654", symbol: "KSP", coinGeckoId: "klayswap-protocol", decimals: 18, price: 0.249078}, // Addr: 0xc6a2ad8cc6e4a7e08fc37cc5954be07d499e7654, Notional: 0.33625530000000003 - {chain: 13, addr: "000000000000000000000000cd670d77f3dcab82d43dff9bd2c4b87339fb3560", symbol: "KOKOS", coinGeckoId: "kokonut-swap", decimals: 18, price: 0.155415}, // Addr: 0xcd670d77f3dcab82d43dff9bd2c4b87339fb3560, Notional: 1308021.1467209973 - {chain: 13, addr: "000000000000000000000000ce899f5fcf55b0c1d7478910f812cfe68c5bcf0f", symbol: "ABC", coinGeckoId: "angry-bulls-club", decimals: 18, price: 0.00475223}, // Addr: 0xce899f5fcf55b0c1d7478910f812cfe68c5bcf0f, Notional: 6.858135453568962 - {chain: 13, addr: "000000000000000000000000cee8faf64bb97a73bb51e115aa89c17ffa8dd167", symbol: "oUSDT", coinGeckoId: "orbit-bridge-klaytn-usd-tether", decimals: 6, price: 0.199587}, // Addr: 0xcee8faf64bb97a73bb51e115aa89c17ffa8dd167, Notional: 20.589695897196 - {chain: 13, addr: "000000000000000000000000d068c52d81f4409b9502da926ace3301cc41f623", symbol: "MBX", coinGeckoId: "marblex", decimals: 18, price: 0.506041}, // Addr: 0xd068c52d81f4409b9502da926ace3301cc41f623, Notional: 0.0506041 - {chain: 13, addr: "000000000000000000000000e4f05a66ec68b54a58b17c22107b02e0232cc817", symbol: "WKLAY", coinGeckoId: "wrapped-klay", decimals: 18, price: 0.294046}, // Addr: 0xe4f05a66ec68b54a58b17c22107b02e0232cc817, Notional: 4749.215858342857 - {chain: 13, addr: "000000000000000000000000e950bdcfa4d1e45472e76cf967db93dbfc51ba3e", symbol: "KAI", coinGeckoId: "kai-protocol", decimals: 18, price: 0.070905}, // Addr: 0xe950bdcfa4d1e45472e76cf967db93dbfc51ba3e, Notional: 50430.546825259844 - {chain: 14, addr: "00000000000000000000000000be915b9dcf56a3cbe739d9b9c202ca692409ec", symbol: "UBE", coinGeckoId: "ubeswap", decimals: 18, price: 0.00025388}, // Addr: 0x00be915b9dcf56a3cbe739d9b9c202ca692409ec, Notional: 0.34202833653251125 - {chain: 14, addr: "0000000000000000000000002def4285787d58a2f811af24755a8150622f4361", symbol: "cETH", coinGeckoId: "weth", decimals: 18, price: 3594.89}, // Addr: 0x2def4285787d58a2f811af24755a8150622f4361, Notional: 1.6853203809 - {chain: 14, addr: "00000000000000000000000046c9757c5497c5b1f2eb73ae79b6b67d119b0b58", symbol: "PACT", coinGeckoId: "impactmarket", decimals: 18, price: 0.00002924}, // Addr: 0x46c9757c5497c5b1f2eb73ae79b6b67d119b0b58, Notional: 2980.620036014329 - {chain: 14, addr: "000000000000000000000000471ece3750da237f93b8e339c536989b8978a438", symbol: "CELO", coinGeckoId: "celo", decimals: 18, price: 0.9479}, // Addr: 0x471ece3750da237f93b8e339c536989b8978a438, Notional: 598700.0662672342 - {chain: 14, addr: "00000000000000000000000048065fbbe25f71c9282ddf5e1cd6d6a887483d5e", symbol: "USD₮", coinGeckoId: "tether", decimals: 6, price: 1}, // Addr: 0x48065fbbe25f71c9282ddf5e1cd6d6a887483d5e, Notional: 1.871171 - {chain: 14, addr: "00000000000000000000000062b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a", symbol: "G$", coinGeckoId: "gooddollar", decimals: 18, price: 0.00005854}, // Addr: 0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a, Notional: 0.00005854 - {chain: 14, addr: "000000000000000000000000639a647fbe20b6c8ac19e48e2de44ea792c62c5c", symbol: "BIFI", coinGeckoId: "beefy-finance", decimals: 18, price: 332.12}, // Addr: 0x639a647fbe20b6c8ac19e48e2de44ea792c62c5c, Notional: 202.48605808800002 - {chain: 14, addr: "00000000000000000000000074c0c58b99b68cf16a717279ac2d056a34ba2bfe", symbol: "SOURCE", coinGeckoId: "resource-protocol", decimals: 18, price: 0.00748291}, // Addr: 0x74c0c58b99b68cf16a717279ac2d056a34ba2bfe, Notional: 0.032176513 - {chain: 14, addr: "000000000000000000000000765de816845861e75a25fca122bb6898b8b1282a", symbol: "cUSD", coinGeckoId: "celo-dollar", decimals: 18, price: 1.002}, // Addr: 0x765de816845861e75a25fca122bb6898b8b1282a, Notional: 475.7392635684 - {chain: 14, addr: "000000000000000000000000c16b81af351ba9e64c1a069e3ab18c244a1e3049", symbol: "agEUR", coinGeckoId: "ageur", decimals: 18, price: 1.046}, // Addr: 0xc16b81af351ba9e64c1a069e3ab18c244a1e3049, Notional: 60.50704599688 - {chain: 14, addr: "000000000000000000000000ceba9300f2b948710d2653dd7b07f33a8b32118c", symbol: "USDC", coinGeckoId: "usd-coin", decimals: 6, price: 1}, // Addr: 0xceba9300f2b948710d2653dd7b07f33a8b32118c, Notional: 1013.905056 - {chain: 14, addr: "000000000000000000000000d629eb00deced2a080b7ec630ef6ac117e614f1b", symbol: "BTC", coinGeckoId: "wrapped-bitcoin", decimals: 18, price: 94688}, // Addr: 0xd629eb00deced2a080b7ec630ef6ac117e614f1b, Notional: 12.214751999999999 - {chain: 14, addr: "000000000000000000000000d8763cba276a3738e6de85b4b3bf5fded6d6ca73", symbol: "cEUR", coinGeckoId: "celo-euro", decimals: 18, price: 1.051}, // Addr: 0xd8763cba276a3738e6de85b4b3bf5fded6d6ca73, Notional: 31898.62658357419 - {chain: 14, addr: "000000000000000000000000eb466342c4d449bc9f53a865d5cb90586f405215", symbol: "axlUSDC", coinGeckoId: "axlusdc", decimals: 6, price: 0.99899}, // Addr: 0xeb466342c4d449bc9f53a865d5cb90586f405215, Notional: 0.22673576535 - {chain: 15, addr: "152fd354c086478f67c36eaa07d209631825c097490fbdb38b2a9876039be6e0", symbol: "PURGE", coinGeckoId: "forgive-me-father", decimals: 18, price: 0.0242359}, // Addr: purge-558.meme-cooking.near, Notional: 6.1770992982101 - {chain: 15, addr: "67499b7b8f58eaeb3cd81aea1d1ce9f7f722fd7750ceb2bed13e255073c25e2a", symbol: "SWEAT", coinGeckoId: "sweatcoin", decimals: 18, price: 0.00779828}, // Addr: token.sweat, Notional: 8268079.420513918 - {chain: 15, addr: "7cfae19928f9a3b68d342084a420284cb9a7984f52504300acb4e6f7f569393b", symbol: "SHITZU", coinGeckoId: "shitzu", decimals: 18, price: 0.00752106}, // Addr: token.0xshitzu.near, Notional: 0.022563180000000002 - {chain: 15, addr: "95a38d5f6bda0f5e212cd90fd5ae1f40b3a44a1de54df58fb501266cdfc8af7b", symbol: "WALC", coinGeckoId: "walc", decimals: 24, price: 0.00550134}, // Addr: walc.near, Notional: 1650.402 - {chain: 15, addr: "9bef49ce5caa641ff4455e44855fe85a80fb71aecf70b59fc54164b309304e66", symbol: "USDC", coinGeckoId: "usd-coin", decimals: 6, price: 1}, // Addr: 17208628f84f5d6ad33f0da3bbbeb27ffcb398eac501a31bd6ad2011e36133a1, Notional: 1.999899 - {chain: 15, addr: "b55c490bafb82aeb4b950fa479341c1b5fbfa814f8253b6acdf8426b7cd9d3c0", symbol: "wNEAR", coinGeckoId: "wrapped-near", decimals: 24, price: 6.55}, // Addr: wrap.near, Notional: 297.1251433805 - {chain: 15, addr: "f2cc590922eb9d32267bd416a259c2944789f9eb1a6584f4b7149e0f820a237b", symbol: "SOL", coinGeckoId: "wrapped-solana", decimals: 24, price: 222.86}, // Addr: sol.token.a11bd.near, Notional: 38.7847135764 - {chain: 16, addr: "00000000000000000000000030d2a9f5fdf90ace8c17952cbb4ee48a55d916a7", symbol: "WETH", coinGeckoId: "weth", decimals: 18, price: 3594.89}, // Addr: 0x30d2a9f5fdf90ace8c17952cbb4ee48a55d916a7, Notional: 2552.4042180610995 - {chain: 16, addr: "000000000000000000000000322e86852e492a7ee17f28a78c663da38fb33bfb", symbol: "FRAX", coinGeckoId: "frax", decimals: 18, price: 0.996303}, // Addr: 0x322e86852e492a7ee17f28a78c663da38fb33bfb, Notional: 4.99147803 - {chain: 16, addr: "0000000000000000000000003405a1bd46b85c5c029483fbecf2f3e611026e45", symbol: "MATIC", coinGeckoId: "matic-network", decimals: 18, price: 0.587051}, // Addr: 0x3405a1bd46b85c5c029483fbecf2f3e611026e45, Notional: 91.99673207080167 - {chain: 16, addr: "0000000000000000000000004792c1ecb969b036eb51330c63bd27899a13d84e", symbol: "AVAX", coinGeckoId: "wrapped-avax", decimals: 18, price: 47.01}, // Addr: 0x4792c1ecb969b036eb51330c63bd27899a13d84e, Notional: 928.9589175590999 - {chain: 16, addr: "000000000000000000000000511ab53f793683763e5a8829738301368a2411e3", symbol: "WELL", coinGeckoId: "moonwell-artemis", decimals: 18, price: 0.061437}, // Addr: 0x511ab53f793683763e5a8829738301368a2411e3, Notional: 5180692.808606338 - {chain: 16, addr: "000000000000000000000000765277eebeca2e31912c9946eae1021199b39c61", symbol: "DAI", coinGeckoId: "dai", decimals: 18, price: 1}, // Addr: 0x765277eebeca2e31912c9946eae1021199b39c61, Notional: 24 - {chain: 16, addr: "000000000000000000000000818ec0a7fe18ff94269904fced6ae3dae6d6dc0b", symbol: "USDC", coinGeckoId: "multichain-bridged-usdc-moonbeam", decimals: 6, price: 0.179448}, // Addr: 0x818ec0a7fe18ff94269904fced6ae3dae6d6dc0b, Notional: 210.7404742188 - {chain: 16, addr: "0000000000000000000000008f552a71efe5eefc207bf75485b356a0b3f01ec9", symbol: "USDC", coinGeckoId: "usd-coin", decimals: 6, price: 1}, // Addr: 0x8f552a71efe5eefc207bf75485b356a0b3f01ec9, Notional: 1272.414196 - {chain: 16, addr: "000000000000000000000000922d641a426dcffaef11680e5358f34d97d112e1", symbol: "WBTC", coinGeckoId: "wrapped-bitcoin", decimals: 8, price: 94688}, // Addr: 0x922d641a426dcffaef11680e5358f34d97d112e1, Notional: 1184.65293056 - {chain: 16, addr: "000000000000000000000000a423e7eeb60547d9c7b65005477b63ae7ce67e62", symbol: "EFT", coinGeckoId: "energyfi", decimals: 18, price: 0.0002257}, // Addr: 0xa423e7eeb60547d9c7b65005477b63ae7ce67e62, Notional: 5.6425 - {chain: 16, addr: "000000000000000000000000a649325aa7c5093d12d6f98eb4378deae68ce23f", symbol: "BUSD", coinGeckoId: "binance-usd", decimals: 18, price: 0.991874}, // Addr: 0xa649325aa7c5093d12d6f98eb4378deae68ce23f, Notional: 2921.439412286876 - {chain: 16, addr: "000000000000000000000000acc15dc74880c9944775448304b263d191c6077f", symbol: "WGLMR", coinGeckoId: "wrapped-moonbeam", decimals: 18, price: 0.302619}, // Addr: 0xacc15dc74880c9944775448304b263d191c6077f, Notional: 14596.330208340758 - {chain: 16, addr: "000000000000000000000000ca01a1d0993565291051daff390892518acfad3a", symbol: "axlUSDC", coinGeckoId: "axlusdc", decimals: 6, price: 0.99899}, // Addr: 0xca01a1d0993565291051daff390892518acfad3a, Notional: 16.9928199 - {chain: 16, addr: "000000000000000000000000cd3b51d98478d53f4515a306be565c6eebef1d58", symbol: "GLINT", coinGeckoId: "beamswap", decimals: 18, price: 0.00055349}, // Addr: 0xcd3b51d98478d53f4515a306be565c6eebef1d58, Notional: 0.01383725 - {chain: 16, addr: "000000000000000000000000ecf2adaff1de8a512f6e8bfe67a2c836edb25da3", symbol: "xcRMRK", coinGeckoId: "rmrk", decimals: 10, price: 0.410762}, // Addr: 0xecf2adaff1de8a512f6e8bfe67a2c836edb25da3, Notional: 0.24684930929757998 - {chain: 16, addr: "000000000000000000000000efaeee334f0fd1712f9a8cc375f427d9cdd40d73", symbol: "USDT", coinGeckoId: "tether", decimals: 6, price: 1}, // Addr: 0xefaeee334f0fd1712f9a8cc375f427d9cdd40d73, Notional: 561.934496 - {chain: 16, addr: "000000000000000000000000fa9343c3897324496a05fc75abed6bac29f8a40f", symbol: "ETH", coinGeckoId: "weth", decimals: 18, price: 3594.89}, // Addr: 0xfa9343c3897324496a05fc75abed6bac29f8a40f, Notional: 3195.1883807154995 - {chain: 16, addr: "000000000000000000000000ffffffff1fcacbd218edc0eba20fc2308c778080", symbol: "xcDOT", coinGeckoId: "xcdot", decimals: 10, price: 8.64}, // Addr: 0xffffffff1fcacbd218edc0eba20fc2308c778080, Notional: 399.7565975808001 - {chain: 16, addr: "000000000000000000000000ffffffff52c56a9257bb97f4b2b6f7b2d624ecda", symbol: "xcaUSD", coinGeckoId: "acala-dollar-acala", decimals: 12, price: 0.57053}, // Addr: 0xffffffff52c56a9257bb97f4b2b6f7b2d624ecda, Notional: 19.749851182673698 - {chain: 16, addr: "000000000000000000000000ffffffffea09fb06d082fd1275cd48b191cbcd1d", symbol: "xcUSDT", coinGeckoId: "xcusdt", decimals: 6, price: 1.01}, // Addr: 0xffffffffea09fb06d082fd1275cd48b191cbcd1d, Notional: 46.15421139 + {chain: 12, addr: "0000000000000000000000000000000000000000000100000000000000000001", symbol: "aUSD", coinGeckoId: "acala-dollar-acala", decimals: 12, price: 0.450452}, // Addr: 0x0000000000000000000100000000000000000001, Notional: 183.78586894193504 + {chain: 13, addr: "00000000000000000000000034d21b1e550d73cee41151c77f3c73359527a396", symbol: "oETH", coinGeckoId: "orbit-bridge-klaytn-ethereum", decimals: 18, price: 388.64}, // Addr: 0x34d21b1e550d73cee41151c77f3c73359527a396, Notional: 0.77728 + {chain: 13, addr: "0000000000000000000000005c74070fdea071359b86082bd9f9b3deaafbe32b", symbol: "KDAI", coinGeckoId: "klaytn-dai", decimals: 18, price: 0.369392}, // Addr: 0x5c74070fdea071359b86082bd9f9b3deaafbe32b, Notional: 0.00738784 + {chain: 13, addr: "0000000000000000000000006270b58be569a7c0b8f47594f191631ae5b2c86c", symbol: "USDC", coinGeckoId: "usd-coin", decimals: 6, price: 0.999339}, // Addr: 0x6270b58be569a7c0b8f47594f191631ae5b2c86c, Notional: 45541.43625446464 + {chain: 13, addr: "000000000000000000000000754288077d0ff82af7a5317c7cb8c444d421d103", symbol: "oUSDC", coinGeckoId: "orbit-bridge-klaytn-usdc", decimals: 6, price: 0.294212}, // Addr: 0x754288077d0ff82af7a5317c7cb8c444d421d103, Notional: 1.2360352164639998 + {chain: 13, addr: "0000000000000000000000009eaefb09fe4aabfbe6b1ca316a3c36afc83a393f", symbol: "oXRP", coinGeckoId: "orbit-bridge-klaytn-ripple", decimals: 6, price: 2.07}, // Addr: 0x9eaefb09fe4aabfbe6b1ca316a3c36afc83a393f, Notional: 0.1035 + {chain: 13, addr: "000000000000000000000000c6a2ad8cc6e4a7e08fc37cc5954be07d499e7654", symbol: "KSP", coinGeckoId: "klayswap-protocol", decimals: 18, price: 0.159144}, // Addr: 0xc6a2ad8cc6e4a7e08fc37cc5954be07d499e7654, Notional: 0.21484440000000002 + {chain: 13, addr: "000000000000000000000000cd670d77f3dcab82d43dff9bd2c4b87339fb3560", symbol: "KOKOS", coinGeckoId: "kokonut-swap", decimals: 18, price: 0.155415}, // Addr: 0xcd670d77f3dcab82d43dff9bd2c4b87339fb3560, Notional: 1340179.404976995 + {chain: 13, addr: "000000000000000000000000ce899f5fcf55b0c1d7478910f812cfe68c5bcf0f", symbol: "ABC", coinGeckoId: "angry-bulls-club", decimals: 18, price: 0.00303528}, // Addr: 0xce899f5fcf55b0c1d7478910f812cfe68c5bcf0f, Notional: 4.3803354171638995 + {chain: 13, addr: "000000000000000000000000cee8faf64bb97a73bb51e115aa89c17ffa8dd167", symbol: "oUSDT", coinGeckoId: "orbit-bridge-klaytn-usd-tether", decimals: 6, price: 0.133103}, // Addr: 0xcee8faf64bb97a73bb51e115aa89c17ffa8dd167, Notional: 13.731106199324 + {chain: 13, addr: "000000000000000000000000d068c52d81f4409b9502da926ace3301cc41f623", symbol: "MBX", coinGeckoId: "marblex", decimals: 18, price: 0.34317}, // Addr: 0xd068c52d81f4409b9502da926ace3301cc41f623, Notional: 0.034317 + {chain: 13, addr: "000000000000000000000000e4f05a66ec68b54a58b17c22107b02e0232cc817", symbol: "WKLAY", coinGeckoId: "wrapped-klay", decimals: 18, price: 0.200032}, // Addr: 0xe4f05a66ec68b54a58b17c22107b02e0232cc817, Notional: 4740.512074064154 + {chain: 13, addr: "000000000000000000000000e950bdcfa4d1e45472e76cf967db93dbfc51ba3e", symbol: "KAI", coinGeckoId: "kai-protocol", decimals: 18, price: 0.070905}, // Addr: 0xe950bdcfa4d1e45472e76cf967db93dbfc51ba3e, Notional: 50680.82309647042 + {chain: 14, addr: "00000000000000000000000000be915b9dcf56a3cbe739d9b9c202ca692409ec", symbol: "UBE", coinGeckoId: "ubeswap", decimals: 18, price: 0.00012277}, // Addr: 0x00be915b9dcf56a3cbe739d9b9c202ca692409ec, Notional: 0.1653963245474098 + {chain: 14, addr: "0000000000000000000000002def4285787d58a2f811af24755a8150622f4361", symbol: "cETH", coinGeckoId: "weth", decimals: 18, price: 3332.06}, // Addr: 0x2def4285787d58a2f811af24755a8150622f4361, Notional: 1.5621030486 + {chain: 14, addr: "00000000000000000000000046c9757c5497c5b1f2eb73ae79b6b67d119b0b58", symbol: "PACT", coinGeckoId: "impactmarket", decimals: 18, price: 6.0239e-7}, // Addr: 0x46c9757c5497c5b1f2eb73ae79b6b67d119b0b58, Notional: 194.49903750662654 + {chain: 14, addr: "000000000000000000000000471ece3750da237f93b8e339c536989b8978a438", symbol: "CELO", coinGeckoId: "celo", decimals: 18, price: 0.639777}, // Addr: 0x471ece3750da237f93b8e339c536989b8978a438, Notional: 417979.99297391094 + {chain: 14, addr: "00000000000000000000000048065fbbe25f71c9282ddf5e1cd6d6a887483d5e", symbol: "USD₮", coinGeckoId: "tether", decimals: 6, price: 0.99789}, // Addr: 0x48065fbbe25f71c9282ddf5e1cd6d6a887483d5e, Notional: 1.86722282919 + {chain: 14, addr: "00000000000000000000000062b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a", symbol: "G$", coinGeckoId: "gooddollar", decimals: 18, price: 0.00005159}, // Addr: 0x62b8b11039fcfe5ab0c56e502b1c372a3d2a9c7a, Notional: 0.00005159 + {chain: 14, addr: "000000000000000000000000639a647fbe20b6c8ac19e48e2de44ea792c62c5c", symbol: "BIFI", coinGeckoId: "beefy-finance", decimals: 18, price: 337.37}, // Addr: 0x639a647fbe20b6c8ac19e48e2de44ea792c62c5c, Notional: 205.68686443800001 + {chain: 14, addr: "00000000000000000000000074c0c58b99b68cf16a717279ac2d056a34ba2bfe", symbol: "SOURCE", coinGeckoId: "resource-protocol", decimals: 18, price: 0.00715347}, // Addr: 0x74c0c58b99b68cf16a717279ac2d056a34ba2bfe, Notional: 0.030759921 + {chain: 14, addr: "000000000000000000000000765de816845861e75a25fca122bb6898b8b1282a", symbol: "cUSD", coinGeckoId: "celo-dollar", decimals: 18, price: 0.99402}, // Addr: 0x765de816845861e75a25fca122bb6898b8b1282a, Notional: 471.950441888484 + {chain: 14, addr: "000000000000000000000000c16b81af351ba9e64c1a069e3ab18c244a1e3049", symbol: "agEUR", coinGeckoId: "ageur", decimals: 18, price: 1.031}, // Addr: 0xc16b81af351ba9e64c1a069e3ab18c244a1e3049, Notional: 59.63935413267999 + {chain: 14, addr: "000000000000000000000000ceba9300f2b948710d2653dd7b07f33a8b32118c", symbol: "USDC", coinGeckoId: "usd-coin", decimals: 6, price: 0.999339}, // Addr: 0xceba9300f2b948710d2653dd7b07f33a8b32118c, Notional: 1015.4991750588961 + {chain: 14, addr: "000000000000000000000000d629eb00deced2a080b7ec630ef6ac117e614f1b", symbol: "BTC", coinGeckoId: "wrapped-bitcoin", decimals: 18, price: 93245}, // Addr: 0xd629eb00deced2a080b7ec630ef6ac117e614f1b, Notional: 12.028604999999999 + {chain: 14, addr: "000000000000000000000000d8763cba276a3738e6de85b4b3bf5fded6d6ca73", symbol: "cEUR", coinGeckoId: "celo-euro", decimals: 18, price: 1.033}, // Addr: 0xd8763cba276a3738e6de85b4b3bf5fded6d6ca73, Notional: 31352.313283379768 + {chain: 14, addr: "000000000000000000000000eb466342c4d449bc9f53a865d5cb90586f405215", symbol: "axlUSDC", coinGeckoId: "axlusdc", decimals: 6, price: 0.998424}, // Addr: 0xeb466342c4d449bc9f53a865d5cb90586f405215, Notional: 0.22660730316 + {chain: 15, addr: "152fd354c086478f67c36eaa07d209631825c097490fbdb38b2a9876039be6e0", symbol: "PURGE", coinGeckoId: "forgive-me-father", decimals: 18, price: 0.01067331}, // Addr: purge-558.meme-cooking.near, Notional: 2.7203485618680903 + {chain: 15, addr: "67499b7b8f58eaeb3cd81aea1d1ce9f7f722fd7750ceb2bed13e255073c25e2a", symbol: "SWEAT", coinGeckoId: "sweatcoin", decimals: 18, price: 0.00675907}, // Addr: token.sweat, Notional: 7166263.274569905 + {chain: 15, addr: "7cfae19928f9a3b68d342084a420284cb9a7984f52504300acb4e6f7f569393b", symbol: "SHITZU", coinGeckoId: "shitzu", decimals: 18, price: 0.00412827}, // Addr: token.0xshitzu.near, Notional: 0.01238481 + {chain: 15, addr: "95a38d5f6bda0f5e212cd90fd5ae1f40b3a44a1de54df58fb501266cdfc8af7b", symbol: "WALC", coinGeckoId: "walc", decimals: 24, price: 0.00539678}, // Addr: walc.near, Notional: 1619.034 + {chain: 15, addr: "9bef49ce5caa641ff4455e44855fe85a80fb71aecf70b59fc54164b309304e66", symbol: "USDC", coinGeckoId: "usd-coin", decimals: 6, price: 0.999339}, // Addr: 17208628f84f5d6ad33f0da3bbbeb27ffcb398eac501a31bd6ad2011e36133a1, Notional: 1.998577066761 + {chain: 15, addr: "b55c490bafb82aeb4b950fa479341c1b5fbfa814f8253b6acdf8426b7cd9d3c0", symbol: "wNEAR", coinGeckoId: "wrapped-near", decimals: 24, price: 4.9}, // Addr: wrap.near, Notional: 250.69682481900003 + {chain: 15, addr: "f2cc590922eb9d32267bd416a259c2944789f9eb1a6584f4b7149e0f820a237b", symbol: "SOL", coinGeckoId: "wrapped-solana", decimals: 24, price: 190.69}, // Addr: sol.token.a11bd.near, Notional: 33.1861125006 + {chain: 16, addr: "00000000000000000000000030d2a9f5fdf90ace8c17952cbb4ee48a55d916a7", symbol: "WETH", coinGeckoId: "weth", decimals: 18, price: 3332.06}, // Addr: 0x30d2a9f5fdf90ace8c17952cbb4ee48a55d916a7, Notional: 2365.7925552193997 + {chain: 16, addr: "000000000000000000000000322e86852e492a7ee17f28a78c663da38fb33bfb", symbol: "FRAX", coinGeckoId: "frax", decimals: 18, price: 0.993202}, // Addr: 0x322e86852e492a7ee17f28a78c663da38fb33bfb, Notional: 4.97594202 + {chain: 16, addr: "0000000000000000000000003405a1bd46b85c5c029483fbecf2f3e611026e45", symbol: "MATIC", coinGeckoId: "matic-network", decimals: 18, price: 0.449834}, // Addr: 0x3405a1bd46b85c5c029483fbecf2f3e611026e45, Notional: 70.49346304552245 + {chain: 16, addr: "0000000000000000000000004792c1ecb969b036eb51330c63bd27899a13d84e", symbol: "AVAX", coinGeckoId: "wrapped-avax", decimals: 18, price: 35.57}, // Addr: 0x4792c1ecb969b036eb51330c63bd27899a13d84e, Notional: 702.8944628287 + {chain: 16, addr: "000000000000000000000000511ab53f793683763e5a8829738301368a2411e3", symbol: "WELL", coinGeckoId: "moonwell-artemis", decimals: 18, price: 0.051185}, // Addr: 0x511ab53f793683763e5a8829738301368a2411e3, Notional: 3919753.99597594 + {chain: 16, addr: "000000000000000000000000765277eebeca2e31912c9946eae1021199b39c61", symbol: "DAI", coinGeckoId: "dai", decimals: 18, price: 0.99899}, // Addr: 0x765277eebeca2e31912c9946eae1021199b39c61, Notional: 23.97576 + {chain: 16, addr: "000000000000000000000000818ec0a7fe18ff94269904fced6ae3dae6d6dc0b", symbol: "USDC", coinGeckoId: "multichain-bridged-usdc-moonbeam", decimals: 6, price: 0.134078}, // Addr: 0x818ec0a7fe18ff94269904fced6ae3dae6d6dc0b, Notional: 157.4587696843 + {chain: 16, addr: "0000000000000000000000008f552a71efe5eefc207bf75485b356a0b3f01ec9", symbol: "USDC", coinGeckoId: "usd-coin", decimals: 6, price: 0.999339}, // Addr: 0x8f552a71efe5eefc207bf75485b356a0b3f01ec9, Notional: 1277.5691642164438 + {chain: 16, addr: "000000000000000000000000922d641a426dcffaef11680e5358f34d97d112e1", symbol: "WBTC", coinGeckoId: "wrapped-bitcoin", decimals: 8, price: 93245}, // Addr: 0x922d641a426dcffaef11680e5358f34d97d112e1, Notional: 1166.5993844 + {chain: 16, addr: "000000000000000000000000a423e7eeb60547d9c7b65005477b63ae7ce67e62", symbol: "EFT", coinGeckoId: "energyfi", decimals: 18, price: 0.00023377}, // Addr: 0xa423e7eeb60547d9c7b65005477b63ae7ce67e62, Notional: 5.84425 + {chain: 16, addr: "000000000000000000000000a649325aa7c5093d12d6f98eb4378deae68ce23f", symbol: "BUSD", coinGeckoId: "binance-usd", decimals: 18, price: 0.994995}, // Addr: 0xa649325aa7c5093d12d6f98eb4378deae68ce23f, Notional: 2930.6319230349623 + {chain: 16, addr: "000000000000000000000000acc15dc74880c9944775448304b263d191c6077f", symbol: "WGLMR", coinGeckoId: "wrapped-moonbeam", decimals: 18, price: 0.247854}, // Addr: 0xacc15dc74880c9944775448304b263d191c6077f, Notional: 13545.782593914302 + {chain: 16, addr: "000000000000000000000000ca01a1d0993565291051daff390892518acfad3a", symbol: "axlUSDC", coinGeckoId: "axlusdc", decimals: 6, price: 0.998424}, // Addr: 0xca01a1d0993565291051daff390892518acfad3a, Notional: 16.98319224 + {chain: 16, addr: "000000000000000000000000cd3b51d98478d53f4515a306be565c6eebef1d58", symbol: "GLINT", coinGeckoId: "beamswap", decimals: 18, price: 0.0004178}, // Addr: 0xcd3b51d98478d53f4515a306be565c6eebef1d58, Notional: 0.010445000000000001 + {chain: 16, addr: "000000000000000000000000ecf2adaff1de8a512f6e8bfe67a2c836edb25da3", symbol: "xcRMRK", coinGeckoId: "rmrk", decimals: 10, price: 0.282867}, // Addr: 0xecf2adaff1de8a512f6e8bfe67a2c836edb25da3, Notional: 0.16999022200952998 + {chain: 16, addr: "000000000000000000000000efaeee334f0fd1712f9a8cc375f427d9cdd40d73", symbol: "USDT", coinGeckoId: "tether", decimals: 6, price: 0.99789}, // Addr: 0xefaeee334f0fd1712f9a8cc375f427d9cdd40d73, Notional: 560.74881421344 + {chain: 16, addr: "000000000000000000000000fa9343c3897324496a05fc75abed6bac29f8a40f", symbol: "ETH", coinGeckoId: "weth", decimals: 18, price: 3332.06}, // Addr: 0xfa9343c3897324496a05fc75abed6bac29f8a40f, Notional: 2961.581410237 + {chain: 16, addr: "000000000000000000000000ffffffff1fcacbd218edc0eba20fc2308c778080", symbol: "xcDOT", coinGeckoId: "xcdot", decimals: 10, price: 6.61}, // Addr: 0xffffffff1fcacbd218edc0eba20fc2308c778080, Notional: 305.83230439920004 + {chain: 16, addr: "000000000000000000000000ffffffff52c56a9257bb97f4b2b6f7b2d624ecda", symbol: "xcaUSD", coinGeckoId: "acala-dollar-acala", decimals: 12, price: 0.450452}, // Addr: 0xffffffff52c56a9257bb97f4b2b6f7b2d624ecda, Notional: 15.59315016727908 + {chain: 16, addr: "000000000000000000000000ffffffffea09fb06d082fd1275cd48b191cbcd1d", symbol: "xcUSDT", coinGeckoId: "xcusdt", decimals: 6, price: 0.995363}, // Addr: 0xffffffffea09fb06d082fd1275cd48b191cbcd1d, Notional: 45.485340902757 {chain: 18, addr: "00e079a77f9591f05ef4c2208aff66d85b83afe8db60b398acc7b1277c58887e", symbol: "LunaX", coinGeckoId: "lunax", decimals: 6, price: 1.056}, // Addr: terra14xsm2wzvu7xaf567r693vgfkhmvfs08l68h4tjj5wjgyn5ky8e2qvzyanh, Notional: 1.016810784 - {chain: 18, addr: "01fa6c6fbc36d8c245b0a852a43eb5d644e8b4c477b27bfab9537c10945939da", symbol: "LUNA", coinGeckoId: "terra-luna-2", decimals: 6, price: 0.547823}, // Addr: uluna, Notional: 1477.6496432624408 - {chain: 19, addr: "017038850bf3af746c36803cce35009268f00d22ae2b55ffb59ac5f2a6add40b", symbol: "INJ", coinGeckoId: "injective-protocol", decimals: 18, price: 28.5}, // Addr: inj, Notional: 4307.988635715 - {chain: 21, addr: "01087411ef48aaac1eb6e24803213e3a60a03b147dac930e5e341f17a85e524e", symbol: "FUD", coinGeckoId: "fud-the-pug", decimals: 5, price: 2.95146e-7}, // Addr: 0x76cb819b01abed502bee8a702b4c2d547532c12f25001c9dea795a5e631c26f1::fud::FUD, Notional: 0.0000590292 - {chain: 21, addr: "3e50a0a576877092bfaa4f8e4ec8cd7dd0a4a281bec3f806583949cf7873d07b", symbol: "SUIP", coinGeckoId: "suipad", decimals: 9, price: 0.090652}, // Addr: 0xe4239cd951f6c53d9c41e25270d80d31f925ad1655e5ba5b543843d4a66975ee::SUIP::SUIP, Notional: 91219.21244542187 - {chain: 21, addr: "4c0dce55eff2db5419bbd2d239d1aa22b4a400c01bbb648b058a9883989025da", symbol: "CETUS", coinGeckoId: "cetus-protocol", decimals: 9, price: 0.3345}, // Addr: 0x6864a6f921804860930db6ddbe2e16acdf8504495ea7481637a1c8b9a8fe54b::cetus::CETUS, Notional: 0.000003906960000000001 - {chain: 21, addr: "5075594c01d46f3bcbc4a7ef1462058273bece7793eebd0464963597c9fd0935", symbol: "SPT", coinGeckoId: "seapad", decimals: 9, price: 0.054392}, // Addr: 0xb779486cfd6c19e9218cc7dc17c453014d2d9ba12d2ee4dbb0ec4e1e02ae1cca::spt::SPT, Notional: 7.954231688000001 - {chain: 21, addr: "5d26a1e9a55c88147ac870bfa31b729d7f49f8804b8b3adfdf3582d301cca844", symbol: "SCA", coinGeckoId: "scallop-2", decimals: 9, price: 0.353067}, // Addr: 0x7016aae72cfc67f2fadf55769c0a7dd54291a583b63051a5ed71081cce836ac6::sca::SCA, Notional: 33858.4949417868 - {chain: 21, addr: "9258181f5ceac8dbffb7030890243caed69a9599d2886d957a9cb7656af3bdb3", symbol: "SUI", coinGeckoId: "sui", decimals: 9, price: 3.22}, // Addr: 0x2::sui::SUI, Notional: 563622.8626315028 - {chain: 21, addr: "95a4518ae9e019c757df6703dce9ea5ecac8b319b9afed3a44c4d50363a66b42", symbol: "TURBOS", coinGeckoId: "turbos-finance", decimals: 9, price: 0.00405099}, // Addr: 0x5d1f47ea69bb0de31c313d7acf89b890dbb8991ea8e03c6c355171f84bb1ba4a::turbos::TURBOS, Notional: 215801.15460901128 - {chain: 22, addr: "0cb75f840d0b043dda136e86fb2b01415a873169531ad5be0df923c12864d9bd", symbol: "Cake", coinGeckoId: "pancakeswap-token", decimals: 8, price: 2.94}, // Addr: 0x159df6b7689437016108a019fd5bef736bac692b6d4a1f10c941f6fbb9a74ca6::oft::CakeOFT, Notional: 213.58766401140002 - {chain: 22, addr: "0d080af8d4c0959b482427505b893d59abca4d1c9670de1a1fe02dc9d7c66728", symbol: "tAPT", coinGeckoId: "tortuga-staked-aptos", decimals: 8, price: 14.16}, // Addr: 0x84d7aeef42d38a5ffc3ccef853e1b82e4958659d16a7de736a29c55fbbeb0114::staked_aptos_coin::StakedAptosCoin, Notional: 31.130632560000002 - {chain: 22, addr: "2603e2b07403ec1ff0315cbbeffac190f08a85dd61157c503c8f88efb2a7e123", symbol: "MOVE", coinGeckoId: "bluemove", decimals: 8, price: 0.086821}, // Addr: 0x27fafcc4e39daac97556af8a803dbb52bcb03f0821898dc845ac54225b9793eb::move_coin::MoveCoin, Notional: 196.0232030992163 + {chain: 18, addr: "01fa6c6fbc36d8c245b0a852a43eb5d644e8b4c477b27bfab9537c10945939da", symbol: "LUNA", coinGeckoId: "terra-luna-2", decimals: 6, price: 0.413484}, // Addr: uluna, Notional: 1132.5439091198282 + {chain: 19, addr: "017038850bf3af746c36803cce35009268f00d22ae2b55ffb59ac5f2a6add40b", symbol: "INJ", coinGeckoId: "injective-protocol", decimals: 18, price: 19.64}, // Addr: inj, Notional: 2968.7332212436 + {chain: 21, addr: "01087411ef48aaac1eb6e24803213e3a60a03b147dac930e5e341f17a85e524e", symbol: "FUD", coinGeckoId: "fud-the-pug", decimals: 5, price: 1.98475e-7}, // Addr: 0x76cb819b01abed502bee8a702b4c2d547532c12f25001c9dea795a5e631c26f1::fud::FUD, Notional: 0.000039695 + {chain: 21, addr: "3e50a0a576877092bfaa4f8e4ec8cd7dd0a4a281bec3f806583949cf7873d07b", symbol: "SUIP", coinGeckoId: "suipad", decimals: 9, price: 0.075493}, // Addr: 0xe4239cd951f6c53d9c41e25270d80d31f925ad1655e5ba5b543843d4a66975ee::SUIP::SUIP, Notional: 75322.90232691502 + {chain: 21, addr: "4c0dce55eff2db5419bbd2d239d1aa22b4a400c01bbb648b058a9883989025da", symbol: "CETUS", coinGeckoId: "cetus-protocol", decimals: 9, price: 0.28763}, // Addr: 0x6864a6f921804860930db6ddbe2e16acdf8504495ea7481637a1c8b9a8fe54b::cetus::CETUS, Notional: 0.0000033595184 + {chain: 21, addr: "5075594c01d46f3bcbc4a7ef1462058273bece7793eebd0464963597c9fd0935", symbol: "SPT", coinGeckoId: "seapad", decimals: 9, price: 0.052768}, // Addr: 0xb779486cfd6c19e9218cc7dc17c453014d2d9ba12d2ee4dbb0ec4e1e02ae1cca::spt::SPT, Notional: 7.716739552000001 + {chain: 21, addr: "5d26a1e9a55c88147ac870bfa31b729d7f49f8804b8b3adfdf3582d301cca844", symbol: "SCA", coinGeckoId: "scallop-2", decimals: 9, price: 0.266994}, // Addr: 0x7016aae72cfc67f2fadf55769c0a7dd54291a583b63051a5ed71081cce836ac6::sca::SCA, Notional: 28416.55636975718 + {chain: 21, addr: "9258181f5ceac8dbffb7030890243caed69a9599d2886d957a9cb7656af3bdb3", symbol: "SUI", coinGeckoId: "sui", decimals: 9, price: 4.13}, // Addr: 0x2::sui::SUI, Notional: 618829.8539137868 + {chain: 21, addr: "95a4518ae9e019c757df6703dce9ea5ecac8b319b9afed3a44c4d50363a66b42", symbol: "TURBOS", coinGeckoId: "turbos-finance", decimals: 9, price: 0.00307835}, // Addr: 0x5d1f47ea69bb0de31c313d7acf89b890dbb8991ea8e03c6c355171f84bb1ba4a::turbos::TURBOS, Notional: 163951.80377336746 + {chain: 22, addr: "0cb75f840d0b043dda136e86fb2b01415a873169531ad5be0df923c12864d9bd", symbol: "Cake", coinGeckoId: "pancakeswap-token", decimals: 8, price: 2.5}, // Addr: 0x159df6b7689437016108a019fd5bef736bac692b6d4a1f10c941f6fbb9a74ca6::oft::CakeOFT, Notional: 181.62216327500002 + {chain: 22, addr: "0d080af8d4c0959b482427505b893d59abca4d1c9670de1a1fe02dc9d7c66728", symbol: "tAPT", coinGeckoId: "tortuga-staked-aptos", decimals: 8, price: 9.98}, // Addr: 0x84d7aeef42d38a5ffc3ccef853e1b82e4958659d16a7de736a29c55fbbeb0114::staked_aptos_coin::StakedAptosCoin, Notional: 21.940940180000002 + {chain: 22, addr: "2603e2b07403ec1ff0315cbbeffac190f08a85dd61157c503c8f88efb2a7e123", symbol: "MOVE", coinGeckoId: "bluemove", decimals: 8, price: 0.058764}, // Addr: 0x27fafcc4e39daac97556af8a803dbb52bcb03f0821898dc845ac54225b9793eb::move_coin::MoveCoin, Notional: 132.67651267461036 {chain: 22, addr: "5a03e1706af81b4176d7a25ec23b7ce4098f79082daf20e312d4bf6e52d2e195", symbol: "SLT", coinGeckoId: "sui-launch-token", decimals: 8, price: 0.00000593}, // Addr: 0x8b2df69c9766e18486c37e3cfc53c6ce6e9aa58bbc606a8a0a219f24cf9eafc1::sui_launch_token::SuiLaunchToken, Notional: 0.19020295196120132 - {chain: 22, addr: "6155e0a106aeb3b0944388613027aee11c84921969ff775727e8046b17b17154", symbol: "USDC", coinGeckoId: "usd-coin", decimals: 6, price: 1}, // Addr: 0xf22bede237a07e121b56d91a491eb7bcdfd1f5907926a9e58338f964a01b17fa::asset::USDC, Notional: 16785.687382 - {chain: 22, addr: "61f76dbc4bdb1add1afecc1f726638bc9b5b2ac42b62f8d598b27431e5c82b7c", symbol: "GUI", coinGeckoId: "gui-inu", decimals: 6, price: 0.00002785}, // Addr: 0xe4ccb6d39136469f376242c31b34d10515c8eaaa38092f804db8e08a8f53c5b2::assets_v1::EchoCoin002, Notional: 22.7062721 - {chain: 22, addr: "8604102ac84987cb6d5e3ba0bce7530f2d9036b80752dce5202227221787957a", symbol: "APC", coinGeckoId: "apass-coin", decimals: 8, price: 0.01280341}, // Addr: 0x777821c78442e17d82c3d7a371f42de7189e4248e529fe6eee6bca40ddbb::apcoin::ApCoin, Notional: 0.032008524999999996 - {chain: 22, addr: "93601512902fe46ad6c51440c23a1a7e166c4b60e773579eda639c113a81325a", symbol: "USDT", coinGeckoId: "layerzero-bridged-usdt-aptos", decimals: 6, price: 1}, // Addr: 0xf22bede237a07e121b56d91a491eb7bcdfd1f5907926a9e58338f964a01b17fa::asset::USDT, Notional: 7273.214008 - {chain: 22, addr: "a4b99ea559e3faeb5ddaf5bf39101894d0ce210d5e79306034d031cb6ac79693", symbol: "MAU", coinGeckoId: "mau", decimals: 8, price: 0.00003726}, // Addr: 0x83b619e2d9e6e10d15ed4b714111a4cd9526c1c2ae0eec4b252a619d3e8bdda3::MAU::MAU, Notional: 0.0007452 - {chain: 22, addr: "a867703f5395cb2965feb7ebff5cdf39b771fc6156085da3ae4147a00be91b38", symbol: "APT", coinGeckoId: "aptos", decimals: 8, price: 12.52}, // Addr: 0x1::aptos_coin::AptosCoin, Notional: 293034.140808118 - {chain: 22, addr: "b029b48ea7d6c38a48a0400a156544700a9fc7ac9b82a18a3e644326177996be", symbol: "MOD", coinGeckoId: "move-dollar", decimals: 8, price: 1.002}, // Addr: 0x6f986d146e4a90b828d8c12c14b6f4e003fdff11a8eecceceb63744363eaac01::mod_coin::MOD, Notional: 1.0420800000000001 - {chain: 22, addr: "b848656c196bccfa7b9708992b6af7714afce6a56e4689da5aed63b14e99757b", symbol: "WETH", coinGeckoId: "layerzero-bridged-weth-aptos", decimals: 6, price: 3594.26}, // Addr: 0xf22bede237a07e121b56d91a491eb7bcdfd1f5907926a9e58338f964a01b17fa::asset::WETH, Notional: 31207.615326760006 - {chain: 22, addr: "c0ef1c9f58413f5fce5cf859b363b291eb43995b9e790da04afe15772f502fbf", symbol: "ANI", coinGeckoId: "animeswap", decimals: 8, price: 0.00098118}, // Addr: 0x16fe2df00ea7dde4a63409201f7f4e536bde7bb7335526a35d05111e68aa322c::AnimeCoin::ANI, Notional: 1.6941901093803755 - {chain: 22, addr: "d64be880bc9b995c0028588e916e21e7e796ae5cf32cac551edeaf95f2f9fdbd", symbol: "doodoo", coinGeckoId: "doodoo", decimals: 8, price: 0.341423}, // Addr: 0x73eb84966be67e4697fc5ae75173ca6c35089e802650f75422ab49a8729704ec::coin::DooDoo, Notional: 1546613.5186915854 - {chain: 22, addr: "eb1cbad587018a828b7e2d49456ed3e96d01baa8f7590723c558fecdfdffe842", symbol: "ALT", coinGeckoId: "aptos-launch-token", decimals: 8, price: 0.01556757}, // Addr: 0xd0b4efb4be7c3508d9a26a9b5405cf9f860d0b9e5fe2f498b90e68b8d2cedd3e::aptos_launch_token::AptosLaunchToken, Notional: 0.20238502621725 - {chain: 22, addr: "ec43792d3639b37cfcf7a3381d4fd71e2a7c75e708a518970eb0d475a03097cf", symbol: "BNB", coinGeckoId: "wrapped-bnb-celer", decimals: 8, price: 559.35}, // Addr: 0x8d87a65ba30e09357fa2edea2c80dbac296e5dec2b18287113500b902942929d::celer_coin_manager::BnbCoin, Notional: 26.993039584500004 - {chain: 22, addr: "f7835a613217e1b032007d111c9d34db23cf5f976e27e1afda8b97c3e35df17b", symbol: "WETH", coinGeckoId: "wrapped-ether-celer", decimals: 8, price: 3620.28}, // Addr: 0x8d87a65ba30e09357fa2edea2c80dbac296e5dec2b18287113500b902942929d::celer_coin_manager::WethCoin, Notional: 111.0349650756 + {chain: 22, addr: "6155e0a106aeb3b0944388613027aee11c84921969ff775727e8046b17b17154", symbol: "USDC", coinGeckoId: "usd-coin", decimals: 6, price: 0.999339}, // Addr: 0xf22bede237a07e121b56d91a491eb7bcdfd1f5907926a9e58338f964a01b17fa::asset::USDC, Notional: 16787.210157549776 + {chain: 22, addr: "61f76dbc4bdb1add1afecc1f726638bc9b5b2ac42b62f8d598b27431e5c82b7c", symbol: "GUI", coinGeckoId: "gui-inu", decimals: 6, price: 0.0000246}, // Addr: 0xe4ccb6d39136469f376242c31b34d10515c8eaaa38092f804db8e08a8f53c5b2::assets_v1::EchoCoin002, Notional: 20.056527600000003 + {chain: 22, addr: "69e4491bcf06bae41346240afbdab99cdbe40b38d2bb22eb1cf9b4a4d9e635f8", symbol: "MBX", coinGeckoId: "marblex", decimals: 8, price: 0.34317}, // Addr: 0x665d06fcd9c94430099f82973f2a5e5f13142e42fa172e72ce14f51a64bd8ad9::coin_mbx::MBX, Notional: 0.08602783569089999 + {chain: 22, addr: "8604102ac84987cb6d5e3ba0bce7530f2d9036b80752dce5202227221787957a", symbol: "APC", coinGeckoId: "apass-coin", decimals: 8, price: 0.0095959}, // Addr: 0x777821c78442e17d82c3d7a371f42de7189e4248e529fe6eee6bca40ddbb::apcoin::ApCoin, Notional: 0.023989749999999997 + {chain: 22, addr: "93601512902fe46ad6c51440c23a1a7e166c4b60e773579eda639c113a81325a", symbol: "USDT", coinGeckoId: "layerzero-bridged-usdt-aptos", decimals: 6, price: 0.997339}, // Addr: 0xf22bede237a07e121b56d91a491eb7bcdfd1f5907926a9e58338f964a01b17fa::asset::USDT, Notional: 7253.859985524712 + {chain: 22, addr: "a4b99ea559e3faeb5ddaf5bf39101894d0ce210d5e79306034d031cb6ac79693", symbol: "MAU", coinGeckoId: "mau", decimals: 8, price: 0.0000304}, // Addr: 0x83b619e2d9e6e10d15ed4b714111a4cd9526c1c2ae0eec4b252a619d3e8bdda3::MAU::MAU, Notional: 0.000608 + {chain: 22, addr: "a867703f5395cb2965feb7ebff5cdf39b771fc6156085da3ae4147a00be91b38", symbol: "APT", coinGeckoId: "aptos", decimals: 8, price: 8.69}, // Addr: 0x1::aptos_coin::AptosCoin, Notional: 232777.0731259259 + {chain: 22, addr: "b029b48ea7d6c38a48a0400a156544700a9fc7ac9b82a18a3e644326177996be", symbol: "MOD", coinGeckoId: "move-dollar", decimals: 8, price: 0.999624}, // Addr: 0x6f986d146e4a90b828d8c12c14b6f4e003fdff11a8eecceceb63744363eaac01::mod_coin::MOD, Notional: 1.03960896 + {chain: 22, addr: "b848656c196bccfa7b9708992b6af7714afce6a56e4689da5aed63b14e99757b", symbol: "WETH", coinGeckoId: "layerzero-bridged-weth-aptos", decimals: 6, price: 3329.07}, // Addr: 0xf22bede237a07e121b56d91a491eb7bcdfd1f5907926a9e58338f964a01b17fa::asset::WETH, Notional: 29063.866376820002 + {chain: 22, addr: "c0ef1c9f58413f5fce5cf859b363b291eb43995b9e790da04afe15772f502fbf", symbol: "ANI", coinGeckoId: "animeswap", decimals: 8, price: 0.0006402}, // Addr: 0x16fe2df00ea7dde4a63409201f7f4e536bde7bb7335526a35d05111e68aa322c::AnimeCoin::ANI, Notional: 1.105424598978084 + {chain: 22, addr: "d64be880bc9b995c0028588e916e21e7e796ae5cf32cac551edeaf95f2f9fdbd", symbol: "doodoo", coinGeckoId: "doodoo", decimals: 8, price: 0.243577}, // Addr: 0x73eb84966be67e4697fc5ae75173ca6c35089e802650f75422ab49a8729704ec::coin::DooDoo, Notional: 1104444.855229138 + {chain: 22, addr: "eb1cbad587018a828b7e2d49456ed3e96d01baa8f7590723c558fecdfdffe842", symbol: "ALT", coinGeckoId: "aptos-launch-token", decimals: 8, price: 0.01177689}, // Addr: 0xd0b4efb4be7c3508d9a26a9b5405cf9f860d0b9e5fe2f498b90e68b8d2cedd3e::aptos_launch_token::AptosLaunchToken, Notional: 0.15310457517825 + {chain: 22, addr: "ec43792d3639b37cfcf7a3381d4fd71e2a7c75e708a518970eb0d475a03097cf", symbol: "BNB", coinGeckoId: "wrapped-bnb-celer", decimals: 8, price: 456.75}, // Addr: 0x8d87a65ba30e09357fa2edea2c80dbac296e5dec2b18287113500b902942929d::celer_coin_manager::BnbCoin, Notional: 22.0417821225 + {chain: 22, addr: "f7835a613217e1b032007d111c9d34db23cf5f976e27e1afda8b97c3e35df17b", symbol: "WETH", coinGeckoId: "wrapped-ether-celer", decimals: 8, price: 3312.5}, // Addr: 0x8d87a65ba30e09357fa2edea2c80dbac296e5dec2b18287113500b902942929d::celer_coin_manager::WethCoin, Notional: 101.595269375 {chain: 23, addr: "00000000000000000000000009090e22118b375f2c7b95420c04414e4bf68e1a", symbol: "BELA", coinGeckoId: "beluga-protocol", decimals: 18, price: 0.00000568}, // Addr: 0x09090e22118b375f2c7b95420c04414e4bf68e1a, Notional: 0.0005679999999999999 - {chain: 23, addr: "00000000000000000000000009e18590e8f76b6cf471b3cd75fe1a1a9d2b2c2b", symbol: "AIDOGE", coinGeckoId: "arbdoge-ai", decimals: 6, price: 3.53354e-10}, // Addr: 0x09e18590e8f76b6cf471b3cd75fe1a1a9d2b2c2b, Notional: 3.5335400000000003e-7 - {chain: 23, addr: "00000000000000000000000009fd3d6e6889940ca1158b9221309bd69fafa32b", symbol: "DROP", coinGeckoId: "droparb", decimals: 18, price: 3.0148e-11}, // Addr: 0x09fd3d6e6889940ca1158b9221309bd69fafa32b, Notional: 0.038424298222785556 - {chain: 23, addr: "0000000000000000000000000c880f6761f1af8d9aa9c466984b80dab9a8c9e8", symbol: "PENDLE", coinGeckoId: "pendle", decimals: 18, price: 5.52}, // Addr: 0x0c880f6761f1af8d9aa9c466984b80dab9a8c9e8, Notional: 33.12 - {chain: 23, addr: "00000000000000000000000010393c20975cf177a3513071bc110f7962cd67da", symbol: "JONES", coinGeckoId: "jones-dao", decimals: 18, price: 0.168608}, // Addr: 0x10393c20975cf177a3513071bc110f7962cd67da, Notional: 0.0015851765424000001 - {chain: 23, addr: "00000000000000000000000013a7dedb7169a17be92b0e3c7c2315b46f4772b3", symbol: "Boop", coinGeckoId: "boop-2", decimals: 18, price: 0.00011928}, // Addr: 0x13a7dedb7169a17be92b0e3c7c2315b46f4772b3, Notional: 78199.73345842853 - {chain: 23, addr: "00000000000000000000000016f1967565aad72dd77588a332ce445e7cef752b", symbol: "CAW", coinGeckoId: "crow-with-knife", decimals: 0, price: 3.9789e-8}, // Addr: 0x16f1967565aad72dd77588a332ce445e7cef752b, Notional: 636596.0064575649 - {chain: 23, addr: "00000000000000000000000018c11fd286c5ec11c3b683caa813b77f5163a122", symbol: "GNS", coinGeckoId: "gains-network", decimals: 18, price: 2.47}, // Addr: 0x18c11fd286c5ec11c3b683caa813b77f5163a122, Notional: 0.8024698032 - {chain: 23, addr: "000000000000000000000000191c10aa4af7c30e871e70c95db0e4eb77237530", symbol: "aArbLINK", coinGeckoId: "aave-v3-link", decimals: 18, price: 19.86}, // Addr: 0x191c10aa4af7c30e871e70c95db0e4eb77237530, Notional: 1.7743615128 - {chain: 23, addr: "0000000000000000000000001b896893dfc86bb67cf57767298b9073d2c1ba2c", symbol: "Cake", coinGeckoId: "pancakeswap-token", decimals: 18, price: 2.94}, // Addr: 0x1b896893dfc86bb67cf57767298b9073d2c1ba2c, Notional: 9.906467592 - {chain: 23, addr: "0000000000000000000000002297aebd383787a160dd0d9f71508148769342e3", symbol: "BTC.b", coinGeckoId: "bitcoin-avalanche-bridged-btc-b", decimals: 8, price: 94905}, // Addr: 0x2297aebd383787a160dd0d9f71508148769342e3, Notional: 681.6172005000001 - {chain: 23, addr: "00000000000000000000000024ef78c7092d255ed14a0281ac1800c359af3afe", symbol: "RAB", coinGeckoId: "rabbit-wallet", decimals: 18, price: 0.00343975}, // Addr: 0x24ef78c7092d255ed14a0281ac1800c359af3afe, Notional: 0.0343975 - {chain: 23, addr: "0000000000000000000000002598c30330d5771ae9f983979209486ae26de875", symbol: "AI", coinGeckoId: "any-inu", decimals: 18, price: 0.00000789}, // Addr: 0x2598c30330d5771ae9f983979209486ae26de875, Notional: 5.569055679667543 - {chain: 23, addr: "00000000000000000000000025d887ce7a35172c62febfd67a1856f20faebb00", symbol: "PEPE", coinGeckoId: "pepe", decimals: 18, price: 0.00002001}, // Addr: 0x25d887ce7a35172c62febfd67a1856f20faebb00, Notional: 0.00002001 - {chain: 23, addr: "000000000000000000000000289ba1701c2f088cf0faf8b3705246331cb8a839", symbol: "LPT", coinGeckoId: "livepeer", decimals: 18, price: 14.79}, // Addr: 0x289ba1701c2f088cf0faf8b3705246331cb8a839, Notional: 2187.9614982581998 - {chain: 23, addr: "0000000000000000000000002f2a2543b76a4166549f7aab2e75bef0aefc5b0f", symbol: "WBTC", coinGeckoId: "wrapped-bitcoin", decimals: 8, price: 94688}, // Addr: 0x2f2a2543b76a4166549f7aab2e75bef0aefc5b0f, Notional: 469.226384 - {chain: 23, addr: "0000000000000000000000003082cc23568ea640225c2467653db90e9250aaa0", symbol: "RDNT", coinGeckoId: "radiant-capital", decimals: 18, price: 0.083389}, // Addr: 0x3082cc23568ea640225c2467653db90e9250aaa0, Notional: 0.591394788 - {chain: 23, addr: "0000000000000000000000003269a3c00ab86c753856fd135d97b87facb0d848", symbol: "FFM", coinGeckoId: "florence-finance-medici", decimals: 18, price: 0.03034738}, // Addr: 0x3269a3c00ab86c753856fd135d97b87facb0d848, Notional: 523407.98602184246 - {chain: 23, addr: "000000000000000000000000371c7ec6d8039ff7933a2aa28eb827ffe1f52f07", symbol: "JOE", coinGeckoId: "joe", decimals: 18, price: 0.530655}, // Addr: 0x371c7ec6d8039ff7933a2aa28eb827ffe1f52f07, Notional: 998.8165740573314 - {chain: 23, addr: "0000000000000000000000003b475f6f2f41853706afc9fa6a6b8c5df1a2724c", symbol: "ZYB", coinGeckoId: "zyberswap", decimals: 18, price: 0.00598693}, // Addr: 0x3b475f6f2f41853706afc9fa6a6b8c5df1a2724c, Notional: 0.02993465 - {chain: 23, addr: "0000000000000000000000004186bfc76e2e237523cbc30fd220fe055156b41f", symbol: "rsETH", coinGeckoId: "kelpdao-bridged-rseth-arbitrum", decimals: 18, price: 3700.16}, // Addr: 0x4186bfc76e2e237523cbc30fd220fe055156b41f, Notional: 0.23129700159999997 - {chain: 23, addr: "00000000000000000000000042069d11a2cc72388a2e06210921e839cfbd3280", symbol: "GNOME", coinGeckoId: "gnomeland", decimals: 18, price: 0.00033993}, // Addr: 0x42069d11a2cc72388a2e06210921e839cfbd3280, Notional: 0.0033993 - {chain: 23, addr: "0000000000000000000000004425742f1ec8d98779690b5a3a6276db85ddc01a", symbol: "DOG", coinGeckoId: "the-doge-nft", decimals: 18, price: 0.00464939}, // Addr: 0x4425742f1ec8d98779690b5a3a6276db85ddc01a, Notional: 0.9525068432626081 - {chain: 23, addr: "00000000000000000000000046f74778b265df3a15ec9695ccd2fd3869ca848c", symbol: "ANKR", coinGeckoId: "ankr", decimals: 18, price: 0.04128546}, // Addr: 0x46f74778b265df3a15ec9695ccd2fd3869ca848c, Notional: 6481.776752593638 - {chain: 23, addr: "0000000000000000000000004d15a3a2286d883af0aa1b3f21367843fac63e07", symbol: "TUSD", coinGeckoId: "true-usd", decimals: 18, price: 1.001}, // Addr: 0x4d15a3a2286d883af0aa1b3f21367843fac63e07, Notional: 11.011 - {chain: 23, addr: "000000000000000000000000509fd25ee2ac7833a017f17ee8a6fb4aaf947876", symbol: "mWOM", coinGeckoId: "magpie-wom", decimals: 18, price: 0.00992145}, // Addr: 0x509fd25ee2ac7833a017f17ee8a6fb4aaf947876, Notional: 0.10620302651112 - {chain: 23, addr: "00000000000000000000000051318b7d00db7acc4026c88c3952b66278b6a67f", symbol: "PLS", coinGeckoId: "plutusdao", decimals: 18, price: 0.03699248}, // Addr: 0x51318b7d00db7acc4026c88c3952b66278b6a67f, Notional: 0.0031716124201664 - {chain: 23, addr: "00000000000000000000000051b902f19a56f0c8e409a34a215ad2673edf3284", symbol: "NFTE", coinGeckoId: "nftearth", decimals: 18, price: 0.00005538}, // Addr: 0x51b902f19a56f0c8e409a34a215ad2673edf3284, Notional: 0.0221936422638606 - {chain: 23, addr: "00000000000000000000000051fc0f6660482ea73330e414efd7808811a57fa2", symbol: "PREMIA", coinGeckoId: "premia", decimals: 18, price: 0.150244}, // Addr: 0x51fc0f6660482ea73330e414efd7808811a57fa2, Notional: 0.70563596889756 - {chain: 23, addr: "000000000000000000000000539bde0d7dbd336b79148aa742883198bbf60342", symbol: "MAGIC", coinGeckoId: "magic", decimals: 18, price: 0.541671}, // Addr: 0x539bde0d7dbd336b79148aa742883198bbf60342, Notional: 8.08336327180551 + {chain: 23, addr: "00000000000000000000000009e18590e8f76b6cf471b3cd75fe1a1a9d2b2c2b", symbol: "AIDOGE", coinGeckoId: "arbdoge-ai", decimals: 6, price: 2.59792e-10}, // Addr: 0x09e18590e8f76b6cf471b3cd75fe1a1a9d2b2c2b, Notional: 2.5979200000000003e-7 + {chain: 23, addr: "00000000000000000000000009fd3d6e6889940ca1158b9221309bd69fafa32b", symbol: "DROP", coinGeckoId: "droparb", decimals: 18, price: 2.7103e-11}, // Addr: 0x09fd3d6e6889940ca1158b9221309bd69fafa32b, Notional: 0.034543377827124744 + {chain: 23, addr: "0000000000000000000000000c880f6761f1af8d9aa9c466984b80dab9a8c9e8", symbol: "PENDLE", coinGeckoId: "pendle", decimals: 18, price: 4.86}, // Addr: 0x0c880f6761f1af8d9aa9c466984b80dab9a8c9e8, Notional: 29.160000000000004 + {chain: 23, addr: "00000000000000000000000010393c20975cf177a3513071bc110f7962cd67da", symbol: "JONES", coinGeckoId: "jones-dao", decimals: 18, price: 0.178249}, // Addr: 0x10393c20975cf177a3513071bc110f7962cd67da, Notional: 0.0016758168859499999 + {chain: 23, addr: "00000000000000000000000013a7dedb7169a17be92b0e3c7c2315b46f4772b3", symbol: "Boop", coinGeckoId: "boop-2", decimals: 18, price: 0.00010767}, // Addr: 0x13a7dedb7169a17be92b0e3c7c2315b46f4772b3, Notional: 70428.85958999289 + {chain: 23, addr: "00000000000000000000000016f1967565aad72dd77588a332ce445e7cef752b", symbol: "CAW", coinGeckoId: "crow-with-knife", decimals: 0, price: 3.6612e-8}, // Addr: 0x16f1967565aad72dd77588a332ce445e7cef752b, Notional: 564607.5828445087 + {chain: 23, addr: "00000000000000000000000018c11fd286c5ec11c3b683caa813b77f5163a122", symbol: "GNS", coinGeckoId: "gains-network", decimals: 18, price: 1.79}, // Addr: 0x18c11fd286c5ec11c3b683caa813b77f5163a122, Notional: 0.5815469424 + {chain: 23, addr: "000000000000000000000000191c10aa4af7c30e871e70c95db0e4eb77237530", symbol: "aArbLINK", coinGeckoId: "aave-v3-link", decimals: 18, price: 19.83}, // Addr: 0x191c10aa4af7c30e871e70c95db0e4eb77237530, Notional: 1.7716812084 + {chain: 23, addr: "0000000000000000000000001b896893dfc86bb67cf57767298b9073d2c1ba2c", symbol: "Cake", coinGeckoId: "pancakeswap-token", decimals: 18, price: 2.5}, // Addr: 0x1b896893dfc86bb67cf57767298b9073d2c1ba2c, Notional: 8.423867000000001 + {chain: 23, addr: "0000000000000000000000002297aebd383787a160dd0d9f71508148769342e3", symbol: "BTC.b", coinGeckoId: "bitcoin-avalanche-bridged-btc-b", decimals: 8, price: 93213}, // Addr: 0x2297aebd383787a160dd0d9f71508148769342e3, Notional: 669.4650873 + {chain: 23, addr: "00000000000000000000000024ef78c7092d255ed14a0281ac1800c359af3afe", symbol: "RAB", coinGeckoId: "rabbit-wallet", decimals: 18, price: 0.00283092}, // Addr: 0x24ef78c7092d255ed14a0281ac1800c359af3afe, Notional: 0.0283092 + {chain: 23, addr: "0000000000000000000000002598c30330d5771ae9f983979209486ae26de875", symbol: "AI", coinGeckoId: "any-inu", decimals: 18, price: 0.00000937}, // Addr: 0x2598c30330d5771ae9f983979209486ae26de875, Notional: 6.613694767868806 + {chain: 23, addr: "00000000000000000000000025d887ce7a35172c62febfd67a1856f20faebb00", symbol: "PEPE", coinGeckoId: "pepe", decimals: 18, price: 0.00001994}, // Addr: 0x25d887ce7a35172c62febfd67a1856f20faebb00, Notional: 0.00001994 + {chain: 23, addr: "000000000000000000000000289ba1701c2f088cf0faf8b3705246331cb8a839", symbol: "LPT", coinGeckoId: "livepeer", decimals: 18, price: 14.88}, // Addr: 0x289ba1701c2f088cf0faf8b3705246331cb8a839, Notional: 2201.2756655904004 + {chain: 23, addr: "0000000000000000000000002f2a2543b76a4166549f7aab2e75bef0aefc5b0f", symbol: "WBTC", coinGeckoId: "wrapped-bitcoin", decimals: 8, price: 93245}, // Addr: 0x2f2a2543b76a4166549f7aab2e75bef0aefc5b0f, Notional: 462.07559749999996 + {chain: 23, addr: "0000000000000000000000003082cc23568ea640225c2467653db90e9250aaa0", symbol: "RDNT", coinGeckoId: "radiant-capital", decimals: 18, price: 0.057654}, // Addr: 0x3082cc23568ea640225c2467653db90e9250aaa0, Notional: 0.40888216799999993 + {chain: 23, addr: "0000000000000000000000003269a3c00ab86c753856fd135d97b87facb0d848", symbol: "FFM", coinGeckoId: "florence-finance-medici", decimals: 18, price: 0.02385667}, // Addr: 0x3269a3c00ab86c753856fd135d97b87facb0d848, Notional: 412107.9722097304 + {chain: 23, addr: "000000000000000000000000371c7ec6d8039ff7933a2aa28eb827ffe1f52f07", symbol: "JOE", coinGeckoId: "joe", decimals: 18, price: 0.363725}, // Addr: 0x371c7ec6d8039ff7933a2aa28eb827ffe1f52f07, Notional: 684.6153497074425 + {chain: 23, addr: "0000000000000000000000003b475f6f2f41853706afc9fa6a6b8c5df1a2724c", symbol: "ZYB", coinGeckoId: "zyberswap", decimals: 18, price: 0.00820192}, // Addr: 0x3b475f6f2f41853706afc9fa6a6b8c5df1a2724c, Notional: 0.0410096 + {chain: 23, addr: "0000000000000000000000004186bfc76e2e237523cbc30fd220fe055156b41f", symbol: "rsETH", coinGeckoId: "kelpdao-bridged-rseth-arbitrum", decimals: 18, price: 3436.66}, // Addr: 0x4186bfc76e2e237523cbc30fd220fe055156b41f, Notional: 0.2148256166 + {chain: 23, addr: "00000000000000000000000042069d11a2cc72388a2e06210921e839cfbd3280", symbol: "GNOME", coinGeckoId: "gnomeland", decimals: 18, price: 0.00022658}, // Addr: 0x42069d11a2cc72388a2e06210921e839cfbd3280, Notional: 0.0022658 + {chain: 23, addr: "0000000000000000000000004425742f1ec8d98779690b5a3a6276db85ddc01a", symbol: "DOG", coinGeckoId: "the-doge-nft", decimals: 18, price: 0.00399146}, // Addr: 0x4425742f1ec8d98779690b5a3a6276db85ddc01a, Notional: 0.8177186608585147 + {chain: 23, addr: "00000000000000000000000046f74778b265df3a15ec9695ccd2fd3869ca848c", symbol: "ANKR", coinGeckoId: "ankr", decimals: 18, price: 0.03341542}, // Addr: 0x46f74778b265df3a15ec9695ccd2fd3869ca848c, Notional: 5246.1881866921785 + {chain: 23, addr: "0000000000000000000000004d15a3a2286d883af0aa1b3f21367843fac63e07", symbol: "TUSD", coinGeckoId: "true-usd", decimals: 18, price: 0.996888}, // Addr: 0x4d15a3a2286d883af0aa1b3f21367843fac63e07, Notional: 10.965768 + {chain: 23, addr: "000000000000000000000000509fd25ee2ac7833a017f17ee8a6fb4aaf947876", symbol: "mWOM", coinGeckoId: "magpie-wom", decimals: 18, price: 0.00668389}, // Addr: 0x509fd25ee2ac7833a017f17ee8a6fb4aaf947876, Notional: 0.072534806789316 + {chain: 23, addr: "00000000000000000000000051318b7d00db7acc4026c88c3952b66278b6a67f", symbol: "PLS", coinGeckoId: "plutusdao", decimals: 18, price: 0.02939263}, // Addr: 0x51318b7d00db7acc4026c88c3952b66278b6a67f, Notional: 0.0025200265126684 + {chain: 23, addr: "00000000000000000000000051b902f19a56f0c8e409a34a215ad2673edf3284", symbol: "NFTE", coinGeckoId: "nftearth", decimals: 18, price: 0.00001848}, // Addr: 0x51b902f19a56f0c8e409a34a215ad2673edf3284, Notional: 0.0074058957933576 + {chain: 23, addr: "00000000000000000000000051fc0f6660482ea73330e414efd7808811a57fa2", symbol: "PREMIA", coinGeckoId: "premia", decimals: 18, price: 0.14606}, // Addr: 0x51fc0f6660482ea73330e414efd7808811a57fa2, Notional: 0.6859853945394 + {chain: 23, addr: "000000000000000000000000539bde0d7dbd336b79148aa742883198bbf60342", symbol: "MAGIC", coinGeckoId: "magic", decimals: 18, price: 0.42161}, // Addr: 0x539bde0d7dbd336b79148aa742883198bbf60342, Notional: 6.291691430824099 {chain: 23, addr: "00000000000000000000000057f12fe6a4e5fe819eec699fadf9db2d06606bb4", symbol: "NPM", coinGeckoId: "neptune-mutual", decimals: 18, price: 0.04894073}, // Addr: 0x57f12fe6a4e5fe819eec699fadf9db2d06606bb4, Notional: 0.04894073 - {chain: 23, addr: "000000000000000000000000580e933d90091b9ce380740e3a4a39c67eb85b4c", symbol: "GSWIFT", coinGeckoId: "gameswift", decimals: 18, price: 0.103286}, // Addr: 0x580e933d90091b9ce380740e3a4a39c67eb85b4c, Notional: 0.5164300000000001 - {chain: 23, addr: "0000000000000000000000005979d7b546e38e414f7e9822514be443a4800529", symbol: "wstETH", coinGeckoId: "wrapped-steth", decimals: 18, price: 4258.57}, // Addr: 0x5979d7b546e38e414f7e9822514be443a4800529, Notional: 81.1080002631 - {chain: 23, addr: "000000000000000000000000625e7708f30ca75bfd92586e17077590c60eb4cd", symbol: "aArbUSDC", coinGeckoId: "aave-usdc", decimals: 6, price: 1}, // Addr: 0x625e7708f30ca75bfd92586e17077590c60eb4cd, Notional: 0.01 - {chain: 23, addr: "0000000000000000000000006694340fc020c5e6b96567843da2df01b2ce1eb6", symbol: "STG", coinGeckoId: "stargate-finance", decimals: 18, price: 0.382194}, // Addr: 0x6694340fc020c5e6b96567843da2df01b2ce1eb6, Notional: 51.87494138994431 - {chain: 23, addr: "00000000000000000000000068ead55c258d6fa5e46d67fc90f53211eab885be", symbol: "POP", coinGeckoId: "popcorn", decimals: 18, price: 0.00944086}, // Addr: 0x68ead55c258d6fa5e46d67fc90f53211eab885be, Notional: 0.9854323522020407 - {chain: 23, addr: "0000000000000000000000006c2c06790b3e3e3c38e12ee22f8183b37a13ee55", symbol: "DPX", coinGeckoId: "dopex", decimals: 18, price: 10.95}, // Addr: 0x6c2c06790b3e3e3c38e12ee22f8183b37a13ee55, Notional: 0.0012214724999999999 - {chain: 23, addr: "0000000000000000000000006c84a8f1c29108f47a79964b5fe888d4f4d0de40", symbol: "tBTC", coinGeckoId: "tbtc", decimals: 18, price: 94760}, // Addr: 0x6c84a8f1c29108f47a79964b5fe888d4f4d0de40, Notional: 161.5714856 - {chain: 23, addr: "0000000000000000000000006fd58f5a2f3468e35feb098b5f59f04157002407", symbol: "pogai", coinGeckoId: "pogai", decimals: 18, price: 0.00001937}, // Addr: 0x6fd58f5a2f3468e35feb098b5f59f04157002407, Notional: 0.129779 - {chain: 23, addr: "0000000000000000000000007f7d7806f4eb90d63b0b278daf32a2db2c2001bd", symbol: "BONUS", coinGeckoId: "bonusblock", decimals: 18, price: 0.03243182}, // Addr: 0x7f7d7806f4eb90d63b0b278daf32a2db2c2001bd, Notional: 4270.952464776909 - {chain: 23, addr: "00000000000000000000000082af49447d8a07e3bd95bd0d56f35241523fbab1", symbol: "WETH", coinGeckoId: "weth", decimals: 18, price: 3594.89}, // Addr: 0x82af49447d8a07e3bd95bd0d56f35241523fbab1, Notional: 361792.5230092745 - {chain: 23, addr: "000000000000000000000000847503fbf003ce8b005546aa3c03b80b7c2f9771", symbol: "BYTE", coinGeckoId: "byte", decimals: 9, price: 0.00001164}, // Addr: 0x847503fbf003ce8b005546aa3c03b80b7c2f9771, Notional: 410.2919281797665 - {chain: 23, addr: "000000000000000000000000894134a25a5fac1c2c26f1d8fbf05111a3cb9487", symbol: "GRAI", coinGeckoId: "grai", decimals: 18, price: 0.964356}, // Addr: 0x894134a25a5fac1c2c26f1d8fbf05111a3cb9487, Notional: 0.2893068 - {chain: 23, addr: "000000000000000000000000912ce59144191c1204e64559fe8253a0e49e6548", symbol: "ARB", coinGeckoId: "arbitrum", decimals: 18, price: 0.915552}, // Addr: 0x912ce59144191c1204e64559fe8253a0e49e6548, Notional: 92413.21324066997 - {chain: 23, addr: "000000000000000000000000921f99719eb6c01b4b8f0ba7973a7c24891e740a", symbol: "XCAD", coinGeckoId: "xcad-network", decimals: 18, price: 0.437693}, // Addr: 0x921f99719eb6c01b4b8f0ba7973a7c24891e740a, Notional: 36.048628341429854 - {chain: 23, addr: "0000000000000000000000009623063377ad1b27544c965ccd7342f7ea7e88c7", symbol: "GRT", coinGeckoId: "the-graph", decimals: 18, price: 0.272962}, // Addr: 0x9623063377ad1b27544c965ccd7342f7ea7e88c7, Notional: 304.79328403465206 - {chain: 23, addr: "00000000000000000000000099c409e5f62e4bd2ac142f17cafb6810b8f0baae", symbol: "BIFI", coinGeckoId: "beefy-finance", decimals: 18, price: 332.12}, // Addr: 0x99c409e5f62e4bd2ac142f17cafb6810b8f0baae, Notional: 928.2106997028 - {chain: 23, addr: "0000000000000000000000009d2f299715d94d8a7e6f5eaa8e654e8c74a988a7", symbol: "FXS", coinGeckoId: "frax-share", decimals: 18, price: 3.57}, // Addr: 0x9d2f299715d94d8a7e6f5eaa8e654e8c74a988a7, Notional: 8.9828728773 - {chain: 23, addr: "0000000000000000000000009dce8e754913d928eb39bc4fc3cf047e364f7f2c", symbol: "BLOK", coinGeckoId: "bloktopia", decimals: 18, price: 0.00084917}, // Addr: 0x9dce8e754913d928eb39bc4fc3cf047e364f7f2c, Notional: 4.52862361 - {chain: 23, addr: "0000000000000000000000009e20461bc2c4c980f62f1b279d71734207a6a356", symbol: "OMNI", coinGeckoId: "omnicat", decimals: 18, price: 0.00004722}, // Addr: 0x9e20461bc2c4c980f62f1b279d71734207a6a356, Notional: 50.08141885659903 - {chain: 23, addr: "000000000000000000000000a684cd057951541187f288294a1e1c2646aa2d24", symbol: "VSTA", coinGeckoId: "vesta-finance", decimals: 18, price: 0.169467}, // Addr: 0xa684cd057951541187f288294a1e1c2646aa2d24, Notional: 0.00911246767578 - {chain: 23, addr: "000000000000000000000000aa54e84a3e6e5a80288d2c2f8e36ea5ca3a3ca30", symbol: "$SHARBI", coinGeckoId: "sharbi", decimals: 9, price: 0.00000545}, // Addr: 0xaa54e84a3e6e5a80288d2c2f8e36ea5ca3a3ca30, Notional: 0.000014987500000000002 - {chain: 23, addr: "000000000000000000000000af88d065e77c8cc2239327c5edb3a432268e5831", symbol: "USDC", coinGeckoId: "usd-coin", decimals: 6, price: 1}, // Addr: 0xaf88d065e77c8cc2239327c5edb3a432268e5831, Notional: 882634.86029 - {chain: 23, addr: "000000000000000000000000b0ffa8000886e57f86dd5264b9582b2ad87b2b91", symbol: "W", coinGeckoId: "wormhole", decimals: 18, price: 0.318945}, // Addr: 0xb0ffa8000886e57f86dd5264b9582b2ad87b2b91, Notional: 200187.75199468053 - {chain: 23, addr: "000000000000000000000000b261104a83887ae92392fb5ce5899fcfe5481456", symbol: "NFTE", coinGeckoId: "nftearth", decimals: 18, price: 0.00005538}, // Addr: 0xb261104a83887ae92392fb5ce5899fcfe5481456, Notional: 0.0005538 - {chain: 23, addr: "000000000000000000000000b6093b61544572ab42a0e43af08abafd41bf25a6", symbol: "WXM", coinGeckoId: "weatherxm-network", decimals: 18, price: 0.637603}, // Addr: 0xb6093b61544572ab42a0e43af08abafd41bf25a6, Notional: 637.6030000000001 + {chain: 23, addr: "000000000000000000000000580e933d90091b9ce380740e3a4a39c67eb85b4c", symbol: "GSWIFT", coinGeckoId: "gameswift", decimals: 18, price: 0.061269}, // Addr: 0x580e933d90091b9ce380740e3a4a39c67eb85b4c, Notional: 0.306345 + {chain: 23, addr: "0000000000000000000000005979d7b546e38e414f7e9822514be443a4800529", symbol: "wstETH", coinGeckoId: "wrapped-steth", decimals: 18, price: 3961.06}, // Addr: 0x5979d7b546e38e414f7e9822514be443a4800529, Notional: 75.4416753798 + {chain: 23, addr: "000000000000000000000000625e7708f30ca75bfd92586e17077590c60eb4cd", symbol: "aArbUSDC", coinGeckoId: "aave-usdc", decimals: 6, price: 0.99928}, // Addr: 0x625e7708f30ca75bfd92586e17077590c60eb4cd, Notional: 0.0099928 + {chain: 23, addr: "0000000000000000000000006694340fc020c5e6b96567843da2df01b2ce1eb6", symbol: "STG", coinGeckoId: "stargate-finance", decimals: 18, price: 0.36685}, // Addr: 0x6694340fc020c5e6b96567843da2df01b2ce1eb6, Notional: 49.792310315967995 + {chain: 23, addr: "00000000000000000000000068ead55c258d6fa5e46d67fc90f53211eab885be", symbol: "POP", coinGeckoId: "popcorn", decimals: 18, price: 0.00909501}, // Addr: 0x68ead55c258d6fa5e46d67fc90f53211eab885be, Notional: 0.9493326982500622 + {chain: 23, addr: "0000000000000000000000006c2c06790b3e3e3c38e12ee22f8183b37a13ee55", symbol: "DPX", coinGeckoId: "dopex", decimals: 18, price: 18.11}, // Addr: 0x6c2c06790b3e3e3c38e12ee22f8183b37a13ee55, Notional: 0.0020201705 + {chain: 23, addr: "0000000000000000000000006c84a8f1c29108f47a79964b5fe888d4f4d0de40", symbol: "tBTC", coinGeckoId: "tbtc", decimals: 18, price: 93127}, // Addr: 0x6c84a8f1c29108f47a79964b5fe888d4f4d0de40, Notional: 158.78712262 + {chain: 23, addr: "0000000000000000000000006fd58f5a2f3468e35feb098b5f59f04157002407", symbol: "pogai", coinGeckoId: "pogai", decimals: 18, price: 0.00001459}, // Addr: 0x6fd58f5a2f3468e35feb098b5f59f04157002407, Notional: 0.09775299999999999 + {chain: 23, addr: "0000000000000000000000007f7d7806f4eb90d63b0b278daf32a2db2c2001bd", symbol: "BONUS", coinGeckoId: "bonusblock", decimals: 18, price: 0.03134957}, // Addr: 0x7f7d7806f4eb90d63b0b278daf32a2db2c2001bd, Notional: 4128.430759087719 + {chain: 23, addr: "00000000000000000000000082af49447d8a07e3bd95bd0d56f35241523fbab1", symbol: "WETH", coinGeckoId: "weth", decimals: 18, price: 3332.06}, // Addr: 0x82af49447d8a07e3bd95bd0d56f35241523fbab1, Notional: 325694.11730244 + {chain: 23, addr: "000000000000000000000000847503fbf003ce8b005546aa3c03b80b7c2f9771", symbol: "BYTE", coinGeckoId: "byte", decimals: 9, price: 0.00000631}, // Addr: 0x847503fbf003ce8b005546aa3c03b80b7c2f9771, Notional: 222.41770333456412 + {chain: 23, addr: "00000000000000000000000088266f9eb705f5282a2507a9c418821a2ac9f8bd", symbol: "NCASH", coinGeckoId: "nutcash", decimals: 18, price: 0.0152364}, // Addr: 0x88266f9eb705f5282a2507a9c418821a2ac9f8bd, Notional: 17379.505453110276 + {chain: 23, addr: "000000000000000000000000894134a25a5fac1c2c26f1d8fbf05111a3cb9487", symbol: "GRAI", coinGeckoId: "grai", decimals: 18, price: 0.985824}, // Addr: 0x894134a25a5fac1c2c26f1d8fbf05111a3cb9487, Notional: 0.2957472 + {chain: 23, addr: "000000000000000000000000912ce59144191c1204e64559fe8253a0e49e6548", symbol: "ARB", coinGeckoId: "arbitrum", decimals: 18, price: 0.721497}, // Addr: 0x912ce59144191c1204e64559fe8253a0e49e6548, Notional: 70940.9675510017 + {chain: 23, addr: "000000000000000000000000921f99719eb6c01b4b8f0ba7973a7c24891e740a", symbol: "XCAD", coinGeckoId: "xcad-network", decimals: 18, price: 0.247048}, // Addr: 0x921f99719eb6c01b4b8f0ba7973a7c24891e740a, Notional: 20.347004714476956 + {chain: 23, addr: "0000000000000000000000009623063377ad1b27544c965ccd7342f7ea7e88c7", symbol: "GRT", coinGeckoId: "the-graph", decimals: 18, price: 0.199064}, // Addr: 0x9623063377ad1b27544c965ccd7342f7ea7e88c7, Notional: 222.27771738584119 + {chain: 23, addr: "00000000000000000000000099c409e5f62e4bd2ac142f17cafb6810b8f0baae", symbol: "BIFI", coinGeckoId: "beefy-finance", decimals: 18, price: 337.37}, // Addr: 0x99c409e5f62e4bd2ac142f17cafb6810b8f0baae, Notional: 942.8834269503 + {chain: 23, addr: "0000000000000000000000009d2f299715d94d8a7e6f5eaa8e654e8c74a988a7", symbol: "FXS", coinGeckoId: "frax-share", decimals: 18, price: 3.49}, // Addr: 0x9d2f299715d94d8a7e6f5eaa8e654e8c74a988a7, Notional: 8.7815760061 + {chain: 23, addr: "0000000000000000000000009dce8e754913d928eb39bc4fc3cf047e364f7f2c", symbol: "BLOK", coinGeckoId: "bloktopia", decimals: 18, price: 0.00067727}, // Addr: 0x9dce8e754913d928eb39bc4fc3cf047e364f7f2c, Notional: 3.61188091 + {chain: 23, addr: "0000000000000000000000009e20461bc2c4c980f62f1b279d71734207a6a356", symbol: "OMNI", coinGeckoId: "omnicat", decimals: 18, price: 0.00002616}, // Addr: 0x9e20461bc2c4c980f62f1b279d71734207a6a356, Notional: 27.745233318268333 + {chain: 23, addr: "000000000000000000000000a684cd057951541187f288294a1e1c2646aa2d24", symbol: "VSTA", coinGeckoId: "vesta-finance", decimals: 18, price: 0.051561}, // Addr: 0xa684cd057951541187f288294a1e1c2646aa2d24, Notional: 0.00277250406174 + {chain: 23, addr: "000000000000000000000000aa54e84a3e6e5a80288d2c2f8e36ea5ca3a3ca30", symbol: "$SHARBI", coinGeckoId: "sharbi", decimals: 9, price: 0.00000532}, // Addr: 0xaa54e84a3e6e5a80288d2c2f8e36ea5ca3a3ca30, Notional: 0.00001463 + {chain: 23, addr: "000000000000000000000000af88d065e77c8cc2239327c5edb3a432268e5831", symbol: "USDC", coinGeckoId: "usd-coin", decimals: 6, price: 0.999339}, // Addr: 0xaf88d065e77c8cc2239327c5edb3a432268e5831, Notional: 1310828.615049079 + {chain: 23, addr: "000000000000000000000000b0ffa8000886e57f86dd5264b9582b2ad87b2b91", symbol: "W", coinGeckoId: "wormhole", decimals: 18, price: 0.284654}, // Addr: 0xb0ffa8000886e57f86dd5264b9582b2ad87b2b91, Notional: 170148.8887007849 + {chain: 23, addr: "000000000000000000000000b261104a83887ae92392fb5ce5899fcfe5481456", symbol: "NFTE", coinGeckoId: "nftearth", decimals: 18, price: 0.00001848}, // Addr: 0xb261104a83887ae92392fb5ce5899fcfe5481456, Notional: 0.0001848 + {chain: 23, addr: "000000000000000000000000b6093b61544572ab42a0e43af08abafd41bf25a6", symbol: "WXM", coinGeckoId: "weatherxm-network", decimals: 18, price: 0.491216}, // Addr: 0xb6093b61544572ab42a0e43af08abafd41bf25a6, Notional: 491.216 {chain: 23, addr: "000000000000000000000000b827710314a05bcbee9180e11c2abe5823289422", symbol: "ABI", coinGeckoId: "abachi-2", decimals: 18, price: 0.960946}, // Addr: 0xb827710314a05bcbee9180e11c2abe5823289422, Notional: 0.960946 - {chain: 23, addr: "000000000000000000000000b9af4762c039d63e30039f1712dfab77026408c7", symbol: "AIBB", coinGeckoId: "bullbear-ai", decimals: 18, price: 1.29571e-10}, // Addr: 0xb9af4762c039d63e30039f1712dfab77026408c7, Notional: 1.29571e-9 - {chain: 23, addr: "000000000000000000000000ba0dda8762c24da9487f5fa026a9b64b695a07ea", symbol: "OX", coinGeckoId: "ox-fun", decimals: 18, price: 0.02629672}, // Addr: 0xba0dda8762c24da9487f5fa026a9b64b695a07ea, Notional: 1152039.883173162 - {chain: 23, addr: "000000000000000000000000bfbcfe8873fe28dfa25f1099282b088d52bbad9c", symbol: "EQB", coinGeckoId: "equilibria-finance", decimals: 18, price: 0.386239}, // Addr: 0xbfbcfe8873fe28dfa25f1099282b088d52bbad9c, Notional: 90.54309431479054 - {chain: 23, addr: "000000000000000000000000c3abc47863524ced8daf3ef98d74dd881e131c38", symbol: "LUA", coinGeckoId: "lumi-finance", decimals: 18, price: 3.6}, // Addr: 0xc3abc47863524ced8daf3ef98d74dd881e131c38, Notional: 1104712.27806942 + {chain: 23, addr: "000000000000000000000000b9af4762c039d63e30039f1712dfab77026408c7", symbol: "AIBB", coinGeckoId: "bullbear-ai", decimals: 18, price: 1.11715e-10}, // Addr: 0xb9af4762c039d63e30039f1712dfab77026408c7, Notional: 1.11715e-9 + {chain: 23, addr: "000000000000000000000000ba0dda8762c24da9487f5fa026a9b64b695a07ea", symbol: "OX", coinGeckoId: "ox-fun", decimals: 18, price: 0.02482136}, // Addr: 0xba0dda8762c24da9487f5fa026a9b64b695a07ea, Notional: 1219454.480956781 + {chain: 23, addr: "000000000000000000000000bfbcfe8873fe28dfa25f1099282b088d52bbad9c", symbol: "EQB", coinGeckoId: "equilibria-finance", decimals: 18, price: 0.356325}, // Addr: 0xbfbcfe8873fe28dfa25f1099282b088d52bbad9c, Notional: 83.53058101775775 + {chain: 23, addr: "000000000000000000000000c3abc47863524ced8daf3ef98d74dd881e131c38", symbol: "LUA", coinGeckoId: "lumi-finance", decimals: 18, price: 2.84}, // Addr: 0xc3abc47863524ced8daf3ef98d74dd881e131c38, Notional: 843870.561588098 {chain: 23, addr: "000000000000000000000000c628534100180582e43271448098cb2c185795bd", symbol: "FLASH", coinGeckoId: "flash-stake", decimals: 18, price: 0.00650277}, // Addr: 0xc628534100180582e43271448098cb2c185795bd, Notional: 3.3615650033012283 - {chain: 23, addr: "000000000000000000000000d56734d7f9979dd94fae3d67c7e928234e71cd4c", symbol: "TIA.n", coinGeckoId: "bridged-tia-hyperlane", decimals: 6, price: 7.4}, // Addr: 0xd56734d7f9979dd94fae3d67c7e928234e71cd4c, Notional: 11.138783400000001 - {chain: 23, addr: "000000000000000000000000d5a56b510247db33695b0bea29992ac6670081ea", symbol: "GOB", coinGeckoId: "goons-of-balatroon", decimals: 18, price: 0.00075293}, // Addr: 0xd5a56b510247db33695b0bea29992ac6670081ea, Notional: 6.52263259 - {chain: 23, addr: "000000000000000000000000d77b108d4f6cefaa0cae9506a934e825becca46e", symbol: "WINR", coinGeckoId: "winr-protocol", decimals: 18, price: 0.04216733}, // Addr: 0xd77b108d4f6cefaa0cae9506a934e825becca46e, Notional: 388854.8520221225 - {chain: 23, addr: "000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1", symbol: "DAI", coinGeckoId: "dai", decimals: 18, price: 1}, // Addr: 0xda10009cbd5d07dd0cecc66161fc93d7c9000da1, Notional: 1620.55680977 + {chain: 23, addr: "000000000000000000000000d56734d7f9979dd94fae3d67c7e928234e71cd4c", symbol: "TIA.n", coinGeckoId: "bridged-tia-hyperlane", decimals: 6, price: 4.61}, // Addr: 0xd56734d7f9979dd94fae3d67c7e928234e71cd4c, Notional: 6.93916101 + {chain: 23, addr: "000000000000000000000000d5a56b510247db33695b0bea29992ac6670081ea", symbol: "GOB", coinGeckoId: "goons-of-balatroon", decimals: 18, price: 0.00080626}, // Addr: 0xd5a56b510247db33695b0bea29992ac6670081ea, Notional: 6.9846303800000005 + {chain: 23, addr: "000000000000000000000000d77b108d4f6cefaa0cae9506a934e825becca46e", symbol: "WINR", coinGeckoId: "winr-protocol", decimals: 18, price: 0.04712303}, // Addr: 0xd77b108d4f6cefaa0cae9506a934e825becca46e, Notional: 481680.38022086344 + {chain: 23, addr: "000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1", symbol: "DAI", coinGeckoId: "dai", decimals: 18, price: 0.99899}, // Addr: 0xda10009cbd5d07dd0cecc66161fc93d7c9000da1, Notional: 1618.9200473921323 {chain: 23, addr: "000000000000000000000000db13df2ea134e7df2208d74b96db063837db5b5c", symbol: "LAMB", coinGeckoId: "lamb-by-opnx", decimals: 18, price: 0.0104436}, // Addr: 0xdb13df2ea134e7df2208d74b96db063837db5b5c, Notional: 1733636.626466932 - {chain: 23, addr: "000000000000000000000000de903e2712288a1da82942dddf2c20529565ac30", symbol: "SWPR", coinGeckoId: "swapr", decimals: 18, price: 0.00479927}, // Addr: 0xde903e2712288a1da82942dddf2c20529565ac30, Notional: 0.15837590999999998 - {chain: 23, addr: "000000000000000000000000dfb8be6f8c87f74295a87de951974362cedcfa30", symbol: "EMC", coinGeckoId: "edge-matrix-computing", decimals: 18, price: 0.068622}, // Addr: 0xdfb8be6f8c87f74295a87de951974362cedcfa30, Notional: 0.1990038 - {chain: 23, addr: "000000000000000000000000e6045890b20945d00e6f3c01878265c03c5435d3", symbol: "IDIA", coinGeckoId: "idia", decimals: 18, price: 0.04861188}, // Addr: 0xe6045890b20945d00e6f3c01878265c03c5435d3, Notional: 41241.408499917874 - {chain: 23, addr: "000000000000000000000000f8388c2b6edf00e2e27eef5200b1befb24ce141d", symbol: "NOLA", coinGeckoId: "nola", decimals: 18, price: 0.00012228}, // Addr: 0xf8388c2b6edf00e2e27eef5200b1befb24ce141d, Notional: 3.404897332584077 - {chain: 23, addr: "000000000000000000000000f97f4df75117a78c1a5a0dbb814af92458539fb4", symbol: "LINK", coinGeckoId: "chainlink", decimals: 18, price: 19.89}, // Addr: 0xf97f4df75117a78c1a5a0dbb814af92458539fb4, Notional: 283.7225142999 - {chain: 23, addr: "000000000000000000000000fa5ed56a203466cbbc2430a43c66b9d8723528e7", symbol: "EURA", coinGeckoId: "ageur", decimals: 18, price: 1.046}, // Addr: 0xfa5ed56a203466cbbc2430a43c66b9d8723528e7, Notional: 46.3657427917 - {chain: 23, addr: "000000000000000000000000fa7f8980b0f1e64a2062791cc3b0871572f1f7f0", symbol: "UNI", coinGeckoId: "uniswap", decimals: 18, price: 14.02}, // Addr: 0xfa7f8980b0f1e64a2062791cc3b0871572f1f7f0, Notional: 11.1227044708 - {chain: 23, addr: "000000000000000000000000fd086bc7cd5c481dcc9c85ebe478a1c0b69fcbb9", symbol: "USDT", coinGeckoId: "tether", decimals: 6, price: 1}, // Addr: 0xfd086bc7cd5c481dcc9c85ebe478a1c0b69fcbb9, Notional: 51345.546806 - {chain: 23, addr: "000000000000000000000000fea7a6a0b346362bf88a9e4a88416b77a57d6c2a", symbol: "MIM", coinGeckoId: "magic-internet-money", decimals: 18, price: 0.99491}, // Addr: 0xfea7a6a0b346362bf88a9e4a88416b77a57d6c2a, Notional: 0.0009949000509 - {chain: 23, addr: "000000000000000000000000ff970a61a04b1ca14834a43f5de4533ebddb5cc8", symbol: "USDC", coinGeckoId: "usd-coin", decimals: 6, price: 1}, // Addr: 0xff970a61a04b1ca14834a43f5de4533ebddb5cc8, Notional: 3000814.481373 - {chain: 24, addr: "0000000000000000000000000b2c639c533813f4aa9d7837caf62653d097ff85", symbol: "USDC", coinGeckoId: "usd-coin", decimals: 6, price: 1}, // Addr: 0x0b2c639c533813f4aa9d7837caf62653d097ff85, Notional: 1070588.134778 - {chain: 24, addr: "000000000000000000000000135c78d7f52aab6e9f17bcf4a9e8627aa233d050", symbol: "BOO", coinGeckoId: "boo-2", decimals: 18, price: 0.00005478}, // Addr: 0x135c78d7f52aab6e9f17bcf4a9e8627aa233d050, Notional: 6.852322915336602 - {chain: 24, addr: "00000000000000000000000014778860e937f509e651192a90589de711fb88a9", symbol: "CYBER", coinGeckoId: "cyberconnect", decimals: 18, price: 4.62}, // Addr: 0x14778860e937f509e651192a90589de711fb88a9, Notional: 26.4213030312 - {chain: 24, addr: "0000000000000000000000001f32b1c2345538c0c6f582fcb022739c4a194ebb", symbol: "wstETH", coinGeckoId: "wrapped-steth", decimals: 18, price: 4258.57}, // Addr: 0x1f32b1c2345538c0c6f582fcb022739c4a194ebb, Notional: 21445.4670134034 - {chain: 24, addr: "000000000000000000000000296f55f8fb28e498b858d0bcda06d955b2cb3f97", symbol: "STG", coinGeckoId: "stargate-finance", decimals: 18, price: 0.382194}, // Addr: 0x296f55f8fb28e498b858d0bcda06d955b2cb3f97, Notional: 131.44814147003308 - {chain: 24, addr: "0000000000000000000000002dad3a13ef0c6366220f989157009e501e7938f8", symbol: "EXTRA", coinGeckoId: "extra-finance", decimals: 18, price: 0.086038}, // Addr: 0x2dad3a13ef0c6366220f989157009e501e7938f8, Notional: 0.037664862143040004 - {chain: 24, addr: "0000000000000000000000002e3d870790dc77a83dd1d18184acc7439a53f475", symbol: "FRAX", coinGeckoId: "frax", decimals: 18, price: 0.996303}, // Addr: 0x2e3d870790dc77a83dd1d18184acc7439a53f475, Notional: 0.000316824354 - {chain: 24, addr: "000000000000000000000000323665443cef804a3b5206103304bd4872ea4253", symbol: "USDV", coinGeckoId: "verified-usd-foundation-usdv", decimals: 6, price: 0.999897}, // Addr: 0x323665443cef804a3b5206103304bd4872ea4253, Notional: 223.819909174605 - {chain: 24, addr: "000000000000000000000000375488f097176507e39b9653b88fdc52cde736bf", symbol: "TAROT", coinGeckoId: "tarot", decimals: 18, price: 0.00265829}, // Addr: 0x375488f097176507e39b9653b88fdc52cde736bf, Notional: 0.020814852959707298 - {chain: 24, addr: "0000000000000000000000003ed9acaac7bd974eb83a8ea6432a239e3c829d5d", symbol: "2192", coinGeckoId: "lernitas", decimals: 18, price: 0.00002042}, // Addr: 0x3ed9acaac7bd974eb83a8ea6432a239e3c829d5d, Notional: 952.4794281586935 - {chain: 24, addr: "0000000000000000000000004200000000000000000000000000000000000006", symbol: "WETH", coinGeckoId: "weth", decimals: 18, price: 3594.89}, // Addr: 0x4200000000000000000000000000000000000006, Notional: 58695.66209907399 - {chain: 24, addr: "0000000000000000000000004200000000000000000000000000000000000042", symbol: "OP", coinGeckoId: "optimism", decimals: 18, price: 2.34}, // Addr: 0x4200000000000000000000000000000000000042, Notional: 101600.05321900979 - {chain: 24, addr: "00000000000000000000000042069d11a2cc72388a2e06210921e839cfbd3280", symbol: "GNOME", coinGeckoId: "gnomeland", decimals: 18, price: 0.00033993}, // Addr: 0x42069d11a2cc72388a2e06210921e839cfbd3280, Notional: 0.67986 - {chain: 24, addr: "00000000000000000000000048a9f8b4b65a55cc46ea557a610acf227454ab09", symbol: "OPC", coinGeckoId: "op-chads", decimals: 18, price: 0.0000785}, // Addr: 0x48a9f8b4b65a55cc46ea557a610acf227454ab09, Notional: 25.083575976760862 - {chain: 24, addr: "00000000000000000000000050bce64397c75488465253c0a034b8097fea6578", symbol: "HAN", coinGeckoId: "hanchain", decimals: 18, price: 0.0066998}, // Addr: 0x50bce64397c75488465253c0a034b8097fea6578, Notional: 0.0066998 - {chain: 24, addr: "000000000000000000000000528cdc92eab044e1e39fe43b9514bfdab4412b98", symbol: "GIV", coinGeckoId: "giveth", decimals: 18, price: 0.00751451}, // Addr: 0x528cdc92eab044e1e39fe43b9514bfdab4412b98, Notional: 27792.33487776478 - {chain: 24, addr: "000000000000000000000000625e7708f30ca75bfd92586e17077590c60eb4cd", symbol: "aOptUSDC", coinGeckoId: "aave-usdc", decimals: 6, price: 1}, // Addr: 0x625e7708f30ca75bfd92586e17077590c60eb4cd, Notional: 6.607176 - {chain: 24, addr: "00000000000000000000000068f180fcce6836688e9084f035309e29bf0a2095", symbol: "WBTC", coinGeckoId: "wrapped-bitcoin", decimals: 8, price: 94688}, // Addr: 0x68f180fcce6836688e9084f035309e29bf0a2095, Notional: 26593.665468479998 - {chain: 24, addr: "0000000000000000000000006d80113e533a2c0fe82eabd35f1875dcea89ea97", symbol: "aOptSUSD", coinGeckoId: "aave-susd", decimals: 18, price: 1.003}, // Addr: 0x6d80113e533a2c0fe82eabd35f1875dcea89ea97, Notional: 16.749577246429997 - {chain: 24, addr: "0000000000000000000000006f620ec89b8479e97a6985792d0c64f237566746", symbol: "WPC", coinGeckoId: "wepiggy-coin", decimals: 18, price: 0.00006026}, // Addr: 0x6f620ec89b8479e97a6985792d0c64f237566746, Notional: 0.00940056 - {chain: 24, addr: "00000000000000000000000074ccbe53f77b08632ce0cb91d3a545bf6b8e0979", symbol: "fBOMB", coinGeckoId: "fbomb", decimals: 18, price: 0.0499864}, // Addr: 0x74ccbe53f77b08632ce0cb91d3a545bf6b8e0979, Notional: 2.4743268 - {chain: 24, addr: "0000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c31607", symbol: "USDC", coinGeckoId: "usd-coin", decimals: 6, price: 1}, // Addr: 0x7f5c764cbc14f9669b88837ca1490cca17c31607, Notional: 472004.911878 - {chain: 24, addr: "00000000000000000000000081ab7e0d570b01411fcc4afd3d50ec8c241cb74b", symbol: "EQZ", coinGeckoId: "equalizer", decimals: 18, price: 0.00368382}, // Addr: 0x81ab7e0d570b01411fcc4afd3d50ec8c241cb74b, Notional: 0.368382 - {chain: 24, addr: "0000000000000000000000008b21e9b7daf2c4325bf3d18c1beb79a347fe902a", symbol: "COLLAB", coinGeckoId: "collab-land", decimals: 18, price: 0.00089998}, // Addr: 0x8b21e9b7daf2c4325bf3d18c1beb79a347fe902a, Notional: 0.140640603943792 - {chain: 24, addr: "0000000000000000000000008c6f28f2f1a3c87f0f938b96d27520d9751ec8d9", symbol: "sUSD", coinGeckoId: "nusd", decimals: 18, price: 0.994271}, // Addr: 0x8c6f28f2f1a3c87f0f938b96d27520d9751ec8d9, Notional: 1.94216294659541 - {chain: 24, addr: "00000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58", symbol: "USDT", coinGeckoId: "tether", decimals: 6, price: 1}, // Addr: 0x94b008aa00579c1307b0ef2c499ad98a8ce58e58, Notional: 178376.451211 - {chain: 24, addr: "0000000000000000000000009e1028f5f1d5ede59748ffcee5532509976840e0", symbol: "PERP", coinGeckoId: "perpetual-protocol", decimals: 18, price: 0.920039}, // Addr: 0x9e1028f5f1d5ede59748ffcee5532509976840e0, Notional: 0.22019686243653 - {chain: 24, addr: "000000000000000000000000c26921b5b9ee80773774d36c84328ccb22c3a819", symbol: "wOptiDoge", coinGeckoId: "wrapped-optidoge", decimals: 18, price: 0.00000155}, // Addr: 0xc26921b5b9ee80773774d36c84328ccb22c3a819, Notional: 19.2263054 - {chain: 24, addr: "000000000000000000000000c40f949f8a4e094d1b49a23ea9241d289b7b2819", symbol: "LUSD", coinGeckoId: "liquity-usd", decimals: 18, price: 0.997951}, // Addr: 0xc40f949f8a4e094d1b49a23ea9241d289b7b2819, Notional: 1.0977461e-7 - {chain: 24, addr: "000000000000000000000000c5102fe9359fd9a28f877a67e36b0f050d81a3cc", symbol: "HOP", coinGeckoId: "hop-protocol", decimals: 18, price: 0.01973637}, // Addr: 0xc5102fe9359fd9a28f877a67e36b0f050d81a3cc, Notional: 0.836431592077728 - {chain: 24, addr: "000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1", symbol: "DAI", coinGeckoId: "dai", decimals: 18, price: 1}, // Addr: 0xda10009cbd5d07dd0cecc66161fc93d7c9000da1, Notional: 165.13442927 - {chain: 24, addr: "000000000000000000000000dfa46478f9e5ea86d57387849598dbfb2e964b02", symbol: "MAI", coinGeckoId: "mimatic", decimals: 18, price: 0.993831}, // Addr: 0xdfa46478f9e5ea86d57387849598dbfb2e964b02, Notional: 4.969155 - {chain: 24, addr: "000000000000000000000000e453d6649643f1f460c371dc3d1da98f7922fe51", symbol: "FUSE", coinGeckoId: "fuse-network-token", decimals: 18, price: 0.03470058}, // Addr: 0xe453d6649643f1f460c371dc3d1da98f7922fe51, Notional: 0.0340065684 - {chain: 24, addr: "000000000000000000000000e50fa9b3c56ffb159cb0fca61f5c9d750e8128c8", symbol: "aOptWETH", coinGeckoId: "aave-weth", decimals: 18, price: 3590.67}, // Addr: 0xe50fa9b3c56ffb159cb0fca61f5c9d750e8128c8, Notional: 0.0001077201 - {chain: 24, addr: "000000000000000000000000fd389dc9533717239856190f42475d3f263a270d", symbol: "GRAIN", coinGeckoId: "granary", decimals: 18, price: 0.00412269}, // Addr: 0xfd389dc9533717239856190f42475d3f263a270d, Notional: 0.11955801 + {chain: 23, addr: "000000000000000000000000de903e2712288a1da82942dddf2c20529565ac30", symbol: "SWPR", coinGeckoId: "swapr", decimals: 18, price: 0.00400866}, // Addr: 0xde903e2712288a1da82942dddf2c20529565ac30, Notional: 0.13228578 + {chain: 23, addr: "000000000000000000000000dfb8be6f8c87f74295a87de951974362cedcfa30", symbol: "EMC", coinGeckoId: "edge-matrix-computing", decimals: 18, price: 0.04277964}, // Addr: 0xdfb8be6f8c87f74295a87de951974362cedcfa30, Notional: 0.124060956 + {chain: 23, addr: "000000000000000000000000e6045890b20945d00e6f3c01878265c03c5435d3", symbol: "IDIA", coinGeckoId: "idia", decimals: 18, price: 0.059907}, // Addr: 0xe6045890b20945d00e6f3c01878265c03c5435d3, Notional: 50823.97675227907 + {chain: 23, addr: "000000000000000000000000f8388c2b6edf00e2e27eef5200b1befb24ce141d", symbol: "NOLA", coinGeckoId: "nola", decimals: 18, price: 0.00000311}, // Addr: 0xf8388c2b6edf00e2e27eef5200b1befb24ce141d, Notional: 0.0865982229664416 + {chain: 23, addr: "000000000000000000000000f97f4df75117a78c1a5a0dbb814af92458539fb4", symbol: "LINK", coinGeckoId: "chainlink", decimals: 18, price: 19.87}, // Addr: 0xf97f4df75117a78c1a5a0dbb814af92458539fb4, Notional: 283.4372226817 + {chain: 23, addr: "000000000000000000000000fa5ed56a203466cbbc2430a43c66b9d8723528e7", symbol: "EURA", coinGeckoId: "ageur", decimals: 18, price: 1.031}, // Addr: 0xfa5ed56a203466cbbc2430a43c66b9d8723528e7, Notional: 45.700842082449995 + {chain: 23, addr: "000000000000000000000000fa7f8980b0f1e64a2062791cc3b0871572f1f7f0", symbol: "UNI", coinGeckoId: "uniswap", decimals: 18, price: 13.19}, // Addr: 0xfa7f8980b0f1e64a2062791cc3b0871572f1f7f0, Notional: 10.4642276726 + {chain: 23, addr: "000000000000000000000000fd086bc7cd5c481dcc9c85ebe478a1c0b69fcbb9", symbol: "USDT", coinGeckoId: "tether", decimals: 6, price: 0.99789}, // Addr: 0xfd086bc7cd5c481dcc9c85ebe478a1c0b69fcbb9, Notional: 50779.60068766012 + {chain: 23, addr: "000000000000000000000000fea7a6a0b346362bf88a9e4a88416b77a57d6c2a", symbol: "MIM", coinGeckoId: "magic-internet-money", decimals: 18, price: 0.994109}, // Addr: 0xfea7a6a0b346362bf88a9e4a88416b77a57d6c2a, Notional: 0.0009940990589100002 + {chain: 23, addr: "000000000000000000000000ff970a61a04b1ca14834a43f5de4533ebddb5cc8", symbol: "USDC", coinGeckoId: "usd-coin", decimals: 6, price: 0.999339}, // Addr: 0xff970a61a04b1ca14834a43f5de4533ebddb5cc8, Notional: 2847006.3915065615 + {chain: 24, addr: "0000000000000000000000000b2c639c533813f4aa9d7837caf62653d097ff85", symbol: "USDC", coinGeckoId: "usd-coin", decimals: 6, price: 0.999339}, // Addr: 0x0b2c639c533813f4aa9d7837caf62653d097ff85, Notional: 1289452.9428570557 + {chain: 24, addr: "000000000000000000000000135c78d7f52aab6e9f17bcf4a9e8627aa233d050", symbol: "BOO", coinGeckoId: "boo-2", decimals: 18, price: 0.00005436}, // Addr: 0x135c78d7f52aab6e9f17bcf4a9e8627aa233d050, Notional: 6.799785937891524 + {chain: 24, addr: "00000000000000000000000014778860e937f509e651192a90589de711fb88a9", symbol: "CYBER", coinGeckoId: "cyberconnect", decimals: 18, price: 3.2}, // Addr: 0x14778860e937f509e651192a90589de711fb88a9, Notional: 18.300469632 + {chain: 24, addr: "0000000000000000000000001f32b1c2345538c0c6f582fcb022739c4a194ebb", symbol: "wstETH", coinGeckoId: "wrapped-steth", decimals: 18, price: 3961.06}, // Addr: 0x1f32b1c2345538c0c6f582fcb022739c4a194ebb, Notional: 29975.4585630654 + {chain: 24, addr: "000000000000000000000000296f55f8fb28e498b858d0bcda06d955b2cb3f97", symbol: "STG", coinGeckoId: "stargate-finance", decimals: 18, price: 0.36685}, // Addr: 0x296f55f8fb28e498b858d0bcda06d955b2cb3f97, Notional: 201.2489267646275 + {chain: 24, addr: "0000000000000000000000002dad3a13ef0c6366220f989157009e501e7938f8", symbol: "EXTRA", coinGeckoId: "extra-finance", decimals: 18, price: 0.068267}, // Addr: 0x2dad3a13ef0c6366220f989157009e501e7938f8, Notional: 0.029885250051359998 + {chain: 24, addr: "0000000000000000000000002e3d870790dc77a83dd1d18184acc7439a53f475", symbol: "FRAX", coinGeckoId: "frax", decimals: 18, price: 0.993202}, // Addr: 0x2e3d870790dc77a83dd1d18184acc7439a53f475, Notional: 0.000315838236 + {chain: 24, addr: "000000000000000000000000323665443cef804a3b5206103304bd4872ea4253", symbol: "USDV", coinGeckoId: "verified-usd-foundation-usdv", decimals: 6, price: 0.994502}, // Addr: 0x323665443cef804a3b5206103304bd4872ea4253, Notional: 222.61227637842998 + {chain: 24, addr: "000000000000000000000000375488f097176507e39b9653b88fdc52cde736bf", symbol: "TAROT", coinGeckoId: "tarot", decimals: 18, price: 0.00160227}, // Addr: 0x375488f097176507e39b9653b88fdc52cde736bf, Notional: 0.0125460406696599 + {chain: 24, addr: "0000000000000000000000003ed9acaac7bd974eb83a8ea6432a239e3c829d5d", symbol: "2192", coinGeckoId: "lernitas", decimals: 18, price: 0.00001304}, // Addr: 0x3ed9acaac7bd974eb83a8ea6432a239e3c829d5d, Notional: 608.1732361241582 + {chain: 24, addr: "0000000000000000000000004200000000000000000000000000000000000006", symbol: "WETH", coinGeckoId: "weth", decimals: 18, price: 3332.06}, // Addr: 0x4200000000000000000000000000000000000006, Notional: 51232.3376681262 + {chain: 24, addr: "0000000000000000000000004200000000000000000000000000000000000042", symbol: "OP", coinGeckoId: "optimism", decimals: 18, price: 1.74}, // Addr: 0x4200000000000000000000000000000000000042, Notional: 73585.0813103436 + {chain: 24, addr: "00000000000000000000000042069d11a2cc72388a2e06210921e839cfbd3280", symbol: "GNOME", coinGeckoId: "gnomeland", decimals: 18, price: 0.00022658}, // Addr: 0x42069d11a2cc72388a2e06210921e839cfbd3280, Notional: 0.45315999999999995 + {chain: 24, addr: "00000000000000000000000048a9f8b4b65a55cc46ea557a610acf227454ab09", symbol: "OPC", coinGeckoId: "op-chads", decimals: 18, price: 0.00005942}, // Addr: 0x48a9f8b4b65a55cc46ea557a610acf227454ab09, Notional: 18.986829102409303 + {chain: 24, addr: "00000000000000000000000050bce64397c75488465253c0a034b8097fea6578", symbol: "HAN", coinGeckoId: "hanchain", decimals: 18, price: 0.00530405}, // Addr: 0x50bce64397c75488465253c0a034b8097fea6578, Notional: 0.00530405 + {chain: 24, addr: "000000000000000000000000528cdc92eab044e1e39fe43b9514bfdab4412b98", symbol: "GIV", coinGeckoId: "giveth", decimals: 18, price: 0.00671915}, // Addr: 0x528cdc92eab044e1e39fe43b9514bfdab4412b98, Notional: 24685.103560732525 + {chain: 24, addr: "000000000000000000000000625e7708f30ca75bfd92586e17077590c60eb4cd", symbol: "aOptUSDC", coinGeckoId: "aave-usdc", decimals: 6, price: 0.99928}, // Addr: 0x625e7708f30ca75bfd92586e17077590c60eb4cd, Notional: 6.60241883328 + {chain: 24, addr: "00000000000000000000000068f180fcce6836688e9084f035309e29bf0a2095", symbol: "WBTC", coinGeckoId: "wrapped-bitcoin", decimals: 8, price: 93245}, // Addr: 0x68f180fcce6836688e9084f035309e29bf0a2095, Notional: 25478.41205955 + {chain: 24, addr: "0000000000000000000000006d80113e533a2c0fe82eabd35f1875dcea89ea97", symbol: "aOptSUSD", coinGeckoId: "aave-susd", decimals: 18, price: 0.957852}, // Addr: 0x6d80113e533a2c0fe82eabd35f1875dcea89ea97, Notional: 15.99562917711612 + {chain: 24, addr: "0000000000000000000000006f620ec89b8479e97a6985792d0c64f237566746", symbol: "WPC", coinGeckoId: "wepiggy-coin", decimals: 18, price: 0.00005208}, // Addr: 0x6f620ec89b8479e97a6985792d0c64f237566746, Notional: 0.00812448 + {chain: 24, addr: "00000000000000000000000074ccbe53f77b08632ce0cb91d3a545bf6b8e0979", symbol: "fBOMB", coinGeckoId: "fbomb", decimals: 18, price: 0.053255}, // Addr: 0x74ccbe53f77b08632ce0cb91d3a545bf6b8e0979, Notional: 2.6361225 + {chain: 24, addr: "0000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c31607", symbol: "USDC", coinGeckoId: "usd-coin", decimals: 6, price: 0.999339}, // Addr: 0x7f5c764cbc14f9669b88837ca1490cca17c31607, Notional: 454654.99808755436 + {chain: 24, addr: "00000000000000000000000081ab7e0d570b01411fcc4afd3d50ec8c241cb74b", symbol: "EQZ", coinGeckoId: "equalizer", decimals: 18, price: 0.005379}, // Addr: 0x81ab7e0d570b01411fcc4afd3d50ec8c241cb74b, Notional: 0.5379 + {chain: 24, addr: "0000000000000000000000008b21e9b7daf2c4325bf3d18c1beb79a347fe902a", symbol: "COLLAB", coinGeckoId: "collab-land", decimals: 18, price: 0.00130842}, // Addr: 0x8b21e9b7daf2c4325bf3d18c1beb79a347fe902a, Notional: 0.204467853743568 + {chain: 24, addr: "0000000000000000000000008c6f28f2f1a3c87f0f938b96d27520d9751ec8d9", symbol: "sUSD", coinGeckoId: "nusd", decimals: 18, price: 0.965833}, // Addr: 0x8c6f28f2f1a3c87f0f938b96d27520d9751ec8d9, Notional: 1.88661347379043 + {chain: 24, addr: "00000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58", symbol: "USDT", coinGeckoId: "tether", decimals: 6, price: 0.99789}, // Addr: 0x94b008aa00579c1307b0ef2c499ad98a8ce58e58, Notional: 146911.81649210586 + {chain: 24, addr: "0000000000000000000000009e1028f5f1d5ede59748ffcee5532509976840e0", symbol: "PERP", coinGeckoId: "perpetual-protocol", decimals: 18, price: 0.778595}, // Addr: 0x9e1028f5f1d5ede59748ffcee5532509976840e0, Notional: 0.18634446595065 + {chain: 24, addr: "000000000000000000000000c26921b5b9ee80773774d36c84328ccb22c3a819", symbol: "wOptiDoge", coinGeckoId: "wrapped-optidoge", decimals: 18, price: 8.48224e-7}, // Addr: 0xc26921b5b9ee80773774d36c84328ccb22c3a819, Notional: 10.521428175232 + {chain: 24, addr: "000000000000000000000000c40f949f8a4e094d1b49a23ea9241d289b7b2819", symbol: "LUSD", coinGeckoId: "liquity-usd", decimals: 18, price: 0.997526}, // Addr: 0xc40f949f8a4e094d1b49a23ea9241d289b7b2819, Notional: 1.0972786000000001e-7 + {chain: 24, addr: "000000000000000000000000c5102fe9359fd9a28f877a67e36b0f050d81a3cc", symbol: "HOP", coinGeckoId: "hop-protocol", decimals: 18, price: 0.01492362}, // Addr: 0xc5102fe9359fd9a28f877a67e36b0f050d81a3cc, Notional: 0.632466215224128 + {chain: 24, addr: "000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1", symbol: "DAI", coinGeckoId: "dai", decimals: 18, price: 0.99899}, // Addr: 0xda10009cbd5d07dd0cecc66161fc93d7c9000da1, Notional: 164.96764349643732 + {chain: 24, addr: "000000000000000000000000dfa46478f9e5ea86d57387849598dbfb2e964b02", symbol: "MAI", coinGeckoId: "mimatic", decimals: 18, price: 0.994558}, // Addr: 0xdfa46478f9e5ea86d57387849598dbfb2e964b02, Notional: 4.97279 + {chain: 24, addr: "000000000000000000000000e453d6649643f1f460c371dc3d1da98f7922fe51", symbol: "FUSE", coinGeckoId: "fuse-network-token", decimals: 18, price: 0.02914856}, // Addr: 0xe453d6649643f1f460c371dc3d1da98f7922fe51, Notional: 0.0285655888 + {chain: 24, addr: "000000000000000000000000e50fa9b3c56ffb159cb0fca61f5c9d750e8128c8", symbol: "aOptWETH", coinGeckoId: "aave-weth", decimals: 18, price: 3327.38}, // Addr: 0xe50fa9b3c56ffb159cb0fca61f5c9d750e8128c8, Notional: 0.00009982139999999999 + {chain: 24, addr: "000000000000000000000000fd389dc9533717239856190f42475d3f263a270d", symbol: "GRAIN", coinGeckoId: "granary", decimals: 18, price: 0.00318142}, // Addr: 0xfd389dc9533717239856190f42475d3f263a270d, Notional: 0.09226118 {chain: 24, addr: "000000000000000000000000fdb794692724153d1488ccdbe0c56c252596735f", symbol: "LDO", coinGeckoId: "lido-dao", decimals: 18, price: 1.75}, // Addr: 0xfdb794692724153d1488ccdbe0c56c252596735f, Notional: 2.804035605 - {chain: 28, addr: "017ce8aec5af3bb3ac0158d49771d4c8feba2e54a614fa2a1c0c95e9c4c37185", symbol: "XPLA", coinGeckoId: "xpla", decimals: 18, price: 0.105201}, // Addr: axpla, Notional: 0.66865810830525 - {chain: 30, addr: "00000000000000000000000019b50c63d3d7f7a22308cb0fc8d41b66ff9c318a", symbol: "GPX", coinGeckoId: "grabpenny", decimals: 18, price: 0.00332981}, // Addr: 0x19b50c63d3d7f7a22308cb0fc8d41b66ff9c318a, Notional: 16649.05 - {chain: 30, addr: "00000000000000000000000022a2488fe295047ba13bd8cccdbc8361dbd8cf7c", symbol: "SONNE", coinGeckoId: "sonne-finance", decimals: 18, price: 0.00187117}, // Addr: 0x22a2488fe295047ba13bd8cccdbc8361dbd8cf7c, Notional: 0.02619638 - {chain: 30, addr: "000000000000000000000000236aa50979d5f3de3bd1eeb40e81137f22ab794b", symbol: "tBTC", coinGeckoId: "tbtc", decimals: 18, price: 94760}, // Addr: 0x236aa50979d5f3de3bd1eeb40e81137f22ab794b, Notional: 7662.2623292 - {chain: 30, addr: "000000000000000000000000255f1b39172f65dc6406b8bee8b08155c45fe1b6", symbol: "HARAMBE", coinGeckoId: "harambecoin", decimals: 18, price: 6.6701e-7}, // Addr: 0x255f1b39172f65dc6406b8bee8b08155c45fe1b6, Notional: 0.44377480128921 - {chain: 30, addr: "0000000000000000000000002ae3f1ec7f1f5012cfeab0185bfc7aa3cf0dec22", symbol: "cbETH", coinGeckoId: "coinbase-wrapped-staked-eth", decimals: 18, price: 3898.33}, // Addr: 0x2ae3f1ec7f1f5012cfeab0185bfc7aa3cf0dec22, Notional: 7336.9295142837 + {chain: 28, addr: "017ce8aec5af3bb3ac0158d49771d4c8feba2e54a614fa2a1c0c95e9c4c37185", symbol: "XPLA", coinGeckoId: "xpla", decimals: 18, price: 0.08332}, // Addr: axpla, Notional: 0.52958235743 + {chain: 30, addr: "00000000000000000000000019b50c63d3d7f7a22308cb0fc8d41b66ff9c318a", symbol: "GPX", coinGeckoId: "grabpenny", decimals: 18, price: 0.00336635}, // Addr: 0x19b50c63d3d7f7a22308cb0fc8d41b66ff9c318a, Notional: 16831.75 + {chain: 30, addr: "00000000000000000000000022a2488fe295047ba13bd8cccdbc8361dbd8cf7c", symbol: "SONNE", coinGeckoId: "sonne-finance", decimals: 18, price: 0.00184961}, // Addr: 0x22a2488fe295047ba13bd8cccdbc8361dbd8cf7c, Notional: 0.02589454 + {chain: 30, addr: "000000000000000000000000236aa50979d5f3de3bd1eeb40e81137f22ab794b", symbol: "tBTC", coinGeckoId: "tbtc", decimals: 18, price: 93127}, // Addr: 0x236aa50979d5f3de3bd1eeb40e81137f22ab794b, Notional: 7530.2184880899995 + {chain: 30, addr: "000000000000000000000000255f1b39172f65dc6406b8bee8b08155c45fe1b6", symbol: "HARAMBE", coinGeckoId: "harambecoin", decimals: 18, price: 5.6888e-7}, // Addr: 0x255f1b39172f65dc6406b8bee8b08155c45fe1b6, Notional: 0.3784869926349017 + {chain: 30, addr: "0000000000000000000000002ae3f1ec7f1f5012cfeab0185bfc7aa3cf0dec22", symbol: "cbETH", coinGeckoId: "coinbase-wrapped-staked-eth", decimals: 18, price: 3618.54}, // Addr: 0x2ae3f1ec7f1f5012cfeab0185bfc7aa3cf0dec22, Notional: 5000.7820056498 {chain: 30, addr: "000000000000000000000000302ab9ae394d675676ddb41e294169224824fc9a", symbol: "CHZ", coinGeckoId: "cheezburger", decimals: 18, price: 1.77908e-7}, // Addr: 0x302ab9ae394d675676ddb41e294169224824fc9a, Notional: 15.098662663460349 - {chain: 30, addr: "0000000000000000000000003055913c90fcc1a6ce9a358911721eeb942013a1", symbol: "Cake", coinGeckoId: "pancakeswap-token", decimals: 18, price: 2.94}, // Addr: 0x3055913c90fcc1a6ce9a358911721eeb942013a1, Notional: 13.453305612600001 - {chain: 30, addr: "0000000000000000000000004200000000000000000000000000000000000006", symbol: "WETH", coinGeckoId: "weth", decimals: 18, price: 3594.89}, // Addr: 0x4200000000000000000000000000000000000006, Notional: 223235.7667393022 - {chain: 30, addr: "0000000000000000000000004a3a6dd60a34bb2aba60d73b4c88315e9ceb6a3d", symbol: "MIM", coinGeckoId: "magic-internet-money", decimals: 18, price: 0.99491}, // Addr: 0x4a3a6dd60a34bb2aba60d73b4c88315e9ceb6a3d, Notional: 25.1015253062343 - {chain: 30, addr: "0000000000000000000000004ed4e862860bed51a9570b96d89af5e1b0efefed", symbol: "DEGEN", coinGeckoId: "degen-base", decimals: 18, price: 0.01692759}, // Addr: 0x4ed4e862860bed51a9570b96d89af5e1b0efefed, Notional: 6647.016708658265 - {chain: 30, addr: "00000000000000000000000050c5725949a6f0c72e6c4a641f24049a917db0cb", symbol: "DAI", coinGeckoId: "dai", decimals: 18, price: 1}, // Addr: 0x50c5725949a6f0c72e6c4a641f24049a917db0cb, Notional: 687.82966541 - {chain: 30, addr: "000000000000000000000000532f27101965dd16442e59d40670faf5ebb142e4", symbol: "BRETT", coinGeckoId: "based-brett", decimals: 18, price: 0.195977}, // Addr: 0x532f27101965dd16442e59d40670faf5ebb142e4, Notional: 8318.434842575 - {chain: 30, addr: "00000000000000000000000054a65b16d18527160fafc6fcfebaed47c2976dfa", symbol: "RFKJ", coinGeckoId: "independence-token", decimals: 18, price: 0.00000347}, // Addr: 0x54a65b16d18527160fafc6fcfebaed47c2976dfa, Notional: 0.00347 + {chain: 30, addr: "0000000000000000000000003055913c90fcc1a6ce9a358911721eeb942013a1", symbol: "Cake", coinGeckoId: "pancakeswap-token", decimals: 18, price: 2.5}, // Addr: 0x3055913c90fcc1a6ce9a358911721eeb942013a1, Notional: 11.439885725 + {chain: 30, addr: "0000000000000000000000004200000000000000000000000000000000000006", symbol: "WETH", coinGeckoId: "weth", decimals: 18, price: 3332.06}, // Addr: 0x4200000000000000000000000000000000000006, Notional: 221676.7289958736 + {chain: 30, addr: "0000000000000000000000004a3a6dd60a34bb2aba60d73b4c88315e9ceb6a3d", symbol: "MIM", coinGeckoId: "magic-internet-money", decimals: 18, price: 0.994109}, // Addr: 0x4a3a6dd60a34bb2aba60d73b4c88315e9ceb6a3d, Notional: 25.08131611970457 + {chain: 30, addr: "0000000000000000000000004ed4e862860bed51a9570b96d89af5e1b0efefed", symbol: "DEGEN", coinGeckoId: "degen-base", decimals: 18, price: 0.00943624}, // Addr: 0x4ed4e862860bed51a9570b96d89af5e1b0efefed, Notional: 3705.3617760655516 + {chain: 30, addr: "00000000000000000000000050c5725949a6f0c72e6c4a641f24049a917db0cb", symbol: "DAI", coinGeckoId: "dai", decimals: 18, price: 0.99899}, // Addr: 0x50c5725949a6f0c72e6c4a641f24049a917db0cb, Notional: 687.1349574479359 + {chain: 30, addr: "000000000000000000000000532f27101965dd16442e59d40670faf5ebb142e4", symbol: "BRETT", coinGeckoId: "based-brett", decimals: 18, price: 0.116605}, // Addr: 0x532f27101965dd16442e59d40670faf5ebb142e4, Notional: 4949.412914875 + {chain: 30, addr: "00000000000000000000000054a65b16d18527160fafc6fcfebaed47c2976dfa", symbol: "RFKJ", coinGeckoId: "independence-token", decimals: 18, price: 0.00000264}, // Addr: 0x54a65b16d18527160fafc6fcfebaed47c2976dfa, Notional: 0.00264 {chain: 30, addr: "00000000000000000000000060cbb875d3c6314280dd90a4fe6cafc1d7ce5dfd", symbol: "EBASE", coinGeckoId: "ebase", decimals: 9, price: 0.00000782}, // Addr: 0x60cbb875d3c6314280dd90a4fe6cafc1d7ce5dfd, Notional: 0.008542689225092598 - {chain: 30, addr: "00000000000000000000000064b88c73a5dfa78d1713fe1b4c69a22d7e0faaa7", symbol: "MAV", coinGeckoId: "maverick-protocol", decimals: 18, price: 0.290188}, // Addr: 0x64b88c73a5dfa78d1713fe1b4c69a22d7e0faaa7, Notional: 29.82120841210212 + {chain: 30, addr: "00000000000000000000000064b88c73a5dfa78d1713fe1b4c69a22d7e0faaa7", symbol: "MAV", coinGeckoId: "maverick-protocol", decimals: 18, price: 0.196557}, // Addr: 0x64b88c73a5dfa78d1713fe1b4c69a22d7e0faaa7, Notional: 20.19920624511543 {chain: 30, addr: "0000000000000000000000006653dd4b92a0e5bf8ae570a98906d9d6fd2eec09", symbol: "RCKT", coinGeckoId: "rocketswap", decimals: 18, price: 0.04581254}, // Addr: 0x6653dd4b92a0e5bf8ae570a98906d9d6fd2eec09, Notional: 0.04581254 - {chain: 30, addr: "000000000000000000000000717d31a60a9e811469673429c9f8ea24358990f1", symbol: "EVERY", coinGeckoId: "everyworld", decimals: 18, price: 0.0033694}, // Addr: 0x717d31a60a9e811469673429c9f8ea24358990f1, Notional: 4495.647309149116 - {chain: 30, addr: "00000000000000000000000073e58c6f5e7b9def4bdda8f02f59f9ef2a342cca", symbol: "GP", coinGeckoId: "grabpenny", decimals: 18, price: 0.00332981}, // Addr: 0x73e58c6f5e7b9def4bdda8f02f59f9ef2a342cca, Notional: 6.659619999999999 - {chain: 30, addr: "00000000000000000000000076734b57dfe834f102fb61e1ebf844adf8dd931e", symbol: "weirdo", coinGeckoId: "weirdo-2", decimals: 8, price: 0.00004274}, // Addr: 0x76734b57dfe834f102fb61e1ebf844adf8dd931e, Notional: 23830.392429453408 - {chain: 30, addr: "00000000000000000000000078a087d713be963bf307b18f2ff8122ef9a63ae9", symbol: "BSWAP", coinGeckoId: "baseswap", decimals: 18, price: 0.737613}, // Addr: 0x78a087d713be963bf307b18f2ff8122ef9a63ae9, Notional: 5.53350136931838 - {chain: 30, addr: "0000000000000000000000007d49a065d17d6d4a55dc13649901fdbb98b2afba", symbol: "SUSHI", coinGeckoId: "sushi", decimals: 18, price: 1.35}, // Addr: 0x7d49a065d17d6d4a55dc13649901fdbb98b2afba, Notional: 7.894605208500001 - {chain: 30, addr: "0000000000000000000000007f12d13b34f5f4f0a9449c16bcd42f0da47af200", symbol: "NORMIE", coinGeckoId: "normie-2", decimals: 9, price: 0.00974977}, // Addr: 0x7f12d13b34f5f4f0a9449c16bcd42f0da47af200, Notional: 5638.279491481308 - {chain: 30, addr: "000000000000000000000000833589fcd6edb6e08f4c7c32d4f71b54bda02913", symbol: "USDC", coinGeckoId: "usd-coin", decimals: 6, price: 1}, // Addr: 0x833589fcd6edb6e08f4c7c32d4f71b54bda02913, Notional: 63887.054272 - {chain: 30, addr: "000000000000000000000000858c50c3af1913b0e849afdb74617388a1a5340d", symbol: "SQT", coinGeckoId: "subquery-network", decimals: 18, price: 0.0069232}, // Addr: 0x858c50c3af1913b0e849afdb74617388a1a5340d, Notional: 15.274348906168576 - {chain: 30, addr: "0000000000000000000000008e16d46cb2da01cdd49601ec73d7b0344969ae33", symbol: "coin", coinGeckoId: "coin-on-base", decimals: 18, price: 0.00000525}, // Addr: 0x8e16d46cb2da01cdd49601ec73d7b0344969ae33, Notional: 7.830920812710292 - {chain: 30, addr: "0000000000000000000000008fbd0648971d56f1f2c35fa075ff5bc75fb0e39d", symbol: "MBS", coinGeckoId: "monkeyball", decimals: 18, price: 0.02384234}, // Addr: 0x8fbd0648971d56f1f2c35fa075ff5bc75fb0e39d, Notional: 79.76538960582025 - {chain: 30, addr: "00000000000000000000000096e890c6b2501a69cad5dba402bfb871a2a2874c", symbol: "AAG", coinGeckoId: "aag-ventures", decimals: 18, price: 0.00166001}, // Addr: 0x96e890c6b2501a69cad5dba402bfb871a2a2874c, Notional: 0.00166001 - {chain: 30, addr: "0000000000000000000000009a3b7959e998bf2b50ef1969067d623877050d92", symbol: "PBB", coinGeckoId: "pepe-but-blue", decimals: 18, price: 0.00004459}, // Addr: 0x9a3b7959e998bf2b50ef1969067d623877050d92, Notional: 0.41508343155390925 - {chain: 30, addr: "0000000000000000000000009e1028f5f1d5ede59748ffcee5532509976840e0", symbol: "COMP", coinGeckoId: "compound-governance-token", decimals: 18, price: 75.42}, // Addr: 0x9e1028f5f1d5ede59748ffcee5532509976840e0, Notional: 0.0573282504 - {chain: 30, addr: "000000000000000000000000a88594d404727625a9437c3f886c7643872296ae", symbol: "WELL", coinGeckoId: "moonwell-artemis", decimals: 18, price: 0.061437}, // Addr: 0xa88594d404727625a9437c3f886c7643872296ae, Notional: 6.1437 - {chain: 30, addr: "000000000000000000000000ac1bd2486aaf3b5c0fc3fd868558b082a531b2b4", symbol: "TOSHI", coinGeckoId: "toshi", decimals: 18, price: 0.00022285}, // Addr: 0xac1bd2486aaf3b5c0fc3fd868558b082a531b2b4, Notional: 0.1849655 - {chain: 30, addr: "000000000000000000000000b0ffa8000886e57f86dd5264b9582b2ad87b2b91", symbol: "W", coinGeckoId: "wormhole", decimals: 18, price: 0.318945}, // Addr: 0xb0ffa8000886e57f86dd5264b9582b2ad87b2b91, Notional: 273.65520966997946 - {chain: 30, addr: "000000000000000000000000b5c457ddb4ce3312a6c5a2b056a1652bd542a208", symbol: "O404", coinGeckoId: "omni404", decimals: 18, price: 957.98}, // Addr: 0xb5c457ddb4ce3312a6c5a2b056a1652bd542a208, Notional: 6.351407399999999 - {chain: 30, addr: "000000000000000000000000c1cba3fcea344f92d9239c08c0568f6f2f0ee452", symbol: "wstETH", coinGeckoId: "wrapped-steth", decimals: 18, price: 4258.57}, // Addr: 0xc1cba3fcea344f92d9239c08c0568f6f2f0ee452, Notional: 8.51714 - {chain: 30, addr: "000000000000000000000000c48e605c7b722a57277e087a6170b9e227e5ac0a", symbol: "OMNI", coinGeckoId: "omnicat", decimals: 18, price: 0.00004722}, // Addr: 0xc48e605c7b722a57277e087a6170b9e227e5ac0a, Notional: 107.71936354071644 - {chain: 30, addr: "000000000000000000000000c5bebd5a6ae6be4fcf383eea014fb1dbd43789ca", symbol: "BNS", coinGeckoId: "base-name-service", decimals: 18, price: 0.00005058}, // Addr: 0xc5bebd5a6ae6be4fcf383eea014fb1dbd43789ca, Notional: 0.10116 - {chain: 30, addr: "000000000000000000000000d07379a755a8f11b57610154861d694b2a0f615a", symbol: "BASE", coinGeckoId: "base", decimals: 18, price: 0.00001944}, // Addr: 0xd07379a755a8f11b57610154861d694b2a0f615a, Notional: 4.860068224894229 - {chain: 30, addr: "000000000000000000000000d9aaec86b65d86f6a7b5b1b0c42ffa531710b6ca", symbol: "USDbC", coinGeckoId: "bridged-usd-coin-base", decimals: 6, price: 0.999996}, // Addr: 0xd9aaec86b65d86f6a7b5b1b0c42ffa531710b6ca, Notional: 14304.32585246772 - {chain: 30, addr: "000000000000000000000000dfbea88c4842d30c26669602888d746d30f9d60d", symbol: "CAW", coinGeckoId: "crow-with-knife", decimals: 18, price: 3.9789e-8}, // Addr: 0xdfbea88c4842d30c26669602888d746d30f9d60d, Notional: 388.716503936521 - {chain: 30, addr: "000000000000000000000000e3086852a4b125803c815a158249ae468a3254ca", symbol: "$mfer", coinGeckoId: "mfercoin", decimals: 18, price: 0.02595023}, // Addr: 0xe3086852a4b125803c815a158249ae468a3254ca, Notional: 56818.55268445407 - {chain: 30, addr: "000000000000000000000000e3b53af74a4bf62ae5511055290838050bf764df", symbol: "STG", coinGeckoId: "stargate-finance", decimals: 18, price: 0.382194}, // Addr: 0xe3b53af74a4bf62ae5511055290838050bf764df, Notional: 4.276552340792519 - {chain: 30, addr: "000000000000000000000000eb466342c4d449bc9f53a865d5cb90586f405215", symbol: "axlUSDC", coinGeckoId: "axlusdc", decimals: 6, price: 0.99899}, // Addr: 0xeb466342c4d449bc9f53a865d5cb90586f405215, Notional: 131.61413732597998 - {chain: 30, addr: "000000000000000000000000ec1df7edfcdc2e2042c63252c1cef480f64f9189", symbol: "BOO", coinGeckoId: "boo-2", decimals: 18, price: 0.00005478}, // Addr: 0xec1df7edfcdc2e2042c63252c1cef480f64f9189, Notional: 5.807014904092097 - {chain: 34, addr: "0000000000000000000000005300000000000000000000000000000000000004", symbol: "WETH", coinGeckoId: "bridged-wrapped-ether-scroll", decimals: 18, price: 3595.89}, // Addr: 0x5300000000000000000000000000000000000004, Notional: 107522.04671861399 + {chain: 30, addr: "000000000000000000000000717d31a60a9e811469673429c9f8ea24358990f1", symbol: "EVERY", coinGeckoId: "everyworld", decimals: 18, price: 0.00365791}, // Addr: 0x717d31a60a9e811469673429c9f8ea24358990f1, Notional: 4880.593948064831 + {chain: 30, addr: "00000000000000000000000073e58c6f5e7b9def4bdda8f02f59f9ef2a342cca", symbol: "GP", coinGeckoId: "grabpenny", decimals: 18, price: 0.00336635}, // Addr: 0x73e58c6f5e7b9def4bdda8f02f59f9ef2a342cca, Notional: 6.7327 + {chain: 30, addr: "00000000000000000000000076734b57dfe834f102fb61e1ebf844adf8dd931e", symbol: "weirdo", coinGeckoId: "weirdo-2", decimals: 8, price: 0.00004213}, // Addr: 0x76734b57dfe834f102fb61e1ebf844adf8dd931e, Notional: 22692.376386384673 + {chain: 30, addr: "00000000000000000000000078a087d713be963bf307b18f2ff8122ef9a63ae9", symbol: "BSWAP", coinGeckoId: "baseswap", decimals: 18, price: 0.341692}, // Addr: 0x78a087d713be963bf307b18f2ff8122ef9a63ae9, Notional: 2.56334032871592 + {chain: 30, addr: "0000000000000000000000007d49a065d17d6d4a55dc13649901fdbb98b2afba", symbol: "SUSHI", coinGeckoId: "sushi", decimals: 18, price: 1.36}, // Addr: 0x7d49a065d17d6d4a55dc13649901fdbb98b2afba, Notional: 7.953083765600001 + {chain: 30, addr: "0000000000000000000000007f12d13b34f5f4f0a9449c16bcd42f0da47af200", symbol: "NORMIE", coinGeckoId: "normie-2", decimals: 9, price: 0.00306409}, // Addr: 0x7f12d13b34f5f4f0a9449c16bcd42f0da47af200, Notional: 1771.959318738079 + {chain: 30, addr: "000000000000000000000000833589fcd6edb6e08f4c7c32d4f71b54bda02913", symbol: "USDC", coinGeckoId: "usd-coin", decimals: 6, price: 0.999339}, // Addr: 0x833589fcd6edb6e08f4c7c32d4f71b54bda02913, Notional: 74404.16304798148 + {chain: 30, addr: "000000000000000000000000858c50c3af1913b0e849afdb74617388a1a5340d", symbol: "SQT", coinGeckoId: "subquery-network", decimals: 18, price: 0.00504097}, // Addr: 0x858c50c3af1913b0e849afdb74617388a1a5340d, Notional: 11.12166839113829 + {chain: 30, addr: "0000000000000000000000008e16d46cb2da01cdd49601ec73d7b0344969ae33", symbol: "coin", coinGeckoId: "coin-on-base", decimals: 18, price: 0.00000257}, // Addr: 0x8e16d46cb2da01cdd49601ec73d7b0344969ae33, Notional: 5.087014218317229 + {chain: 30, addr: "0000000000000000000000008fbd0648971d56f1f2c35fa075ff5bc75fb0e39d", symbol: "MBS", coinGeckoId: "monkeyball", decimals: 18, price: 0.01713571}, // Addr: 0x8fbd0648971d56f1f2c35fa075ff5bc75fb0e39d, Notional: 57.32812233708394 + {chain: 30, addr: "00000000000000000000000096e890c6b2501a69cad5dba402bfb871a2a2874c", symbol: "AAG", coinGeckoId: "aag-ventures", decimals: 18, price: 0.00096856}, // Addr: 0x96e890c6b2501a69cad5dba402bfb871a2a2874c, Notional: 0.00096856 + {chain: 30, addr: "0000000000000000000000009a3b7959e998bf2b50ef1969067d623877050d92", symbol: "PBB", coinGeckoId: "pepe-but-blue", decimals: 18, price: 0.00003645}, // Addr: 0x9a3b7959e998bf2b50ef1969067d623877050d92, Notional: 0.3393090621246915 + {chain: 30, addr: "0000000000000000000000009e1028f5f1d5ede59748ffcee5532509976840e0", symbol: "COMP", coinGeckoId: "compound-governance-token", decimals: 18, price: 72.9}, // Addr: 0x9e1028f5f1d5ede59748ffcee5532509976840e0, Notional: 0.055412748000000005 + {chain: 30, addr: "000000000000000000000000a88594d404727625a9437c3f886c7643872296ae", symbol: "WELL", coinGeckoId: "moonwell-artemis", decimals: 18, price: 0.051185}, // Addr: 0xa88594d404727625a9437c3f886c7643872296ae, Notional: 5.5400859798388495 + {chain: 30, addr: "000000000000000000000000ac1bd2486aaf3b5c0fc3fd868558b082a531b2b4", symbol: "TOSHI", coinGeckoId: "toshi", decimals: 18, price: 0.00012403}, // Addr: 0xac1bd2486aaf3b5c0fc3fd868558b082a531b2b4, Notional: 0.10294489999999999 + {chain: 30, addr: "000000000000000000000000afb89a09d82fbde58f18ac6437b3fc81724e4df6", symbol: "DOG", coinGeckoId: "the-doge-nft", decimals: 18, price: 0.00399146}, // Addr: 0xafb89a09d82fbde58f18ac6437b3fc81724e4df6, Notional: 60240.00197315485 + {chain: 30, addr: "000000000000000000000000b0ffa8000886e57f86dd5264b9582b2ad87b2b91", symbol: "W", coinGeckoId: "wormhole", decimals: 18, price: 0.284654}, // Addr: 0xb0ffa8000886e57f86dd5264b9582b2ad87b2b91, Notional: 101.90648585338741 + {chain: 30, addr: "000000000000000000000000b5c457ddb4ce3312a6c5a2b056a1652bd542a208", symbol: "O404", coinGeckoId: "omni404", decimals: 18, price: 950.55}, // Addr: 0xb5c457ddb4ce3312a6c5a2b056a1652bd542a208, Notional: 6.302146499999999 + {chain: 30, addr: "000000000000000000000000c1cba3fcea344f92d9239c08c0568f6f2f0ee452", symbol: "wstETH", coinGeckoId: "wrapped-steth", decimals: 18, price: 3961.06}, // Addr: 0xc1cba3fcea344f92d9239c08c0568f6f2f0ee452, Notional: 7.9221200000000005 + {chain: 30, addr: "000000000000000000000000c48e605c7b722a57277e087a6170b9e227e5ac0a", symbol: "OMNI", coinGeckoId: "omnicat", decimals: 18, price: 0.00002616}, // Addr: 0xc48e605c7b722a57277e087a6170b9e227e5ac0a, Notional: 59.676801148351174 + {chain: 30, addr: "000000000000000000000000c5bebd5a6ae6be4fcf383eea014fb1dbd43789ca", symbol: "BNS", coinGeckoId: "base-name-service", decimals: 18, price: 0.00003409}, // Addr: 0xc5bebd5a6ae6be4fcf383eea014fb1dbd43789ca, Notional: 0.06818 + {chain: 30, addr: "000000000000000000000000d07379a755a8f11b57610154861d694b2a0f615a", symbol: "BASE", coinGeckoId: "base", decimals: 18, price: 0.00000888}, // Addr: 0xd07379a755a8f11b57610154861d694b2a0f615a, Notional: 2.2200311644578576 + {chain: 30, addr: "000000000000000000000000d9aaec86b65d86f6a7b5b1b0c42ffa531710b6ca", symbol: "USDbC", coinGeckoId: "bridged-usd-coin-base", decimals: 6, price: 0.999021}, // Addr: 0xd9aaec86b65d86f6a7b5b1b0c42ffa531710b6ca, Notional: 14290.37907897447 + {chain: 30, addr: "000000000000000000000000dfbea88c4842d30c26669602888d746d30f9d60d", symbol: "CAW", coinGeckoId: "crow-with-knife", decimals: 18, price: 3.6612e-8}, // Addr: 0xdfbea88c4842d30c26669602888d746d30f9d60d, Notional: 357.6789726337406 + {chain: 30, addr: "000000000000000000000000e3086852a4b125803c815a158249ae468a3254ca", symbol: "$mfer", coinGeckoId: "mfercoin", decimals: 18, price: 0.01698549}, // Addr: 0xe3086852a4b125803c815a158249ae468a3254ca, Notional: 36654.003513427524 + {chain: 30, addr: "000000000000000000000000e3b53af74a4bf62ae5511055290838050bf764df", symbol: "STG", coinGeckoId: "stargate-finance", decimals: 18, price: 0.36685}, // Addr: 0xe3b53af74a4bf62ae5511055290838050bf764df, Notional: 4.104860950773 + {chain: 30, addr: "000000000000000000000000eb466342c4d449bc9f53a865d5cb90586f405215", symbol: "axlUSDC", coinGeckoId: "axlusdc", decimals: 6, price: 0.998424}, // Addr: 0xeb466342c4d449bc9f53a865d5cb90586f405215, Notional: 131.53956840964798 + {chain: 30, addr: "000000000000000000000000ec1df7edfcdc2e2042c63252c1cef480f64f9189", symbol: "BOO", coinGeckoId: "boo-2", decimals: 18, price: 0.00005436}, // Addr: 0xec1df7edfcdc2e2042c63252c1cef480f64f9189, Notional: 5.762492336371785 + {chain: 30, addr: "000000000000000000000000f7c1cefcf7e1dd8161e00099facd3e1db9e528ee", symbol: "TOWER", coinGeckoId: "tower", decimals: 18, price: 0.00163846}, // Addr: 0xf7c1cefcf7e1dd8161e00099facd3e1db9e528ee, Notional: 0.80939924 + {chain: 34, addr: "0000000000000000000000005300000000000000000000000000000000000004", symbol: "WETH", coinGeckoId: "bridged-wrapped-ether-scroll", decimals: 18, price: 3329.56}, // Addr: 0x5300000000000000000000000000000000000004, Notional: 60499.6465865064 } } diff --git a/node/pkg/governor/governor.go b/node/pkg/governor/governor.go index 8f6137b1c8..28313cfcfb 100644 --- a/node/pkg/governor/governor.go +++ b/node/pkg/governor/governor.go @@ -464,7 +464,7 @@ func (gov *ChainGovernor) ProcessMsgForTime(msg *common.MessagePublication, now gov.logger.Info("ignoring duplicate vaa because it is enqueued", zap.String("msgID", msg.MessageIDString()), zap.String("hash", hash), - zap.Stringer("txHash", msg.TxHash), + zap.String("txID", msg.TxIDString()), ) return false, nil } @@ -472,7 +472,7 @@ func (gov *ChainGovernor) ProcessMsgForTime(msg *common.MessagePublication, now gov.logger.Info("allowing duplicate vaa to be published again, but not adding it to the notional value", zap.String("msgID", msg.MessageIDString()), zap.String("hash", hash), - zap.Stringer("txHash", msg.TxHash), + zap.String("txID", msg.TxIDString()), ) return true, nil } @@ -484,7 +484,7 @@ func (gov *ChainGovernor) ProcessMsgForTime(msg *common.MessagePublication, now gov.logger.Error("Error when attempting to trim and sum transfers", zap.String("msgID", msg.MessageIDString()), zap.String("hash", hash), - zap.Stringer("txHash", msg.TxHash), + zap.String("txID", msg.TxIDString()), zap.Error(err), ) return false, err @@ -496,7 +496,7 @@ func (gov *ChainGovernor) ProcessMsgForTime(msg *common.MessagePublication, now gov.logger.Error("failed to compute value of transfer", zap.String("msgID", msg.MessageIDString()), zap.String("hash", hash), - zap.Stringer("txHash", msg.TxHash), + zap.String("txID", msg.TxIDString()), zap.Error(err), ) return false, err @@ -507,7 +507,7 @@ func (gov *ChainGovernor) ProcessMsgForTime(msg *common.MessagePublication, now gov.logger.Error("total value has overflowed", zap.String("msgID", msg.MessageIDString()), zap.String("hash", hash), - zap.Stringer("txHash", msg.TxHash), + zap.String("txID", msg.TxIDString()), zap.Uint64("prevTotalValue", prevTotalValue), zap.Uint64("newTotalValue", newTotalValue), ) @@ -527,7 +527,7 @@ func (gov *ChainGovernor) ProcessMsgForTime(msg *common.MessagePublication, now zap.Stringer("releaseTime", releaseTime), zap.Uint64("bigTransactionSize", emitterChainEntry.bigTransactionSize), zap.String("hash", hash), - zap.Stringer("txHash", msg.TxHash), + zap.String("txID", msg.TxIDString()), ) } else if newTotalValue > emitterChainEntry.dailyLimit { enqueueIt = true @@ -539,7 +539,7 @@ func (gov *ChainGovernor) ProcessMsgForTime(msg *common.MessagePublication, now zap.Stringer("releaseTime", releaseTime), zap.String("msgID", msg.MessageIDString()), zap.String("hash", hash), - zap.Stringer("txHash", msg.TxHash), + zap.String("txID", msg.TxIDString()), ) } @@ -550,7 +550,7 @@ func (gov *ChainGovernor) ProcessMsgForTime(msg *common.MessagePublication, now gov.logger.Error("failed to store pending vaa", zap.String("msgID", msg.MessageIDString()), zap.String("hash", hash), - zap.Stringer("txHash", msg.TxHash), + zap.String("txID", msg.TxIDString()), zap.Error(err), ) return false, err @@ -570,7 +570,7 @@ func (gov *ChainGovernor) ProcessMsgForTime(msg *common.MessagePublication, now zap.Uint64("newTotalValue", newTotalValue), zap.String("msgID", msg.MessageIDString()), zap.String("hash", hash), - zap.Stringer("txHash", msg.TxHash), + zap.String("txID", msg.TxIDString()), ) dbTransfer := db.Transfer{ @@ -591,7 +591,7 @@ func (gov *ChainGovernor) ProcessMsgForTime(msg *common.MessagePublication, now gov.logger.Error("failed to store transfer", zap.String("msgID", msg.MessageIDString()), zap.String("hash", hash), zap.Error(err), - zap.Stringer("txHash", msg.TxHash), + zap.String("txID", msg.TxIDString()), ) return false, err } diff --git a/node/pkg/governor/governor_db.go b/node/pkg/governor/governor_db.go index db928ce868..809b400510 100644 --- a/node/pkg/governor/governor_db.go +++ b/node/pkg/governor/governor_db.go @@ -67,7 +67,7 @@ func (gov *ChainGovernor) reloadPendingTransfer(pending *db.PendingTransfer) { if !exists { gov.logger.Error("reloaded pending transfer for unsupported chain, dropping it", zap.String("MsgID", msg.MessageIDString()), - zap.Stringer("TxHash", msg.TxHash), + zap.String("txID", msg.TxIDString()), zap.Stringer("Timestamp", msg.Timestamp), zap.Uint32("Nonce", msg.Nonce), zap.Uint64("Sequence", msg.Sequence), @@ -81,7 +81,7 @@ func (gov *ChainGovernor) reloadPendingTransfer(pending *db.PendingTransfer) { if msg.EmitterAddress != ce.emitterAddr { gov.logger.Error("reloaded pending transfer for unsupported emitter address, dropping it", zap.String("MsgID", msg.MessageIDString()), - zap.Stringer("TxHash", msg.TxHash), + zap.String("txID", msg.TxIDString()), zap.Stringer("Timestamp", msg.Timestamp), zap.Uint32("Nonce", msg.Nonce), zap.Uint64("Sequence", msg.Sequence), @@ -96,7 +96,7 @@ func (gov *ChainGovernor) reloadPendingTransfer(pending *db.PendingTransfer) { if err != nil { gov.logger.Error("failed to parse payload for reloaded pending transfer, dropping it", zap.String("MsgID", msg.MessageIDString()), - zap.Stringer("TxHash", msg.TxHash), + zap.String("txID", msg.TxIDString()), zap.Stringer("Timestamp", msg.Timestamp), zap.Uint32("Nonce", msg.Nonce), zap.Uint64("Sequence", msg.Sequence), @@ -113,7 +113,7 @@ func (gov *ChainGovernor) reloadPendingTransfer(pending *db.PendingTransfer) { if !exists { gov.logger.Error("reloaded pending transfer for unsupported token, dropping it", zap.String("MsgID", msg.MessageIDString()), - zap.Stringer("TxHash", msg.TxHash), + zap.String("txID", msg.TxIDString()), zap.Stringer("Timestamp", msg.Timestamp), zap.Uint32("Nonce", msg.Nonce), zap.Uint64("Sequence", msg.Sequence), @@ -131,7 +131,7 @@ func (gov *ChainGovernor) reloadPendingTransfer(pending *db.PendingTransfer) { if _, alreadyExists := gov.msgsSeen[hash]; alreadyExists { gov.logger.Error("not reloading pending transfer because it is a duplicate", zap.String("MsgID", msg.MessageIDString()), - zap.Stringer("TxHash", msg.TxHash), + zap.String("txID", msg.TxIDString()), zap.Stringer("Timestamp", msg.Timestamp), zap.Uint32("Nonce", msg.Nonce), zap.Uint64("Sequence", msg.Sequence), @@ -146,7 +146,7 @@ func (gov *ChainGovernor) reloadPendingTransfer(pending *db.PendingTransfer) { gov.logger.Info("reloaded pending transfer", zap.String("MsgID", msg.MessageIDString()), - zap.Stringer("TxHash", msg.TxHash), + zap.String("txID", msg.TxIDString()), zap.Stringer("Timestamp", msg.Timestamp), zap.Uint32("Nonce", msg.Nonce), zap.Uint64("Sequence", msg.Sequence), diff --git a/node/pkg/governor/governor_monitoring.go b/node/pkg/governor/governor_monitoring.go index 378bc9ba4e..cd03ada24c 100644 --- a/node/pkg/governor/governor_monitoring.go +++ b/node/pkg/governor/governor_monitoring.go @@ -381,7 +381,7 @@ func (gov *ChainGovernor) GetEnqueuedVAAs() []*publicrpcv1.GovernorGetEnqueuedVA Sequence: pe.dbData.Msg.Sequence, ReleaseTime: uint32(pe.dbData.ReleaseTime.Unix()), NotionalValue: value, - TxHash: pe.dbData.Msg.TxHash.String(), + TxHash: pe.dbData.Msg.TxIDString(), }) } } @@ -649,7 +649,7 @@ func (gov *ChainGovernor) publishStatus(ctx context.Context, hb *gossipv1.Heartb Sequence: pe.dbData.Msg.Sequence, ReleaseTime: uint32(pe.dbData.ReleaseTime.Unix()), NotionalValue: value, - TxHash: pe.dbData.Msg.TxHash.String(), + TxHash: pe.dbData.Msg.TxIDString(), }) } } diff --git a/node/pkg/governor/governor_test.go b/node/pkg/governor/governor_test.go index d44168c5d7..a7fed811aa 100644 --- a/node/pkg/governor/governor_test.go +++ b/node/pkg/governor/governor_test.go @@ -697,13 +697,13 @@ func newChainGovernorForTestWithLogger(ctx context.Context, logger *zap.Logger) return gov, nil } -// Converts a string into a go-ethereum Hash object used as test input. -func hashFromString(str string) eth_common.Hash { +// Converts a TxHash string into a byte array to be used as a TxID. +func hashToTxID(str string) []byte { if (len(str) > 2) && (str[0] == '0') && (str[1] == 'x') { str = str[2:] } - return eth_common.HexToHash(str) + return eth_common.HexToHash(str).Bytes() } func TestVaaForUninterestingEmitterChain(t *testing.T) { @@ -717,7 +717,7 @@ func TestVaaForUninterestingEmitterChain(t *testing.T) { payload := []byte{1, 97, 97, 97, 97, 97} msg := common.MessagePublication{ - TxHash: hashFromString("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063"), + TxID: hashToTxID("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063"), Timestamp: time.Unix(int64(1654543099), 0), Nonce: uint32(1), Sequence: uint64(1), @@ -749,7 +749,7 @@ func TestVaaForUninterestingEmitterAddress(t *testing.T) { payload := []byte{1, 97, 97, 97, 97, 97} msg := common.MessagePublication{ - TxHash: hashFromString("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063"), + TxID: hashToTxID("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063"), Timestamp: time.Unix(int64(1654543099), 0), Nonce: uint32(1), Sequence: uint64(1), @@ -782,7 +782,7 @@ func TestVaaForUninterestingPayloadType(t *testing.T) { payload := []byte{2, 97, 97, 97, 97, 97} msg := common.MessagePublication{ - TxHash: hashFromString("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063"), + TxID: hashToTxID("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063"), Timestamp: time.Unix(int64(1654543099), 0), Nonce: uint32(1), Sequence: uint64(1), @@ -886,7 +886,7 @@ func TestVaaForUninterestingToken(t *testing.T) { tokenBridgeAddr, _ := vaa.StringToAddress("0x0290fb167208af455bb137780163b7b7a9a10c16") msg := common.MessagePublication{ - TxHash: hashFromString("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063"), + TxID: hashToTxID("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063"), Timestamp: time.Unix(int64(1654543099), 0), Nonce: uint32(1), Sequence: uint64(1), @@ -971,7 +971,7 @@ func TestFlowCancelProcessMsgForTimeFullCancel(t *testing.T) { // Transfer from Ethereum to Sui via the token bridge msg1 := common.MessagePublication{ - TxHash: hashFromString("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063"), + TxID: hashToTxID("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063"), Timestamp: transferTime, Nonce: uint32(1), Sequence: uint64(1), @@ -989,7 +989,7 @@ func TestFlowCancelProcessMsgForTimeFullCancel(t *testing.T) { // Transfer from Sui to Ethereum via the token bridge msg2 := common.MessagePublication{ - TxHash: hashFromString("0xabc123f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4064"), + TxID: hashToTxID("0xabc123f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4064"), Timestamp: transferTime, Nonce: uint32(2), Sequence: uint64(2), @@ -1007,7 +1007,7 @@ func TestFlowCancelProcessMsgForTimeFullCancel(t *testing.T) { // msg and asset that are NOT flow cancelable msg3 := common.MessagePublication{ - TxHash: hashFromString("0x888888f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a8888"), + TxID: hashToTxID("0x888888f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a8888"), Timestamp: time.Unix(int64(transferTime.Unix()+1), 0), Nonce: uint32(3), Sequence: uint64(3), @@ -1204,7 +1204,7 @@ func TestFlowCancelProcessMsgForTimePartialCancel(t *testing.T) { // Transfer from Ethereum to Sui via the token bridge msg1 := common.MessagePublication{ - TxHash: hashFromString("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063"), + TxID: hashToTxID("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063"), Timestamp: transferTime, Nonce: uint32(1), Sequence: uint64(1), @@ -1222,7 +1222,7 @@ func TestFlowCancelProcessMsgForTimePartialCancel(t *testing.T) { // Transfer from Sui to Ethereum via the token bridge msg2 := common.MessagePublication{ - TxHash: hashFromString("0xabc123f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4064"), + TxID: hashToTxID("0xabc123f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4064"), Timestamp: transferTime, Nonce: uint32(2), Sequence: uint64(2), @@ -1240,7 +1240,7 @@ func TestFlowCancelProcessMsgForTimePartialCancel(t *testing.T) { // msg and asset that are NOT flow cancelable msg3 := common.MessagePublication{ - TxHash: hashFromString("0x888888f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a8888"), + TxID: hashToTxID("0x888888f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a8888"), Timestamp: time.Unix(int64(transferTime.Unix()+1), 0), Nonce: uint32(3), Sequence: uint64(3), @@ -1391,7 +1391,7 @@ func TestTransfersUpToAndOverTheLimit(t *testing.T) { // The first two transfers should be accepted. msg1 := common.MessagePublication{ - TxHash: hashFromString("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063"), + TxID: hashToTxID("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063"), Timestamp: time.Unix(int64(1654543099), 0), Nonce: uint32(1), Sequence: uint64(1), @@ -1402,7 +1402,7 @@ func TestTransfersUpToAndOverTheLimit(t *testing.T) { } msg2 := common.MessagePublication{ - TxHash: hashFromString("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063"), + TxID: hashToTxID("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063"), Timestamp: time.Unix(int64(1654543099), 0), Nonce: uint32(1), Sequence: uint64(2), @@ -1444,7 +1444,7 @@ func TestTransfersUpToAndOverTheLimit(t *testing.T) { ) msg3 := common.MessagePublication{ - TxHash: hashFromString("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063"), + TxID: hashToTxID("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063"), Timestamp: time.Unix(int64(1654543099), 0), Nonce: uint32(1), Sequence: uint64(3), @@ -1467,7 +1467,7 @@ func TestTransfersUpToAndOverTheLimit(t *testing.T) { // But a small one should still go through. msg4 := common.MessagePublication{ - TxHash: hashFromString("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063"), + TxID: hashToTxID("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063"), Timestamp: time.Unix(int64(1654543099), 0), Nonce: uint32(1), Sequence: uint64(4), @@ -1517,7 +1517,7 @@ func TestPendingTransferBeingReleased(t *testing.T) { ) msg1 := common.MessagePublication{ - TxHash: hashFromString("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063"), + TxID: hashToTxID("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063"), Timestamp: time.Unix(int64(1654543099), 0), Nonce: uint32(1), Sequence: uint64(1), @@ -1549,7 +1549,7 @@ func TestPendingTransferBeingReleased(t *testing.T) { ) msg2 := common.MessagePublication{ - TxHash: hashFromString("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063"), + TxID: hashToTxID("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063"), Timestamp: time.Unix(int64(1654543099), 0), Nonce: uint32(1), Sequence: uint64(1), @@ -1581,7 +1581,7 @@ func TestPendingTransferBeingReleased(t *testing.T) { ) msg3 := common.MessagePublication{ - TxHash: hashFromString("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063"), + TxID: hashToTxID("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063"), Timestamp: time.Unix(int64(1654543099), 0), Nonce: uint32(1), Sequence: uint64(1), @@ -1613,7 +1613,7 @@ func TestPendingTransferBeingReleased(t *testing.T) { ) msg4 := common.MessagePublication{ - TxHash: hashFromString("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063"), + TxID: hashToTxID("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063"), Timestamp: time.Unix(int64(1654543099), 0), Nonce: uint32(1), Sequence: uint64(1), @@ -1744,7 +1744,7 @@ func TestPendingTransferFlowCancelsWhenReleased(t *testing.T) { // First message: consume most of the dailyLimit for the emitter chain msg1 := common.MessagePublication{ - TxHash: hashFromString("0x888888f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a8888"), + TxID: hashToTxID("0x888888f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a8888"), Timestamp: time.Unix(int64(transferTime.Unix()+1), 0), Nonce: uint32(1), Sequence: uint64(1), @@ -1762,7 +1762,7 @@ func TestPendingTransferFlowCancelsWhenReleased(t *testing.T) { // Second message: This transfer gets queued because the limit is exhausted msg2 := common.MessagePublication{ - TxHash: hashFromString("0x888888f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a8888"), + TxID: hashToTxID("0x888888f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a8888"), Timestamp: time.Unix(int64(transferTime.Unix()+2), 0), Nonce: uint32(2), Sequence: uint64(2), @@ -1781,7 +1781,7 @@ func TestPendingTransferFlowCancelsWhenReleased(t *testing.T) { // Third message: Incoming flow cancelling transfer to the emitter chain for the previous messages. This // reduces the Governor usage for that chain. msg3 := common.MessagePublication{ - TxHash: hashFromString("0x888888f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a8888"), + TxID: hashToTxID("0x888888f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a8888"), Timestamp: time.Unix(int64(transferTime.Unix()+3), 0), Nonce: uint32(3), Sequence: uint64(3), @@ -1973,7 +1973,7 @@ func TestSmallerPendingTransfersAfterBigOneShouldGetReleased(t *testing.T) { // The first VAA should be accepted. msg1 := common.MessagePublication{ - TxHash: hashFromString("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063"), + TxID: hashToTxID("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063"), Timestamp: time.Unix(int64(1654543099), 0), Nonce: uint32(1), Sequence: uint64(1), @@ -2003,7 +2003,7 @@ func TestSmallerPendingTransfersAfterBigOneShouldGetReleased(t *testing.T) { // And so should the second. msg2 := common.MessagePublication{ - TxHash: hashFromString("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063"), + TxID: hashToTxID("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063"), Timestamp: time.Unix(int64(1654543099), 0), Nonce: uint32(1), Sequence: uint64(1), @@ -2033,7 +2033,7 @@ func TestSmallerPendingTransfersAfterBigOneShouldGetReleased(t *testing.T) { // But the third, big one should be queued up. msg3 := common.MessagePublication{ - TxHash: hashFromString("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063"), + TxID: hashToTxID("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063"), Timestamp: time.Unix(int64(1654543099), 0), Nonce: uint32(1), Sequence: uint64(1), @@ -2063,7 +2063,7 @@ func TestSmallerPendingTransfersAfterBigOneShouldGetReleased(t *testing.T) { // A fourth, smaller, but still too big one, should get enqueued. msg4 := common.MessagePublication{ - TxHash: hashFromString("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063"), + TxID: hashToTxID("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063"), Timestamp: time.Unix(int64(1654543099), 0), Nonce: uint32(1), Sequence: uint64(1), @@ -2093,7 +2093,7 @@ func TestSmallerPendingTransfersAfterBigOneShouldGetReleased(t *testing.T) { // A fifth, smaller, but still too big one, should also get enqueued. msg5 := common.MessagePublication{ - TxHash: hashFromString("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063"), + TxID: hashToTxID("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063"), Timestamp: time.Unix(int64(1654543099), 0), Nonce: uint32(1), Sequence: uint64(1), @@ -2123,7 +2123,7 @@ func TestSmallerPendingTransfersAfterBigOneShouldGetReleased(t *testing.T) { // A sixth, big one should also get enqueued. msg6 := common.MessagePublication{ - TxHash: hashFromString("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063"), + TxID: hashToTxID("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063"), Timestamp: time.Unix(int64(1654543099), 0), Nonce: uint32(1), Sequence: uint64(1), @@ -2223,7 +2223,7 @@ func TestNumDaysForReleaseTimerReset(t *testing.T) { // message that, when processed, should exceed the big transfer size msg := common.MessagePublication{ - TxHash: hashFromString("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063"), + TxID: hashToTxID("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063"), Timestamp: messageTimestamp, Nonce: uint32(1), Sequence: uint64(3), @@ -2284,7 +2284,7 @@ func TestLargeTransactionGetsEnqueuedAndReleasedWhenTheTimerExpires(t *testing.T // The first small transfer should be accepted. msg1 := common.MessagePublication{ - TxHash: hashFromString("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063"), + TxID: hashToTxID("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063"), Timestamp: time.Unix(int64(1654543099), 0), Nonce: uint32(1), Sequence: uint64(1), @@ -2314,7 +2314,7 @@ func TestLargeTransactionGetsEnqueuedAndReleasedWhenTheTimerExpires(t *testing.T // And so should the second. msg2 := common.MessagePublication{ - TxHash: hashFromString("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063"), + TxID: hashToTxID("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063"), Timestamp: time.Unix(int64(1654543099), 0), Nonce: uint32(1), Sequence: uint64(2), @@ -2344,7 +2344,7 @@ func TestLargeTransactionGetsEnqueuedAndReleasedWhenTheTimerExpires(t *testing.T // But the third big one should get enqueued. msg3 := common.MessagePublication{ - TxHash: hashFromString("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063"), + TxID: hashToTxID("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063"), Timestamp: time.Unix(int64(1654543099), 0), Nonce: uint32(1), Sequence: uint64(3), @@ -2501,7 +2501,7 @@ func TestSmallTransactionsGetReleasedWhenTheTimerExpires(t *testing.T) { // Submit a small transfer that will get enqueued due to the low daily limit. msg1 := common.MessagePublication{ - TxHash: hashFromString("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063"), + TxID: hashToTxID("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063"), Timestamp: time.Unix(int64(1654543099), 0), Nonce: uint32(1), Sequence: uint64(1), @@ -2606,7 +2606,7 @@ func TestTransferPayloadTooShort(t *testing.T) { payloadBytes1 = payloadBytes1[0 : len(payloadBytes1)-1] msg := common.MessagePublication{ - TxHash: hashFromString("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063"), + TxID: hashToTxID("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063"), Timestamp: time.Unix(int64(1654543099), 0), Nonce: uint32(1), Sequence: uint64(1), @@ -2697,7 +2697,7 @@ func TestDontReloadDuplicates(t *testing.T) { pending1 := &db.PendingTransfer{ ReleaseTime: now.Add(time.Hour * 24), Msg: common.MessagePublication{ - TxHash: hashFromString("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063"), + TxID: hashToTxID("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063"), Timestamp: time.Unix(int64(1654543099), 0), Nonce: uint32(1), Sequence: uint64(200), @@ -2712,7 +2712,7 @@ func TestDontReloadDuplicates(t *testing.T) { pending2 := &db.PendingTransfer{ ReleaseTime: now.Add(time.Hour * 24), Msg: common.MessagePublication{ - TxHash: hashFromString("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063"), + TxID: hashToTxID("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063"), Timestamp: time.Unix(int64(1654543099), 0), Nonce: uint32(1), Sequence: uint64(201), @@ -2963,7 +2963,7 @@ func TestReobservationOfPublishedMsg(t *testing.T) { // The first transfer should be accepted. msg := common.MessagePublication{ - TxHash: hashFromString("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063"), + TxID: hashToTxID("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063"), Timestamp: time.Unix(int64(1654543099), 0), Nonce: uint32(1), Sequence: uint64(1), @@ -3026,7 +3026,7 @@ func TestReobservationOfEnqueued(t *testing.T) { // A big transfer should get enqueued. msg := common.MessagePublication{ - TxHash: hashFromString("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063"), + TxID: hashToTxID("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063"), Timestamp: time.Unix(int64(1654543099), 0), Nonce: uint32(1), Sequence: uint64(1), @@ -3088,7 +3088,7 @@ func TestReusedMsgIdWithDifferentPayloadGetsProcessed(t *testing.T) { // The first transfer should be accepted. msg1 := common.MessagePublication{ - TxHash: hashFromString("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063"), + TxID: hashToTxID("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063"), Timestamp: time.Unix(int64(1654543099), 0), Nonce: uint32(1), Sequence: uint64(1), @@ -3118,7 +3118,7 @@ func TestReusedMsgIdWithDifferentPayloadGetsProcessed(t *testing.T) { // A second message with the same msgId but a different payload should also get published and apply to the notional value. msg2 := common.MessagePublication{ - TxHash: hashFromString("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063"), + TxID: hashToTxID("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063"), Timestamp: time.Unix(int64(1654543099), 0), Nonce: uint32(1), Sequence: uint64(1), @@ -3291,7 +3291,7 @@ func TestPendingTransferWithBadPayloadGetsDroppedNotReleased(t *testing.T) { // Create two big transactions. msg1 := common.MessagePublication{ - TxHash: hashFromString("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063"), + TxID: hashToTxID("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063"), Timestamp: time.Unix(int64(1654543099), 0), Nonce: uint32(1), Sequence: uint64(1), @@ -3308,7 +3308,7 @@ func TestPendingTransferWithBadPayloadGetsDroppedNotReleased(t *testing.T) { } msg2 := common.MessagePublication{ - TxHash: hashFromString("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063"), + TxID: hashToTxID("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063"), Timestamp: time.Unix(int64(1654543099), 0), Nonce: uint32(2), Sequence: uint64(2), diff --git a/node/pkg/node/node.go b/node/pkg/node/node.go index fab5bedce8..fbfcb89e5e 100644 --- a/node/pkg/node/node.go +++ b/node/pkg/node/node.go @@ -29,10 +29,6 @@ const ( // gossipVaaSendBufferSize configures the size of the gossip network send buffer gossipVaaSendBufferSize = 5000 - // inboundObservationBufferSize configures the size of the obsvC channel that contains observations from other Guardians. - // One observation takes roughly 0.1ms to process on one core, so the whole queue could be processed in 1s - inboundObservationBufferSize = 10000 - // inboundBatchObservationBufferSize configures the size of the batchObsvC channel that contains batches of observations from other Guardians. // Since a batch contains many observations, the guardians should not be publishing too many of these. With 19 guardians, we would expect 19 messages // per second during normal operations. However, since some messages get published immediately, we need to allow extra room. @@ -84,8 +80,6 @@ type G struct { gossipControlSendC chan []byte gossipAttestationSendC chan []byte gossipVaaSendC chan []byte - // Inbound observations. This is read/write because the processor also writes to it as a fast-path when handling locally made observations. - obsvC chan *common.MsgWithTimeStamp[gossipv1.SignedObservation] // Inbound observation batches. batchObsvC channelPair[*common.MsgWithTimeStamp[gossipv1.SignedObservationBatch]] // Finalized guardian observations aggregated across all chains @@ -127,7 +121,6 @@ func (g *G) initializeBasic(rootCtxCancel context.CancelFunc) { g.gossipControlSendC = make(chan []byte, gossipControlSendBufferSize) g.gossipAttestationSendC = make(chan []byte, gossipAttestationSendBufferSize) g.gossipVaaSendC = make(chan []byte, gossipVaaSendBufferSize) - g.obsvC = make(chan *common.MsgWithTimeStamp[gossipv1.SignedObservation], inboundObservationBufferSize) g.batchObsvC = makeChannelPair[*common.MsgWithTimeStamp[gossipv1.SignedObservationBatch]](inboundBatchObservationBufferSize) g.msgC = makeChannelPair[*common.MessagePublication](0) g.setC = makeChannelPair[*common.GuardianSet](1) // This needs to be a buffered channel because of a circular dependency between processor and accountant during startup. diff --git a/node/pkg/node/node_test.go b/node/pkg/node/node_test.go index 05b260b4d2..1678544057 100644 --- a/node/pkg/node/node_test.go +++ b/node/pkg/node/node_test.go @@ -374,8 +374,9 @@ var someMsgEmitterChain vaa.ChainID = vaa.ChainIDSolana func someMessage() *common.MessagePublication { someMsgSequenceCounter++ + txID := [32]byte{byte(someMsgSequenceCounter % 8), byte(someMsgSequenceCounter / 8), 3} return &common.MessagePublication{ - TxHash: [32]byte{byte(someMsgSequenceCounter % 8), byte(someMsgSequenceCounter / 8), 3}, + TxID: txID[:], Timestamp: randomTime(), Nonce: math_rand.Uint32(), //nolint Sequence: someMsgSequenceCounter, @@ -439,8 +440,9 @@ func governedMsg(shouldBeDelayed bool) *common.MessagePublication { ) tokenBridgeSequenceCounter++ + txID := [32]byte{byte(tokenBridgeSequenceCounter % 8), byte(tokenBridgeSequenceCounter / 8), 3, 1, 10, 76} return &common.MessagePublication{ - TxHash: [32]byte{byte(tokenBridgeSequenceCounter % 8), byte(tokenBridgeSequenceCounter / 8), 3, 1, 10, 76}, + TxID: txID[:], Timestamp: randomTime(), Nonce: math_rand.Uint32(), //nolint Sequence: tokenBridgeSequenceCounter, @@ -458,7 +460,7 @@ func makeObsDb(tc []testCase) mock.ObservationDb { if t.unavailableInReobservation { continue } - db[t.msg.TxHash] = t.msg + db[eth_common.BytesToHash(t.msg.TxID)] = t.msg } return db } @@ -748,7 +750,7 @@ func runConsensusTests(t *testing.T, testCases []testCase, numGuardians int) { _, err := adminCs[adminRpcGuardianIndex].SendObservationRequest(queryCtx, &nodev1.SendObservationRequestRequest{ ObservationRequest: &gossipv1.ObservationRequest{ ChainId: uint32(testCase.msg.EmitterChain), - TxHash: testCase.msg.TxHash[:], + TxHash: testCase.msg.TxID, }, }) queryCancel() @@ -1146,7 +1148,7 @@ func BenchmarkCrypto(b *testing.B) { // How to run: // -// go test -v -ldflags '-extldflags "-Wl,--allow-multiple-definition" ' -bench ^BenchmarkConsensus -benchtime=1x -count 1 -run ^$ > bench.log; tail bench.log +// go test -v -bench ^BenchmarkConsensus -benchtime=1x -count 1 -run ^$ > bench.log; tail bench.log func BenchmarkConsensus(b *testing.B) { require.Equal(b, b.N, 1) //CONSOLE_LOG_LEVEL = zap.DebugLevel diff --git a/node/pkg/node/options.go b/node/pkg/node/options.go index a5b46e2d0a..be1bdb4d37 100644 --- a/node/pkg/node/options.go +++ b/node/pkg/node/options.go @@ -83,7 +83,6 @@ func GuardianOptionP2P( p2p.WithGuardianOptions( nodeName, g.guardianSigner, - g.obsvC, g.batchObsvC.writeC, signedInC, g.obsvReqC.writeC, @@ -353,7 +352,7 @@ func GuardianOptionWatchers(watcherConfigs []watchers.WatcherConfig, ibcWatcherC level = zapcore.ErrorLevel } logger.Log(level, "SECURITY CRITICAL: Received observation from a chain that was not marked as originating from that chain", - zap.Stringer("tx", msg.TxHash), + zap.String("tx", msg.TxIDString()), zap.Stringer("emitter_address", msg.EmitterAddress), zap.Uint64("sequence", msg.Sequence), zap.Stringer("msgChainId", msg.EmitterChain), @@ -368,7 +367,7 @@ func GuardianOptionWatchers(watcherConfigs []watchers.WatcherConfig, ibcWatcherC level = zapcore.ErrorLevel } logger.Log(level, "SECURITY ERROR: Received observation with EmitterAddress == 0x00", - zap.Stringer("tx", msg.TxHash), + zap.String("tx", msg.TxIDString()), zap.Stringer("emitter_address", msg.EmitterAddress), zap.Uint64("sequence", msg.Sequence), zap.Stringer("msgChainId", msg.EmitterChain), @@ -380,7 +379,7 @@ func GuardianOptionWatchers(watcherConfigs []watchers.WatcherConfig, ibcWatcherC zap.Stringer("emitter_chain", msg.EmitterChain), zap.Stringer("emitter_address", msg.EmitterAddress), zap.Uint32("nonce", msg.Nonce), - zap.Stringer("txhash", msg.TxHash), + zap.String("txID", msg.TxIDString()), zap.Time("timestamp", msg.Timestamp)) } else { g.msgC.writeC <- msg @@ -593,7 +592,6 @@ func GuardianOptionProcessor(networkId string) *GuardianOption { g.setC.readC, g.gossipAttestationSendC, g.gossipVaaSendC, - g.obsvC, g.batchObsvC.readC, g.obsvReqSendC.writeC, g.signedInC.readC, diff --git a/node/pkg/p2p/p2p.go b/node/pkg/p2p/p2p.go index bde810819e..79ca1fcaaa 100644 --- a/node/pkg/p2p/p2p.go +++ b/node/pkg/p2p/p2p.go @@ -393,7 +393,7 @@ func Run(params *RunParams) func(ctx context.Context) error { } // Set up the attestation channel. //////////////////////////////////////////////////////////////////// - if params.gossipAttestationSendC != nil || params.obsvRecvC != nil || params.batchObsvRecvC != nil { + if params.gossipAttestationSendC != nil || params.batchObsvRecvC != nil { attestationTopic := fmt.Sprintf("%s/%s", params.networkID, "attestation") logger.Info("joining the attestation topic", zap.String("topic", attestationTopic)) attestationPubsubTopic, err = ps.Join(attestationTopic) @@ -407,7 +407,7 @@ func Run(params *RunParams) func(ctx context.Context) error { } }() - if params.obsvRecvC != nil || params.batchObsvRecvC != nil { + if params.batchObsvRecvC != nil { logger.Info("subscribing to the attestation topic", zap.String("topic", attestationTopic)) attestationSubscription, err = attestationPubsubTopic.Subscribe(pubsub.WithBufferSize(P2P_SUBSCRIPTION_BUFFER_SIZE)) if err != nil { @@ -883,17 +883,6 @@ func Run(params *RunParams) func(ctx context.Context) error { } switch m := msg.Message.(type) { - case *gossipv1.GossipMessage_SignedObservation: - if params.obsvRecvC != nil { - if err := common.PostMsgWithTimestamp(m.SignedObservation, params.obsvRecvC); err == nil { - p2pMessagesReceived.WithLabelValues("observation").Inc() - } else { - if params.components.WarnChannelOverflow { - logger.Warn("Ignoring SignedObservation because obsvRecvC is full", zap.String("addr", hex.EncodeToString(m.SignedObservation.Addr))) - } - p2pReceiveChannelOverflow.WithLabelValues("observation").Inc() - } - } case *gossipv1.GossipMessage_SignedObservationBatch: if params.batchObsvRecvC != nil { if err := common.PostMsgWithTimestamp(m.SignedObservationBatch, params.batchObsvRecvC); err == nil { diff --git a/node/pkg/p2p/run_params.go b/node/pkg/p2p/run_params.go index 4cdd05539a..3876471ec7 100644 --- a/node/pkg/p2p/run_params.go +++ b/node/pkg/p2p/run_params.go @@ -23,9 +23,6 @@ type ( gst *common.GuardianSetState rootCtxCancel context.CancelFunc - // obsvRecvC is optional and can be set with `WithSignedObservationListener`. - obsvRecvC chan<- *common.MsgWithTimeStamp[gossipv1.SignedObservation] - // batchObsvRecvC is optional and can be set with `WithSignedObservationBatchListener`. batchObsvRecvC chan<- *common.MsgWithTimeStamp[gossipv1.SignedObservationBatch] @@ -117,14 +114,6 @@ func WithProcessorFeaturesFunc(processorFeaturesFunc func() string) RunOpt { } } -// WithSignedObservationListener is used to set the channel to receive `SignedObservation` messages. -func WithSignedObservationListener(obsvRecvC chan<- *common.MsgWithTimeStamp[gossipv1.SignedObservation]) RunOpt { - return func(p *RunParams) error { - p.obsvRecvC = obsvRecvC - return nil - } -} - // WithSignedObservationBatchListener is used to set the channel to receive `SignedObservationBatch` messages. func WithSignedObservationBatchListener(batchObsvC chan<- *common.MsgWithTimeStamp[gossipv1.SignedObservationBatch]) RunOpt { return func(p *RunParams) error { @@ -177,7 +166,6 @@ func WithDisableHeartbeatVerify(disableHeartbeatVerify bool) RunOpt { func WithGuardianOptions( nodeName string, guardianSigner guardiansigner.GuardianSigner, - obsvRecvC chan<- *common.MsgWithTimeStamp[gossipv1.SignedObservation], batchObsvRecvC chan<- *common.MsgWithTimeStamp[gossipv1.SignedObservationBatch], signedIncomingVaaRecvC chan<- *gossipv1.SignedVAAWithQuorum, obsvReqRecvC chan<- *gossipv1.ObservationRequest, @@ -201,7 +189,6 @@ func WithGuardianOptions( return func(p *RunParams) error { p.nodeName = nodeName p.guardianSigner = guardianSigner - p.obsvRecvC = obsvRecvC p.batchObsvRecvC = batchObsvRecvC p.signedIncomingVaaRecvC = signedIncomingVaaRecvC p.obsvReqRecvC = obsvReqRecvC diff --git a/node/pkg/p2p/run_params_test.go b/node/pkg/p2p/run_params_test.go index 99903d79fc..103470f541 100644 --- a/node/pkg/p2p/run_params_test.go +++ b/node/pkg/p2p/run_params_test.go @@ -138,7 +138,6 @@ func TestRunParamsWithGuardianOptions(t *testing.T) { require.NoError(t, err) require.NotNil(t, guardianSigner) - obsvC := make(chan<- *common.MsgWithTimeStamp[gossipv1.SignedObservation], 42) batchObsvC := make(chan<- *common.MsgWithTimeStamp[gossipv1.SignedObservationBatch], 42) signedInC := make(chan<- *gossipv1.SignedVAAWithQuorum, 42) obsvReqC := make(chan<- *gossipv1.ObservationRequest, 42) @@ -170,7 +169,6 @@ func TestRunParamsWithGuardianOptions(t *testing.T) { WithGuardianOptions( nodeName, guardianSigner, - obsvC, batchObsvC, signedInC, obsvReqC, @@ -195,7 +193,6 @@ func TestRunParamsWithGuardianOptions(t *testing.T) { require.NoError(t, err) require.NotNil(t, params) assert.Equal(t, nodeName, params.nodeName) - assert.Equal(t, obsvC, params.obsvRecvC) assert.Equal(t, signedInC, params.signedIncomingVaaRecvC) assert.Equal(t, obsvReqC, params.obsvReqRecvC) assert.Equal(t, gossipControlSendC, params.gossipControlSendC) diff --git a/node/pkg/p2p/watermark_test.go b/node/pkg/p2p/watermark_test.go index 7c99ede7c9..aa5365dd42 100644 --- a/node/pkg/p2p/watermark_test.go +++ b/node/pkg/p2p/watermark_test.go @@ -26,7 +26,6 @@ const LOCAL_P2P_PORTRANGE_START = 11000 type G struct { // arguments passed to p2p.New - obsvC chan *node_common.MsgWithTimeStamp[gossipv1.SignedObservation] batchObsvC chan *node_common.MsgWithTimeStamp[gossipv1.SignedObservationBatch] obsvReqC chan *gossipv1.ObservationRequest obsvReqSendC chan *gossipv1.ObservationRequest @@ -66,7 +65,6 @@ func NewG(t *testing.T, nodeName string) *G { _, rootCtxCancel := context.WithCancel(context.Background()) g := &G{ - obsvC: make(chan *node_common.MsgWithTimeStamp[gossipv1.SignedObservation], cs), batchObsvC: make(chan *node_common.MsgWithTimeStamp[gossipv1.SignedObservationBatch], cs), obsvReqC: make(chan *gossipv1.ObservationRequest, cs), obsvReqSendC: make(chan *gossipv1.ObservationRequest, cs), @@ -91,7 +89,6 @@ func NewG(t *testing.T, nodeName string) *G { name := g.nodeName t.Logf("[%s] consuming\n", name) select { - case <-g.obsvC: case <-g.obsvReqC: case <-g.signedInC: case <-g.signedGovCfg: @@ -182,7 +179,6 @@ func startGuardian(t *testing.T, ctx context.Context, g *G) { WithGuardianOptions( g.nodeName, g.guardianSigner, - g.obsvC, g.batchObsvC, g.signedInC, g.obsvReqC, diff --git a/node/pkg/processor/batch_obs_test.go b/node/pkg/processor/batch_obs_test.go index 381fd985ca..6391dcb804 100644 --- a/node/pkg/processor/batch_obs_test.go +++ b/node/pkg/processor/batch_obs_test.go @@ -8,7 +8,6 @@ import ( "github.com/certusone/wormhole/node/pkg/devnet" "github.com/certusone/wormhole/node/pkg/p2p" gossipv1 "github.com/certusone/wormhole/node/pkg/proto/gossip/v1" - ethcommon "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/crypto" pubsub "github.com/libp2p/go-libp2p-pubsub" "github.com/stretchr/testify/assert" @@ -43,6 +42,7 @@ func TestMarshalSignedObservationBatch(t *testing.T) { NumObservations := uint64(p2p.MaxObservationBatchSize) observations := make([]*gossipv1.Observation, 0, NumObservations) + txHash := []byte("0123456789012345678901234567890123456789012345678901234567890123") // 64 bytes, the size of a Solana signature. for seqNo := uint64(1); seqNo <= NumObservations; seqNo++ { vaa := getUniqueVAA(seqNo) digest := vaa.SigningDigest() @@ -52,14 +52,14 @@ func TestMarshalSignedObservationBatch(t *testing.T) { observations = append(observations, &gossipv1.Observation{ Hash: digest.Bytes(), Signature: sig, - TxHash: ethcommon.HexToHash("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063").Bytes(), + TxHash: txHash, MessageId: vaa.MessageID(), }) } obsBuf, err := proto.Marshal(observations[0]) require.NoError(t, err) - assert.Equal(t, 205, len(obsBuf)) + assert.Equal(t, (173 + len(txHash)), len(obsBuf)) batch := gossipv1.SignedObservationBatch{ Addr: crypto.PubkeyToAddress(gk.PublicKey).Bytes(), diff --git a/node/pkg/processor/benchmark_test.go b/node/pkg/processor/benchmark_test.go index c85fe5031b..1cb94a49e7 100644 --- a/node/pkg/processor/benchmark_test.go +++ b/node/pkg/processor/benchmark_test.go @@ -194,7 +194,7 @@ func createProcessorForTest(b *testing.B, numVAAs int, ctx context.Context, db * func (pd *ProcessorData) createMessagePublication(b *testing.B, sequence uint64) *common.MessagePublication { b.Helper() return &common.MessagePublication{ - TxHash: ethCommon.HexToHash(fmt.Sprintf("%064x", sequence)), + TxID: ethCommon.HexToHash(fmt.Sprintf("%064x", sequence)).Bytes(), Timestamp: time.Now(), Nonce: 42, Sequence: sequence, @@ -235,7 +235,7 @@ func (pd *ProcessorData) createObservation(b *testing.B, guardianIdx int, k *com return &gossipv1.Observation{ Hash: digest.Bytes(), Signature: signature, - TxHash: k.TxHash.Bytes(), + TxHash: k.TxID, MessageId: pd.messageID(k.Sequence), } } diff --git a/node/pkg/processor/message.go b/node/pkg/processor/message.go index 929f951760..ec67aae0fe 100644 --- a/node/pkg/processor/message.go +++ b/node/pkg/processor/message.go @@ -37,7 +37,7 @@ func (p *Processor) handleMessage(ctx context.Context, k *common.MessagePublicat p.logger.Warn("dropping observation since we haven't initialized our guardian set yet", zap.String("message_id", k.MessageIDString()), zap.Uint32("nonce", k.Nonce), - zap.Stringer("txhash", k.TxHash), + zap.String("txID", k.TxIDString()), zap.Time("timestamp", k.Timestamp), ) return @@ -80,8 +80,8 @@ func (p *Processor) handleMessage(ctx context.Context, k *common.MessagePublicat if p.logger.Core().Enabled(zapcore.DebugLevel) { p.logger.Debug("observed and signed confirmed message publication", zap.String("message_id", k.MessageIDString()), - zap.Stringer("txhash", k.TxHash), - zap.String("txhash_b58", base58.Encode(k.TxHash.Bytes())), + zap.String("txID", k.TxIDString()), + zap.String("txID_b58", base58.Encode(k.TxID)), zap.String("hash", hash), zap.Uint32("nonce", k.Nonce), zap.Time("timestamp", k.Timestamp), @@ -93,7 +93,7 @@ func (p *Processor) handleMessage(ctx context.Context, k *common.MessagePublicat } // Broadcast the signature. - ourObs, msg := p.broadcastSignature(v.MessageID(), k.TxHash.Bytes(), digest, signature, shouldPublishImmediately) + ourObs, msg := p.broadcastSignature(v.MessageID(), k.TxID, digest, signature, shouldPublishImmediately) // Indicate that we observed this one. observationsReceivedTotal.Inc() @@ -114,7 +114,7 @@ func (p *Processor) handleMessage(ctx context.Context, k *common.MessagePublicat // Update our state. s.ourObservation = v - s.txHash = k.TxHash.Bytes() + s.txHash = k.TxID s.source = v.GetEmitterChain().String() s.gs = p.gs // guaranteed to match ourObservation - there's no concurrent access to p.gs s.signatures[p.ourAddr] = signature diff --git a/node/pkg/processor/observation.go b/node/pkg/processor/observation.go index 3fcea6318d..cd71330611 100644 --- a/node/pkg/processor/observation.go +++ b/node/pkg/processor/observation.go @@ -75,18 +75,6 @@ func (p *Processor) handleBatchObservation(m *node_common.MsgWithTimeStamp[gossi batchObservationTotalDelay.Observe(float64(time.Since(m.Timestamp).Microseconds())) } -// handleObservation processes a remote VAA observation. -func (p *Processor) handleObservation(m *node_common.MsgWithTimeStamp[gossipv1.SignedObservation]) { - obs := gossipv1.Observation{ - Hash: m.Msg.Hash, - Signature: m.Msg.Signature, - TxHash: m.Msg.TxHash, - MessageId: m.Msg.MessageId, - } - p.handleSingleObservation(m.Msg.Addr, &obs) - observationTotalDelay.Observe(float64(time.Since(m.Timestamp).Microseconds())) -} - // handleObservation processes a remote VAA observation, verifies it, checks whether the VAA has met quorum, and assembles and submits a valid VAA if possible. func (p *Processor) handleSingleObservation(addr []byte, m *gossipv1.Observation) { // SECURITY: at this point, observations received from the p2p network are fully untrusted (all fields!) @@ -197,7 +185,7 @@ func (p *Processor) handleSingleObservation(addr []byte, m *gossipv1.Observation return } - // Hooray! Now, we have verified all fields on SignedObservation and know that it includes + // Hooray! Now, we have verified all fields on the observation and know that it includes // a valid signature by an active guardian. We still don't fully trust them, as they may be // byzantine, but now we know who we're dealing with. diff --git a/node/pkg/processor/processor.go b/node/pkg/processor/processor.go index 87d6aebee4..44212d26d7 100644 --- a/node/pkg/processor/processor.go +++ b/node/pkg/processor/processor.go @@ -114,9 +114,6 @@ type Processor struct { // gossipVaaSendC is a channel of outbound VAA messages to broadcast on p2p gossipVaaSendC chan<- []byte - // obsvC is a channel of inbound decoded observations from p2p - obsvC chan *common.MsgWithTimeStamp[gossipv1.SignedObservation] - // batchObsvC is a channel of inbound decoded batches of observations from p2p batchObsvC <-chan *common.MsgWithTimeStamp[gossipv1.SignedObservationBatch] @@ -166,20 +163,6 @@ type updateVaaEntry struct { } var ( - observationChanDelay = promauto.NewHistogram( - prometheus.HistogramOpts{ - Name: "wormhole_signed_observation_channel_delay_us", - Help: "Latency histogram for delay of signed observations in channel", - Buckets: []float64{10.0, 20.0, 50.0, 100.0, 1000.0, 5000.0, 10000.0, 100_000.0, 1_000_000.0, 10_000_000.0, 100_000_000.0, 1_000_000_000.0}, - }) - - observationTotalDelay = promauto.NewHistogram( - prometheus.HistogramOpts{ - Name: "wormhole_signed_observation_total_delay_us", - Help: "Latency histogram for total time to process signed observations", - Buckets: []float64{10.0, 20.0, 50.0, 100.0, 1000.0, 5000.0, 10_000.0, 100_000.0, 1_000_000.0, 10_000_000.0, 100_000_000.0, 1_000_000_000.0}, - }) - batchObservationChanDelay = promauto.NewHistogram( prometheus.HistogramOpts{ Name: "wormhole_batch_observation_channel_delay_us", @@ -225,7 +208,6 @@ func NewProcessor( setC <-chan *common.GuardianSet, gossipAttestationSendC chan<- []byte, gossipVaaSendC chan<- []byte, - obsvC chan *common.MsgWithTimeStamp[gossipv1.SignedObservation], batchObsvC <-chan *common.MsgWithTimeStamp[gossipv1.SignedObservationBatch], obsvReqSendC chan<- *gossipv1.ObservationRequest, signedInC <-chan *gossipv1.SignedVAAWithQuorum, @@ -243,7 +225,6 @@ func NewProcessor( setC: setC, gossipAttestationSendC: gossipAttestationSendC, gossipVaaSendC: gossipVaaSendC, - obsvC: obsvC, batchObsvC: batchObsvC, obsvReqSendC: obsvReqSendC, signedInC: signedInC, @@ -319,9 +300,6 @@ func (p *Processor) Run(ctx context.Context) error { return fmt.Errorf("accountant published a message that is not covered by it: `%s`", k.MessageIDString()) } p.handleMessage(ctx, k) - case m := <-p.obsvC: - observationChanDelay.Observe(float64(time.Since(m.Timestamp).Microseconds())) - p.handleObservation(m) case m := <-p.batchObsvC: batchObservationChanDelay.Observe(float64(time.Since(m.Timestamp).Microseconds())) p.handleBatchObservation(m) diff --git a/node/pkg/proto/gossip/v1/gossip.pb.go b/node/pkg/proto/gossip/v1/gossip.pb.go index f41bcc34e9..7487b1bd1e 100644 --- a/node/pkg/proto/gossip/v1/gossip.pb.go +++ b/node/pkg/proto/gossip/v1/gossip.pb.go @@ -27,7 +27,6 @@ type GossipMessage struct { // Types that are assignable to Message: // - // *GossipMessage_SignedObservation // *GossipMessage_SignedHeartbeat // *GossipMessage_SignedVaaWithQuorum // *GossipMessage_SignedObservationRequest @@ -78,13 +77,6 @@ func (m *GossipMessage) GetMessage() isGossipMessage_Message { return nil } -func (x *GossipMessage) GetSignedObservation() *SignedObservation { - if x, ok := x.GetMessage().(*GossipMessage_SignedObservation); ok { - return x.SignedObservation - } - return nil -} - func (x *GossipMessage) GetSignedHeartbeat() *SignedHeartbeat { if x, ok := x.GetMessage().(*GossipMessage_SignedHeartbeat); ok { return x.SignedHeartbeat @@ -145,11 +137,8 @@ type isGossipMessage_Message interface { isGossipMessage_Message() } -type GossipMessage_SignedObservation struct { - SignedObservation *SignedObservation `protobuf:"bytes,2,opt,name=signed_observation,json=signedObservation,proto3,oneof"` -} - type GossipMessage_SignedHeartbeat struct { + // SignedObservation signed_observation = 2; SignedHeartbeat *SignedHeartbeat `protobuf:"bytes,3,opt,name=signed_heartbeat,json=signedHeartbeat,proto3,oneof"` } @@ -181,8 +170,6 @@ type GossipMessage_SignedObservationBatch struct { SignedObservationBatch *SignedObservationBatch `protobuf:"bytes,12,opt,name=signed_observation_batch,json=signedObservationBatch,proto3,oneof"` } -func (*GossipMessage_SignedObservation) isGossipMessage_Message() {} - func (*GossipMessage_SignedHeartbeat) isGossipMessage_Message() {} func (*GossipMessage_SignedVaaWithQuorum) isGossipMessage_Message() {} @@ -387,105 +374,6 @@ func (x *Heartbeat) GetP2PNodeId() []byte { return nil } -// A SignedObservation is a signed statement by a given guardian node -// that they observed a given event. -// -// Observations always result from an external, final event being observed. -// Examples are emitted messages in finalized blocks on a block or guardian set changes -// injected by node operators after reaching off-chain consensus. -// -// The event is uniquely identified by its hashed (tx_hash, nonce, values...) tuple. -// -// Other nodes will verify the signature. Once any node has observed a quorum of -// guardians submitting valid signatures for a given hash, they can be assembled into a VAA. -// -// Messages without valid signature are dropped unceremoniously. -type SignedObservation struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // Guardian pubkey as truncated eth address. - Addr []byte `protobuf:"bytes,1,opt,name=addr,proto3" json:"addr,omitempty"` - // The observation's deterministic, unique hash. - Hash []byte `protobuf:"bytes,2,opt,name=hash,proto3" json:"hash,omitempty"` - // ECSDA signature of the hash using the node's guardian key. - Signature []byte `protobuf:"bytes,3,opt,name=signature,proto3" json:"signature,omitempty"` - // Transaction hash this observation was made from. - // Optional, included for observability. - TxHash []byte `protobuf:"bytes,4,opt,name=tx_hash,json=txHash,proto3" json:"tx_hash,omitempty"` - // Message ID (chain/emitter/seq) for this observation. - // Optional, included for observability. - MessageId string `protobuf:"bytes,5,opt,name=message_id,json=messageId,proto3" json:"message_id,omitempty"` -} - -func (x *SignedObservation) Reset() { - *x = SignedObservation{} - if protoimpl.UnsafeEnabled { - mi := &file_gossip_v1_gossip_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *SignedObservation) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*SignedObservation) ProtoMessage() {} - -func (x *SignedObservation) ProtoReflect() protoreflect.Message { - mi := &file_gossip_v1_gossip_proto_msgTypes[3] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use SignedObservation.ProtoReflect.Descriptor instead. -func (*SignedObservation) Descriptor() ([]byte, []int) { - return file_gossip_v1_gossip_proto_rawDescGZIP(), []int{3} -} - -func (x *SignedObservation) GetAddr() []byte { - if x != nil { - return x.Addr - } - return nil -} - -func (x *SignedObservation) GetHash() []byte { - if x != nil { - return x.Hash - } - return nil -} - -func (x *SignedObservation) GetSignature() []byte { - if x != nil { - return x.Signature - } - return nil -} - -func (x *SignedObservation) GetTxHash() []byte { - if x != nil { - return x.TxHash - } - return nil -} - -func (x *SignedObservation) GetMessageId() string { - if x != nil { - return x.MessageId - } - return "" -} - // A SignedVAAWithQuorum message is sent by nodes whenever one of the VAAs they observed // reached a 2/3+ quorum to be considered valid. Signed VAAs are broadcasted to the gossip // network to allow nodes to persist them even if they failed to observe the signature. @@ -500,7 +388,7 @@ type SignedVAAWithQuorum struct { func (x *SignedVAAWithQuorum) Reset() { *x = SignedVAAWithQuorum{} if protoimpl.UnsafeEnabled { - mi := &file_gossip_v1_gossip_proto_msgTypes[4] + mi := &file_gossip_v1_gossip_proto_msgTypes[3] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -513,7 +401,7 @@ func (x *SignedVAAWithQuorum) String() string { func (*SignedVAAWithQuorum) ProtoMessage() {} func (x *SignedVAAWithQuorum) ProtoReflect() protoreflect.Message { - mi := &file_gossip_v1_gossip_proto_msgTypes[4] + mi := &file_gossip_v1_gossip_proto_msgTypes[3] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -526,7 +414,7 @@ func (x *SignedVAAWithQuorum) ProtoReflect() protoreflect.Message { // Deprecated: Use SignedVAAWithQuorum.ProtoReflect.Descriptor instead. func (*SignedVAAWithQuorum) Descriptor() ([]byte, []int) { - return file_gossip_v1_gossip_proto_rawDescGZIP(), []int{4} + return file_gossip_v1_gossip_proto_rawDescGZIP(), []int{3} } func (x *SignedVAAWithQuorum) GetVaa() []byte { @@ -557,7 +445,7 @@ type SignedObservationRequest struct { func (x *SignedObservationRequest) Reset() { *x = SignedObservationRequest{} if protoimpl.UnsafeEnabled { - mi := &file_gossip_v1_gossip_proto_msgTypes[5] + mi := &file_gossip_v1_gossip_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -570,7 +458,7 @@ func (x *SignedObservationRequest) String() string { func (*SignedObservationRequest) ProtoMessage() {} func (x *SignedObservationRequest) ProtoReflect() protoreflect.Message { - mi := &file_gossip_v1_gossip_proto_msgTypes[5] + mi := &file_gossip_v1_gossip_proto_msgTypes[4] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -583,7 +471,7 @@ func (x *SignedObservationRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use SignedObservationRequest.ProtoReflect.Descriptor instead. func (*SignedObservationRequest) Descriptor() ([]byte, []int) { - return file_gossip_v1_gossip_proto_rawDescGZIP(), []int{5} + return file_gossip_v1_gossip_proto_rawDescGZIP(), []int{4} } func (x *SignedObservationRequest) GetObservationRequest() []byte { @@ -619,7 +507,7 @@ type ObservationRequest struct { func (x *ObservationRequest) Reset() { *x = ObservationRequest{} if protoimpl.UnsafeEnabled { - mi := &file_gossip_v1_gossip_proto_msgTypes[6] + mi := &file_gossip_v1_gossip_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -632,7 +520,7 @@ func (x *ObservationRequest) String() string { func (*ObservationRequest) ProtoMessage() {} func (x *ObservationRequest) ProtoReflect() protoreflect.Message { - mi := &file_gossip_v1_gossip_proto_msgTypes[6] + mi := &file_gossip_v1_gossip_proto_msgTypes[5] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -645,7 +533,7 @@ func (x *ObservationRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ObservationRequest.ProtoReflect.Descriptor instead. func (*ObservationRequest) Descriptor() ([]byte, []int) { - return file_gossip_v1_gossip_proto_rawDescGZIP(), []int{6} + return file_gossip_v1_gossip_proto_rawDescGZIP(), []int{5} } func (x *ObservationRequest) GetChainId() uint32 { @@ -679,7 +567,7 @@ type SignedChainGovernorConfig struct { func (x *SignedChainGovernorConfig) Reset() { *x = SignedChainGovernorConfig{} if protoimpl.UnsafeEnabled { - mi := &file_gossip_v1_gossip_proto_msgTypes[7] + mi := &file_gossip_v1_gossip_proto_msgTypes[6] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -692,7 +580,7 @@ func (x *SignedChainGovernorConfig) String() string { func (*SignedChainGovernorConfig) ProtoMessage() {} func (x *SignedChainGovernorConfig) ProtoReflect() protoreflect.Message { - mi := &file_gossip_v1_gossip_proto_msgTypes[7] + mi := &file_gossip_v1_gossip_proto_msgTypes[6] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -705,7 +593,7 @@ func (x *SignedChainGovernorConfig) ProtoReflect() protoreflect.Message { // Deprecated: Use SignedChainGovernorConfig.ProtoReflect.Descriptor instead. func (*SignedChainGovernorConfig) Descriptor() ([]byte, []int) { - return file_gossip_v1_gossip_proto_rawDescGZIP(), []int{7} + return file_gossip_v1_gossip_proto_rawDescGZIP(), []int{6} } func (x *SignedChainGovernorConfig) GetConfig() []byte { @@ -745,7 +633,7 @@ type ChainGovernorConfig struct { func (x *ChainGovernorConfig) Reset() { *x = ChainGovernorConfig{} if protoimpl.UnsafeEnabled { - mi := &file_gossip_v1_gossip_proto_msgTypes[8] + mi := &file_gossip_v1_gossip_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -758,7 +646,7 @@ func (x *ChainGovernorConfig) String() string { func (*ChainGovernorConfig) ProtoMessage() {} func (x *ChainGovernorConfig) ProtoReflect() protoreflect.Message { - mi := &file_gossip_v1_gossip_proto_msgTypes[8] + mi := &file_gossip_v1_gossip_proto_msgTypes[7] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -771,7 +659,7 @@ func (x *ChainGovernorConfig) ProtoReflect() protoreflect.Message { // Deprecated: Use ChainGovernorConfig.ProtoReflect.Descriptor instead. func (*ChainGovernorConfig) Descriptor() ([]byte, []int) { - return file_gossip_v1_gossip_proto_rawDescGZIP(), []int{8} + return file_gossip_v1_gossip_proto_rawDescGZIP(), []int{7} } func (x *ChainGovernorConfig) GetNodeName() string { @@ -833,7 +721,7 @@ type SignedChainGovernorStatus struct { func (x *SignedChainGovernorStatus) Reset() { *x = SignedChainGovernorStatus{} if protoimpl.UnsafeEnabled { - mi := &file_gossip_v1_gossip_proto_msgTypes[9] + mi := &file_gossip_v1_gossip_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -846,7 +734,7 @@ func (x *SignedChainGovernorStatus) String() string { func (*SignedChainGovernorStatus) ProtoMessage() {} func (x *SignedChainGovernorStatus) ProtoReflect() protoreflect.Message { - mi := &file_gossip_v1_gossip_proto_msgTypes[9] + mi := &file_gossip_v1_gossip_proto_msgTypes[8] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -859,7 +747,7 @@ func (x *SignedChainGovernorStatus) ProtoReflect() protoreflect.Message { // Deprecated: Use SignedChainGovernorStatus.ProtoReflect.Descriptor instead. func (*SignedChainGovernorStatus) Descriptor() ([]byte, []int) { - return file_gossip_v1_gossip_proto_rawDescGZIP(), []int{9} + return file_gossip_v1_gossip_proto_rawDescGZIP(), []int{8} } func (x *SignedChainGovernorStatus) GetStatus() []byte { @@ -897,7 +785,7 @@ type ChainGovernorStatus struct { func (x *ChainGovernorStatus) Reset() { *x = ChainGovernorStatus{} if protoimpl.UnsafeEnabled { - mi := &file_gossip_v1_gossip_proto_msgTypes[10] + mi := &file_gossip_v1_gossip_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -910,7 +798,7 @@ func (x *ChainGovernorStatus) String() string { func (*ChainGovernorStatus) ProtoMessage() {} func (x *ChainGovernorStatus) ProtoReflect() protoreflect.Message { - mi := &file_gossip_v1_gossip_proto_msgTypes[10] + mi := &file_gossip_v1_gossip_proto_msgTypes[9] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -923,7 +811,7 @@ func (x *ChainGovernorStatus) ProtoReflect() protoreflect.Message { // Deprecated: Use ChainGovernorStatus.ProtoReflect.Descriptor instead. func (*ChainGovernorStatus) Descriptor() ([]byte, []int) { - return file_gossip_v1_gossip_proto_rawDescGZIP(), []int{10} + return file_gossip_v1_gossip_proto_rawDescGZIP(), []int{9} } func (x *ChainGovernorStatus) GetNodeName() string { @@ -968,7 +856,7 @@ type SignedQueryRequest struct { func (x *SignedQueryRequest) Reset() { *x = SignedQueryRequest{} if protoimpl.UnsafeEnabled { - mi := &file_gossip_v1_gossip_proto_msgTypes[11] + mi := &file_gossip_v1_gossip_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -981,7 +869,7 @@ func (x *SignedQueryRequest) String() string { func (*SignedQueryRequest) ProtoMessage() {} func (x *SignedQueryRequest) ProtoReflect() protoreflect.Message { - mi := &file_gossip_v1_gossip_proto_msgTypes[11] + mi := &file_gossip_v1_gossip_proto_msgTypes[10] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -994,7 +882,7 @@ func (x *SignedQueryRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use SignedQueryRequest.ProtoReflect.Descriptor instead. func (*SignedQueryRequest) Descriptor() ([]byte, []int) { - return file_gossip_v1_gossip_proto_rawDescGZIP(), []int{11} + return file_gossip_v1_gossip_proto_rawDescGZIP(), []int{10} } func (x *SignedQueryRequest) GetQueryRequest() []byte { @@ -1025,7 +913,7 @@ type SignedQueryResponse struct { func (x *SignedQueryResponse) Reset() { *x = SignedQueryResponse{} if protoimpl.UnsafeEnabled { - mi := &file_gossip_v1_gossip_proto_msgTypes[12] + mi := &file_gossip_v1_gossip_proto_msgTypes[11] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1038,7 +926,7 @@ func (x *SignedQueryResponse) String() string { func (*SignedQueryResponse) ProtoMessage() {} func (x *SignedQueryResponse) ProtoReflect() protoreflect.Message { - mi := &file_gossip_v1_gossip_proto_msgTypes[12] + mi := &file_gossip_v1_gossip_proto_msgTypes[11] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1051,7 +939,7 @@ func (x *SignedQueryResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use SignedQueryResponse.ProtoReflect.Descriptor instead. func (*SignedQueryResponse) Descriptor() ([]byte, []int) { - return file_gossip_v1_gossip_proto_rawDescGZIP(), []int{12} + return file_gossip_v1_gossip_proto_rawDescGZIP(), []int{11} } func (x *SignedQueryResponse) GetQueryResponse() []byte { @@ -1084,7 +972,7 @@ type SignedObservationBatch struct { func (x *SignedObservationBatch) Reset() { *x = SignedObservationBatch{} if protoimpl.UnsafeEnabled { - mi := &file_gossip_v1_gossip_proto_msgTypes[13] + mi := &file_gossip_v1_gossip_proto_msgTypes[12] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1097,7 +985,7 @@ func (x *SignedObservationBatch) String() string { func (*SignedObservationBatch) ProtoMessage() {} func (x *SignedObservationBatch) ProtoReflect() protoreflect.Message { - mi := &file_gossip_v1_gossip_proto_msgTypes[13] + mi := &file_gossip_v1_gossip_proto_msgTypes[12] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1110,7 +998,7 @@ func (x *SignedObservationBatch) ProtoReflect() protoreflect.Message { // Deprecated: Use SignedObservationBatch.ProtoReflect.Descriptor instead. func (*SignedObservationBatch) Descriptor() ([]byte, []int) { - return file_gossip_v1_gossip_proto_rawDescGZIP(), []int{13} + return file_gossip_v1_gossip_proto_rawDescGZIP(), []int{12} } func (x *SignedObservationBatch) GetAddr() []byte { @@ -1148,7 +1036,7 @@ type Observation struct { func (x *Observation) Reset() { *x = Observation{} if protoimpl.UnsafeEnabled { - mi := &file_gossip_v1_gossip_proto_msgTypes[14] + mi := &file_gossip_v1_gossip_proto_msgTypes[13] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1161,7 +1049,7 @@ func (x *Observation) String() string { func (*Observation) ProtoMessage() {} func (x *Observation) ProtoReflect() protoreflect.Message { - mi := &file_gossip_v1_gossip_proto_msgTypes[14] + mi := &file_gossip_v1_gossip_proto_msgTypes[13] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1174,7 +1062,7 @@ func (x *Observation) ProtoReflect() protoreflect.Message { // Deprecated: Use Observation.ProtoReflect.Descriptor instead. func (*Observation) Descriptor() ([]byte, []int) { - return file_gossip_v1_gossip_proto_rawDescGZIP(), []int{14} + return file_gossip_v1_gossip_proto_rawDescGZIP(), []int{13} } func (x *Observation) GetHash() []byte { @@ -1227,7 +1115,7 @@ type Heartbeat_Network struct { func (x *Heartbeat_Network) Reset() { *x = Heartbeat_Network{} if protoimpl.UnsafeEnabled { - mi := &file_gossip_v1_gossip_proto_msgTypes[15] + mi := &file_gossip_v1_gossip_proto_msgTypes[14] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1240,7 +1128,7 @@ func (x *Heartbeat_Network) String() string { func (*Heartbeat_Network) ProtoMessage() {} func (x *Heartbeat_Network) ProtoReflect() protoreflect.Message { - mi := &file_gossip_v1_gossip_proto_msgTypes[15] + mi := &file_gossip_v1_gossip_proto_msgTypes[14] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1311,7 +1199,7 @@ type ChainGovernorConfig_Chain struct { func (x *ChainGovernorConfig_Chain) Reset() { *x = ChainGovernorConfig_Chain{} if protoimpl.UnsafeEnabled { - mi := &file_gossip_v1_gossip_proto_msgTypes[16] + mi := &file_gossip_v1_gossip_proto_msgTypes[15] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1324,7 +1212,7 @@ func (x *ChainGovernorConfig_Chain) String() string { func (*ChainGovernorConfig_Chain) ProtoMessage() {} func (x *ChainGovernorConfig_Chain) ProtoReflect() protoreflect.Message { - mi := &file_gossip_v1_gossip_proto_msgTypes[16] + mi := &file_gossip_v1_gossip_proto_msgTypes[15] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1337,7 +1225,7 @@ func (x *ChainGovernorConfig_Chain) ProtoReflect() protoreflect.Message { // Deprecated: Use ChainGovernorConfig_Chain.ProtoReflect.Descriptor instead. func (*ChainGovernorConfig_Chain) Descriptor() ([]byte, []int) { - return file_gossip_v1_gossip_proto_rawDescGZIP(), []int{8, 0} + return file_gossip_v1_gossip_proto_rawDescGZIP(), []int{7, 0} } func (x *ChainGovernorConfig_Chain) GetChainId() uint32 { @@ -1374,7 +1262,7 @@ type ChainGovernorConfig_Token struct { func (x *ChainGovernorConfig_Token) Reset() { *x = ChainGovernorConfig_Token{} if protoimpl.UnsafeEnabled { - mi := &file_gossip_v1_gossip_proto_msgTypes[17] + mi := &file_gossip_v1_gossip_proto_msgTypes[16] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1387,7 +1275,7 @@ func (x *ChainGovernorConfig_Token) String() string { func (*ChainGovernorConfig_Token) ProtoMessage() {} func (x *ChainGovernorConfig_Token) ProtoReflect() protoreflect.Message { - mi := &file_gossip_v1_gossip_proto_msgTypes[17] + mi := &file_gossip_v1_gossip_proto_msgTypes[16] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1400,7 +1288,7 @@ func (x *ChainGovernorConfig_Token) ProtoReflect() protoreflect.Message { // Deprecated: Use ChainGovernorConfig_Token.ProtoReflect.Descriptor instead. func (*ChainGovernorConfig_Token) Descriptor() ([]byte, []int) { - return file_gossip_v1_gossip_proto_rawDescGZIP(), []int{8, 1} + return file_gossip_v1_gossip_proto_rawDescGZIP(), []int{7, 1} } func (x *ChainGovernorConfig_Token) GetOriginChainId() uint32 { @@ -1438,7 +1326,7 @@ type ChainGovernorStatus_EnqueuedVAA struct { func (x *ChainGovernorStatus_EnqueuedVAA) Reset() { *x = ChainGovernorStatus_EnqueuedVAA{} if protoimpl.UnsafeEnabled { - mi := &file_gossip_v1_gossip_proto_msgTypes[18] + mi := &file_gossip_v1_gossip_proto_msgTypes[17] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1451,7 +1339,7 @@ func (x *ChainGovernorStatus_EnqueuedVAA) String() string { func (*ChainGovernorStatus_EnqueuedVAA) ProtoMessage() {} func (x *ChainGovernorStatus_EnqueuedVAA) ProtoReflect() protoreflect.Message { - mi := &file_gossip_v1_gossip_proto_msgTypes[18] + mi := &file_gossip_v1_gossip_proto_msgTypes[17] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1464,7 +1352,7 @@ func (x *ChainGovernorStatus_EnqueuedVAA) ProtoReflect() protoreflect.Message { // Deprecated: Use ChainGovernorStatus_EnqueuedVAA.ProtoReflect.Descriptor instead. func (*ChainGovernorStatus_EnqueuedVAA) Descriptor() ([]byte, []int) { - return file_gossip_v1_gossip_proto_rawDescGZIP(), []int{10, 0} + return file_gossip_v1_gossip_proto_rawDescGZIP(), []int{9, 0} } func (x *ChainGovernorStatus_EnqueuedVAA) GetSequence() uint64 { @@ -1508,7 +1396,7 @@ type ChainGovernorStatus_Emitter struct { func (x *ChainGovernorStatus_Emitter) Reset() { *x = ChainGovernorStatus_Emitter{} if protoimpl.UnsafeEnabled { - mi := &file_gossip_v1_gossip_proto_msgTypes[19] + mi := &file_gossip_v1_gossip_proto_msgTypes[18] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1521,7 +1409,7 @@ func (x *ChainGovernorStatus_Emitter) String() string { func (*ChainGovernorStatus_Emitter) ProtoMessage() {} func (x *ChainGovernorStatus_Emitter) ProtoReflect() protoreflect.Message { - mi := &file_gossip_v1_gossip_proto_msgTypes[19] + mi := &file_gossip_v1_gossip_proto_msgTypes[18] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1534,7 +1422,7 @@ func (x *ChainGovernorStatus_Emitter) ProtoReflect() protoreflect.Message { // Deprecated: Use ChainGovernorStatus_Emitter.ProtoReflect.Descriptor instead. func (*ChainGovernorStatus_Emitter) Descriptor() ([]byte, []int) { - return file_gossip_v1_gossip_proto_rawDescGZIP(), []int{10, 1} + return file_gossip_v1_gossip_proto_rawDescGZIP(), []int{9, 1} } func (x *ChainGovernorStatus_Emitter) GetEmitterAddress() string { @@ -1574,7 +1462,7 @@ type ChainGovernorStatus_Chain struct { func (x *ChainGovernorStatus_Chain) Reset() { *x = ChainGovernorStatus_Chain{} if protoimpl.UnsafeEnabled { - mi := &file_gossip_v1_gossip_proto_msgTypes[20] + mi := &file_gossip_v1_gossip_proto_msgTypes[19] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1587,7 +1475,7 @@ func (x *ChainGovernorStatus_Chain) String() string { func (*ChainGovernorStatus_Chain) ProtoMessage() {} func (x *ChainGovernorStatus_Chain) ProtoReflect() protoreflect.Message { - mi := &file_gossip_v1_gossip_proto_msgTypes[20] + mi := &file_gossip_v1_gossip_proto_msgTypes[19] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1600,7 +1488,7 @@ func (x *ChainGovernorStatus_Chain) ProtoReflect() protoreflect.Message { // Deprecated: Use ChainGovernorStatus_Chain.ProtoReflect.Descriptor instead. func (*ChainGovernorStatus_Chain) Descriptor() ([]byte, []int) { - return file_gossip_v1_gossip_proto_rawDescGZIP(), []int{10, 2} + return file_gossip_v1_gossip_proto_rawDescGZIP(), []int{9, 2} } func (x *ChainGovernorStatus_Chain) GetChainId() uint32 { @@ -1650,256 +1538,242 @@ var File_gossip_v1_gossip_proto protoreflect.FileDescriptor var file_gossip_v1_gossip_proto_rawDesc = []byte{ 0x0a, 0x16, 0x67, 0x6f, 0x73, 0x73, 0x69, 0x70, 0x2f, 0x76, 0x31, 0x2f, 0x67, 0x6f, 0x73, 0x73, 0x69, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x09, 0x67, 0x6f, 0x73, 0x73, 0x69, 0x70, - 0x2e, 0x76, 0x31, 0x22, 0xc8, 0x06, 0x0a, 0x0d, 0x47, 0x6f, 0x73, 0x73, 0x69, 0x70, 0x4d, 0x65, - 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x4d, 0x0a, 0x12, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x5f, - 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x73, 0x73, 0x69, 0x70, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x69, - 0x67, 0x6e, 0x65, 0x64, 0x4f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x48, - 0x00, 0x52, 0x11, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x4f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x47, 0x0a, 0x10, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x5f, 0x68, - 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, + 0x2e, 0x76, 0x31, 0x22, 0xf9, 0x05, 0x0a, 0x0d, 0x47, 0x6f, 0x73, 0x73, 0x69, 0x70, 0x4d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x47, 0x0a, 0x10, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x5f, + 0x68, 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x1a, 0x2e, 0x67, 0x6f, 0x73, 0x73, 0x69, 0x70, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x69, 0x67, 0x6e, + 0x65, 0x64, 0x48, 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x48, 0x00, 0x52, 0x0f, 0x73, + 0x69, 0x67, 0x6e, 0x65, 0x64, 0x48, 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x12, 0x55, + 0x0a, 0x16, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x5f, 0x76, 0x61, 0x61, 0x5f, 0x77, 0x69, 0x74, + 0x68, 0x5f, 0x71, 0x75, 0x6f, 0x72, 0x75, 0x6d, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x67, 0x6f, 0x73, 0x73, 0x69, 0x70, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x65, - 0x64, 0x48, 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x48, 0x00, 0x52, 0x0f, 0x73, 0x69, - 0x67, 0x6e, 0x65, 0x64, 0x48, 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x12, 0x55, 0x0a, - 0x16, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x5f, 0x76, 0x61, 0x61, 0x5f, 0x77, 0x69, 0x74, 0x68, - 0x5f, 0x71, 0x75, 0x6f, 0x72, 0x75, 0x6d, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, - 0x67, 0x6f, 0x73, 0x73, 0x69, 0x70, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, - 0x56, 0x41, 0x41, 0x57, 0x69, 0x74, 0x68, 0x51, 0x75, 0x6f, 0x72, 0x75, 0x6d, 0x48, 0x00, 0x52, - 0x13, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x56, 0x61, 0x61, 0x57, 0x69, 0x74, 0x68, 0x51, 0x75, - 0x6f, 0x72, 0x75, 0x6d, 0x12, 0x63, 0x0a, 0x1a, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x5f, 0x6f, - 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x67, 0x6f, 0x73, 0x73, 0x69, - 0x70, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x4f, 0x62, 0x73, 0x65, 0x72, - 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x00, 0x52, - 0x18, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x4f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x67, 0x0a, 0x1c, 0x73, 0x69, 0x67, - 0x6e, 0x65, 0x64, 0x5f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x67, 0x6f, 0x76, 0x65, 0x72, 0x6e, - 0x6f, 0x72, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x24, 0x2e, 0x67, 0x6f, 0x73, 0x73, 0x69, 0x70, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x69, 0x67, 0x6e, - 0x65, 0x64, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x47, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72, 0x43, - 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x48, 0x00, 0x52, 0x19, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x43, - 0x68, 0x61, 0x69, 0x6e, 0x47, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72, 0x43, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x12, 0x67, 0x0a, 0x1c, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x5f, 0x63, 0x68, 0x61, - 0x69, 0x6e, 0x5f, 0x67, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72, 0x5f, 0x73, 0x74, 0x61, 0x74, - 0x75, 0x73, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x67, 0x6f, 0x73, 0x73, 0x69, - 0x70, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x43, 0x68, 0x61, 0x69, 0x6e, - 0x47, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x48, 0x00, - 0x52, 0x19, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x47, 0x6f, 0x76, - 0x65, 0x72, 0x6e, 0x6f, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x51, 0x0a, 0x14, 0x73, - 0x69, 0x67, 0x6e, 0x65, 0x64, 0x5f, 0x71, 0x75, 0x65, 0x72, 0x79, 0x5f, 0x72, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x67, 0x6f, 0x73, 0x73, - 0x69, 0x70, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x51, 0x75, 0x65, 0x72, - 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x00, 0x52, 0x12, 0x73, 0x69, 0x67, 0x6e, - 0x65, 0x64, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x54, - 0x0a, 0x15, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x5f, 0x71, 0x75, 0x65, 0x72, 0x79, 0x5f, 0x72, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, - 0x67, 0x6f, 0x73, 0x73, 0x69, 0x70, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, - 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48, 0x00, 0x52, - 0x13, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5d, 0x0a, 0x18, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x5f, 0x6f, - 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x62, 0x61, 0x74, 0x63, 0x68, - 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x67, 0x6f, 0x73, 0x73, 0x69, 0x70, 0x2e, - 0x76, 0x31, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x4f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x48, 0x00, 0x52, 0x16, 0x73, 0x69, 0x67, - 0x6e, 0x65, 0x64, 0x4f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x61, - 0x74, 0x63, 0x68, 0x42, 0x09, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x72, - 0x0a, 0x0f, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x48, 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, - 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x68, 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x68, 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x12, - 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x23, 0x0a, - 0x0d, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x41, 0x64, - 0x64, 0x72, 0x22, 0x88, 0x04, 0x0a, 0x09, 0x48, 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, - 0x12, 0x1b, 0x0a, 0x09, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x08, 0x6e, 0x6f, 0x64, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, - 0x07, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, - 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, - 0x74, 0x61, 0x6d, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, - 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x38, 0x0a, 0x08, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, - 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x73, 0x73, 0x69, 0x70, - 0x2e, 0x76, 0x31, 0x2e, 0x48, 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x2e, 0x4e, 0x65, - 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x52, 0x08, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x12, - 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x23, 0x0a, 0x0d, 0x67, 0x75, 0x61, - 0x72, 0x64, 0x69, 0x61, 0x6e, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0c, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x41, 0x64, 0x64, 0x72, 0x12, 0x25, - 0x0a, 0x0e, 0x62, 0x6f, 0x6f, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, - 0x18, 0x07, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x62, 0x6f, 0x6f, 0x74, 0x54, 0x69, 0x6d, 0x65, - 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x1a, 0x0a, 0x08, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, - 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, - 0x73, 0x12, 0x1e, 0x0a, 0x0b, 0x70, 0x32, 0x70, 0x5f, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x69, 0x64, - 0x18, 0x09, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x70, 0x32, 0x70, 0x4e, 0x6f, 0x64, 0x65, 0x49, - 0x64, 0x1a, 0xc9, 0x01, 0x0a, 0x07, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x12, 0x0e, 0x0a, - 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x02, 0x69, 0x64, 0x12, 0x16, 0x0a, - 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x68, - 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x29, 0x0a, 0x10, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, - 0x74, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, - 0x12, 0x1f, 0x0a, 0x0b, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, - 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0a, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x43, 0x6f, 0x75, 0x6e, - 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x61, 0x66, 0x65, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, - 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x73, 0x61, 0x66, 0x65, 0x48, 0x65, 0x69, 0x67, - 0x68, 0x74, 0x12, 0x29, 0x0a, 0x10, 0x66, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x5f, - 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0f, 0x66, 0x69, - 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x22, 0x91, 0x01, - 0x0a, 0x11, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x4f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x61, 0x64, 0x64, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x04, 0x61, 0x64, 0x64, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x61, 0x73, 0x68, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x68, 0x61, 0x73, 0x68, 0x12, 0x1c, 0x0a, 0x09, 0x73, - 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, - 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x74, 0x78, 0x5f, - 0x68, 0x61, 0x73, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x74, 0x78, 0x48, 0x61, - 0x73, 0x68, 0x12, 0x1d, 0x0a, 0x0a, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x69, 0x64, - 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x49, - 0x64, 0x22, 0x27, 0x0a, 0x13, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x56, 0x41, 0x41, 0x57, 0x69, - 0x74, 0x68, 0x51, 0x75, 0x6f, 0x72, 0x75, 0x6d, 0x12, 0x10, 0x0a, 0x03, 0x76, 0x61, 0x61, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x76, 0x61, 0x61, 0x22, 0x8e, 0x01, 0x0a, 0x18, 0x53, - 0x69, 0x67, 0x6e, 0x65, 0x64, 0x4f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2f, 0x0a, 0x13, 0x6f, 0x62, 0x73, 0x65, 0x72, - 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0c, 0x52, 0x12, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, - 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, 0x67, - 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, - 0x61, 0x6e, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x67, - 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x41, 0x64, 0x64, 0x72, 0x22, 0x48, 0x0a, 0x12, 0x4f, - 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0d, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x17, 0x0a, 0x07, - 0x74, 0x78, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x74, - 0x78, 0x48, 0x61, 0x73, 0x68, 0x22, 0x76, 0x0a, 0x19, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x43, - 0x68, 0x61, 0x69, 0x6e, 0x47, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72, 0x43, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x12, 0x16, 0x0a, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0c, 0x52, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, - 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, - 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x67, 0x75, 0x61, 0x72, - 0x64, 0x69, 0x61, 0x6e, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, - 0x0c, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x41, 0x64, 0x64, 0x72, 0x22, 0x81, 0x04, - 0x0a, 0x13, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x47, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72, 0x43, - 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x1b, 0x0a, 0x09, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x6e, 0x61, - 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6e, 0x6f, 0x64, 0x65, 0x4e, 0x61, - 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x03, 0x52, 0x07, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x12, 0x1c, 0x0a, 0x09, - 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, - 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x3c, 0x0a, 0x06, 0x63, 0x68, - 0x61, 0x69, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x67, 0x6f, 0x73, - 0x73, 0x69, 0x70, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x47, 0x6f, 0x76, 0x65, - 0x72, 0x6e, 0x6f, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x43, 0x68, 0x61, 0x69, 0x6e, - 0x52, 0x06, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x73, 0x12, 0x3c, 0x0a, 0x06, 0x74, 0x6f, 0x6b, 0x65, - 0x6e, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x67, 0x6f, 0x73, 0x73, 0x69, - 0x70, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x47, 0x6f, 0x76, 0x65, 0x72, 0x6e, - 0x6f, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x06, - 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x12, 0x2e, 0x0a, 0x13, 0x66, 0x6c, 0x6f, 0x77, 0x5f, 0x63, - 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x06, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x11, 0x66, 0x6c, 0x6f, 0x77, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x45, - 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x1a, 0x7b, 0x0a, 0x05, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x12, - 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0d, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x0e, 0x6e, 0x6f, - 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x04, 0x52, 0x0d, 0x6e, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x4c, 0x69, 0x6d, 0x69, - 0x74, 0x12, 0x30, 0x0a, 0x14, 0x62, 0x69, 0x67, 0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, - 0x12, 0x62, 0x69, 0x67, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x53, - 0x69, 0x7a, 0x65, 0x1a, 0x6c, 0x0a, 0x05, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x26, 0x0a, 0x0f, - 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x5f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0d, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x43, 0x68, 0x61, - 0x69, 0x6e, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x0e, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x5f, 0x61, - 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6f, 0x72, - 0x69, 0x67, 0x69, 0x6e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x70, - 0x72, 0x69, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x02, 0x52, 0x05, 0x70, 0x72, 0x69, 0x63, - 0x65, 0x22, 0x76, 0x0a, 0x19, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x43, 0x68, 0x61, 0x69, 0x6e, - 0x47, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x16, - 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, - 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, - 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, - 0x74, 0x75, 0x72, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, - 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x67, 0x75, 0x61, - 0x72, 0x64, 0x69, 0x61, 0x6e, 0x41, 0x64, 0x64, 0x72, 0x22, 0xdb, 0x06, 0x0a, 0x13, 0x43, 0x68, - 0x61, 0x69, 0x6e, 0x47, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, - 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, + 0x64, 0x56, 0x41, 0x41, 0x57, 0x69, 0x74, 0x68, 0x51, 0x75, 0x6f, 0x72, 0x75, 0x6d, 0x48, 0x00, + 0x52, 0x13, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x56, 0x61, 0x61, 0x57, 0x69, 0x74, 0x68, 0x51, + 0x75, 0x6f, 0x72, 0x75, 0x6d, 0x12, 0x63, 0x0a, 0x1a, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x5f, + 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x67, 0x6f, 0x73, 0x73, + 0x69, 0x70, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x4f, 0x62, 0x73, 0x65, + 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x00, + 0x52, 0x18, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x4f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x67, 0x0a, 0x1c, 0x73, 0x69, + 0x67, 0x6e, 0x65, 0x64, 0x5f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x67, 0x6f, 0x76, 0x65, 0x72, + 0x6e, 0x6f, 0x72, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x24, 0x2e, 0x67, 0x6f, 0x73, 0x73, 0x69, 0x70, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x69, 0x67, + 0x6e, 0x65, 0x64, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x47, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72, + 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x48, 0x00, 0x52, 0x19, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, + 0x43, 0x68, 0x61, 0x69, 0x6e, 0x47, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72, 0x43, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x12, 0x67, 0x0a, 0x1c, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x5f, 0x63, 0x68, + 0x61, 0x69, 0x6e, 0x5f, 0x67, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72, 0x5f, 0x73, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x67, 0x6f, 0x73, 0x73, + 0x69, 0x70, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x43, 0x68, 0x61, 0x69, + 0x6e, 0x47, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x48, + 0x00, 0x52, 0x19, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x47, 0x6f, + 0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x51, 0x0a, 0x14, + 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x5f, 0x71, 0x75, 0x65, 0x72, 0x79, 0x5f, 0x72, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x67, 0x6f, 0x73, + 0x73, 0x69, 0x70, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x51, 0x75, 0x65, + 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x00, 0x52, 0x12, 0x73, 0x69, 0x67, + 0x6e, 0x65, 0x64, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x54, 0x0a, 0x15, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x5f, 0x71, 0x75, 0x65, 0x72, 0x79, 0x5f, + 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, + 0x2e, 0x67, 0x6f, 0x73, 0x73, 0x69, 0x70, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x65, + 0x64, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48, 0x00, + 0x52, 0x13, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5d, 0x0a, 0x18, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x5f, + 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x62, 0x61, 0x74, 0x63, + 0x68, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x67, 0x6f, 0x73, 0x73, 0x69, 0x70, + 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x4f, 0x62, 0x73, 0x65, 0x72, 0x76, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x48, 0x00, 0x52, 0x16, 0x73, 0x69, + 0x67, 0x6e, 0x65, 0x64, 0x4f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, + 0x61, 0x74, 0x63, 0x68, 0x42, 0x09, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, + 0x72, 0x0a, 0x0f, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x48, 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, + 0x61, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x68, 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x68, 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, + 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x23, + 0x0a, 0x0d, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x41, + 0x64, 0x64, 0x72, 0x22, 0x88, 0x04, 0x0a, 0x09, 0x48, 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, + 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6e, 0x6f, 0x64, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x69, 0x6d, - 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x3c, 0x0a, 0x06, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x73, - 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x67, 0x6f, 0x73, 0x73, 0x69, 0x70, 0x2e, - 0x76, 0x31, 0x2e, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x47, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72, - 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2e, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x52, 0x06, 0x63, 0x68, - 0x61, 0x69, 0x6e, 0x73, 0x1a, 0x8c, 0x01, 0x0a, 0x0b, 0x45, 0x6e, 0x71, 0x75, 0x65, 0x75, 0x65, - 0x64, 0x56, 0x41, 0x41, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, - 0x12, 0x21, 0x0a, 0x0c, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x54, - 0x69, 0x6d, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x6e, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x5f, - 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x6e, 0x6f, 0x74, - 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x74, 0x78, - 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x74, 0x78, 0x48, - 0x61, 0x73, 0x68, 0x1a, 0xb3, 0x01, 0x0a, 0x07, 0x45, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x72, 0x12, - 0x27, 0x0a, 0x0f, 0x65, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, - 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x65, 0x6d, 0x69, 0x74, 0x74, 0x65, - 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x2e, 0x0a, 0x13, 0x74, 0x6f, 0x74, 0x61, - 0x6c, 0x5f, 0x65, 0x6e, 0x71, 0x75, 0x65, 0x75, 0x65, 0x64, 0x5f, 0x76, 0x61, 0x61, 0x73, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x11, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x45, 0x6e, 0x71, 0x75, - 0x65, 0x75, 0x65, 0x64, 0x56, 0x61, 0x61, 0x73, 0x12, 0x4f, 0x0a, 0x0d, 0x65, 0x6e, 0x71, 0x75, - 0x65, 0x75, 0x65, 0x64, 0x5f, 0x76, 0x61, 0x61, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x2a, 0x2e, 0x67, 0x6f, 0x73, 0x73, 0x69, 0x70, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x68, 0x61, 0x69, + 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x38, 0x0a, 0x08, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, + 0x6b, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x73, 0x73, 0x69, + 0x70, 0x2e, 0x76, 0x31, 0x2e, 0x48, 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x2e, 0x4e, + 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x52, 0x08, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x73, + 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x23, 0x0a, 0x0d, 0x67, 0x75, + 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0c, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x41, 0x64, 0x64, 0x72, 0x12, + 0x25, 0x0a, 0x0e, 0x62, 0x6f, 0x6f, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, + 0x70, 0x18, 0x07, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x62, 0x6f, 0x6f, 0x74, 0x54, 0x69, 0x6d, + 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x1a, 0x0a, 0x08, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, + 0x65, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, + 0x65, 0x73, 0x12, 0x1e, 0x0a, 0x0b, 0x70, 0x32, 0x70, 0x5f, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x69, + 0x64, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x70, 0x32, 0x70, 0x4e, 0x6f, 0x64, 0x65, + 0x49, 0x64, 0x1a, 0xc9, 0x01, 0x0a, 0x07, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x12, 0x0e, + 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x02, 0x69, 0x64, 0x12, 0x16, + 0x0a, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, + 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x29, 0x0a, 0x10, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, + 0x63, 0x74, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, + 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0a, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x43, 0x6f, 0x75, + 0x6e, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x61, 0x66, 0x65, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, + 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x73, 0x61, 0x66, 0x65, 0x48, 0x65, 0x69, + 0x67, 0x68, 0x74, 0x12, 0x29, 0x0a, 0x10, 0x66, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, + 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0f, 0x66, + 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x22, 0x27, + 0x0a, 0x13, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x56, 0x41, 0x41, 0x57, 0x69, 0x74, 0x68, 0x51, + 0x75, 0x6f, 0x72, 0x75, 0x6d, 0x12, 0x10, 0x0a, 0x03, 0x76, 0x61, 0x61, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x03, 0x76, 0x61, 0x61, 0x22, 0x8e, 0x01, 0x0a, 0x18, 0x53, 0x69, 0x67, 0x6e, + 0x65, 0x64, 0x4f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x2f, 0x0a, 0x13, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x12, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, + 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, + 0x75, 0x72, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x5f, + 0x61, 0x64, 0x64, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x67, 0x75, 0x61, 0x72, + 0x64, 0x69, 0x61, 0x6e, 0x41, 0x64, 0x64, 0x72, 0x22, 0x48, 0x0a, 0x12, 0x4f, 0x62, 0x73, 0x65, + 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x19, + 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, + 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x74, 0x78, 0x5f, + 0x68, 0x61, 0x73, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x74, 0x78, 0x48, 0x61, + 0x73, 0x68, 0x22, 0x76, 0x0a, 0x19, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x43, 0x68, 0x61, 0x69, + 0x6e, 0x47, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, + 0x16, 0x0a, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, + 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, + 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, + 0x6e, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x67, 0x75, + 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x41, 0x64, 0x64, 0x72, 0x22, 0x81, 0x04, 0x0a, 0x13, 0x43, + 0x68, 0x61, 0x69, 0x6e, 0x47, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72, 0x43, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x12, 0x1b, 0x0a, 0x09, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6e, 0x6f, 0x64, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, + 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, + 0x52, 0x07, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, + 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x69, + 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x3c, 0x0a, 0x06, 0x63, 0x68, 0x61, 0x69, 0x6e, + 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x67, 0x6f, 0x73, 0x73, 0x69, 0x70, + 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x47, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6f, + 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x52, 0x06, 0x63, + 0x68, 0x61, 0x69, 0x6e, 0x73, 0x12, 0x3c, 0x0a, 0x06, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x18, + 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x67, 0x6f, 0x73, 0x73, 0x69, 0x70, 0x2e, 0x76, + 0x31, 0x2e, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x47, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72, 0x43, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x06, 0x74, 0x6f, 0x6b, + 0x65, 0x6e, 0x73, 0x12, 0x2e, 0x0a, 0x13, 0x66, 0x6c, 0x6f, 0x77, 0x5f, 0x63, 0x61, 0x6e, 0x63, + 0x65, 0x6c, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x11, 0x66, 0x6c, 0x6f, 0x77, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x45, 0x6e, 0x61, 0x62, + 0x6c, 0x65, 0x64, 0x1a, 0x7b, 0x0a, 0x05, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x12, 0x19, 0x0a, 0x08, + 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, + 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x0e, 0x6e, 0x6f, 0x74, 0x69, 0x6f, + 0x6e, 0x61, 0x6c, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, + 0x0d, 0x6e, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x30, + 0x0a, 0x14, 0x62, 0x69, 0x67, 0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x12, 0x62, 0x69, + 0x67, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x69, 0x7a, 0x65, + 0x1a, 0x6c, 0x0a, 0x05, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x26, 0x0a, 0x0f, 0x6f, 0x72, 0x69, + 0x67, 0x69, 0x6e, 0x5f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0d, 0x52, 0x0d, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x49, + 0x64, 0x12, 0x25, 0x0a, 0x0e, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x5f, 0x61, 0x64, 0x64, 0x72, + 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6f, 0x72, 0x69, 0x67, 0x69, + 0x6e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x70, 0x72, 0x69, 0x63, + 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x02, 0x52, 0x05, 0x70, 0x72, 0x69, 0x63, 0x65, 0x22, 0x76, + 0x0a, 0x19, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x47, 0x6f, 0x76, + 0x65, 0x72, 0x6e, 0x6f, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x73, + 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x73, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, + 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x5f, 0x61, 0x64, + 0x64, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, + 0x61, 0x6e, 0x41, 0x64, 0x64, 0x72, 0x22, 0xdb, 0x06, 0x0a, 0x13, 0x43, 0x68, 0x61, 0x69, 0x6e, + 0x47, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1b, + 0x0a, 0x09, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x08, 0x6e, 0x6f, 0x64, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x63, + 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x63, 0x6f, + 0x75, 0x6e, 0x74, 0x65, 0x72, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, + 0x6d, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, + 0x61, 0x6d, 0x70, 0x12, 0x3c, 0x0a, 0x06, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x73, 0x18, 0x04, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x67, 0x6f, 0x73, 0x73, 0x69, 0x70, 0x2e, 0x76, 0x31, 0x2e, + 0x43, 0x68, 0x61, 0x69, 0x6e, 0x47, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72, 0x53, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x2e, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x52, 0x06, 0x63, 0x68, 0x61, 0x69, 0x6e, + 0x73, 0x1a, 0x8c, 0x01, 0x0a, 0x0b, 0x45, 0x6e, 0x71, 0x75, 0x65, 0x75, 0x65, 0x64, 0x56, 0x41, + 0x41, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x04, 0x52, 0x08, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x21, 0x0a, + 0x0c, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x54, 0x69, 0x6d, 0x65, + 0x12, 0x25, 0x0a, 0x0e, 0x6e, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x5f, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x6e, 0x6f, 0x74, 0x69, 0x6f, 0x6e, + 0x61, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x74, 0x78, 0x5f, 0x68, 0x61, + 0x73, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x74, 0x78, 0x48, 0x61, 0x73, 0x68, + 0x1a, 0xb3, 0x01, 0x0a, 0x07, 0x45, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x72, 0x12, 0x27, 0x0a, 0x0f, + 0x65, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x65, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x72, 0x41, 0x64, + 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x2e, 0x0a, 0x13, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x65, + 0x6e, 0x71, 0x75, 0x65, 0x75, 0x65, 0x64, 0x5f, 0x76, 0x61, 0x61, 0x73, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x04, 0x52, 0x11, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x45, 0x6e, 0x71, 0x75, 0x65, 0x75, 0x65, + 0x64, 0x56, 0x61, 0x61, 0x73, 0x12, 0x4f, 0x0a, 0x0d, 0x65, 0x6e, 0x71, 0x75, 0x65, 0x75, 0x65, + 0x64, 0x5f, 0x76, 0x61, 0x61, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x67, + 0x6f, 0x73, 0x73, 0x69, 0x70, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x47, 0x6f, + 0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2e, 0x45, 0x6e, 0x71, + 0x75, 0x65, 0x75, 0x65, 0x64, 0x56, 0x41, 0x41, 0x52, 0x0c, 0x65, 0x6e, 0x71, 0x75, 0x65, 0x75, + 0x65, 0x64, 0x56, 0x61, 0x61, 0x73, 0x1a, 0xeb, 0x02, 0x0a, 0x05, 0x43, 0x68, 0x61, 0x69, 0x6e, + 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0d, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x40, 0x0a, 0x1c, 0x72, + 0x65, 0x6d, 0x61, 0x69, 0x6e, 0x69, 0x6e, 0x67, 0x5f, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, + 0x6c, 0x65, 0x5f, 0x6e, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x04, 0x52, 0x1a, 0x72, 0x65, 0x6d, 0x61, 0x69, 0x6e, 0x69, 0x6e, 0x67, 0x41, 0x76, 0x61, 0x69, + 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x12, 0x42, 0x0a, + 0x08, 0x65, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x72, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x26, 0x2e, 0x67, 0x6f, 0x73, 0x73, 0x69, 0x70, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x47, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2e, - 0x45, 0x6e, 0x71, 0x75, 0x65, 0x75, 0x65, 0x64, 0x56, 0x41, 0x41, 0x52, 0x0c, 0x65, 0x6e, 0x71, - 0x75, 0x65, 0x75, 0x65, 0x64, 0x56, 0x61, 0x61, 0x73, 0x1a, 0xeb, 0x02, 0x0a, 0x05, 0x43, 0x68, - 0x61, 0x69, 0x6e, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x40, - 0x0a, 0x1c, 0x72, 0x65, 0x6d, 0x61, 0x69, 0x6e, 0x69, 0x6e, 0x67, 0x5f, 0x61, 0x76, 0x61, 0x69, - 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x6e, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x04, 0x52, 0x1a, 0x72, 0x65, 0x6d, 0x61, 0x69, 0x6e, 0x69, 0x6e, 0x67, 0x41, - 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, - 0x12, 0x42, 0x0a, 0x08, 0x65, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x72, 0x73, 0x18, 0x03, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x67, 0x6f, 0x73, 0x73, 0x69, 0x70, 0x2e, 0x76, 0x31, 0x2e, 0x43, - 0x68, 0x61, 0x69, 0x6e, 0x47, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72, 0x53, 0x74, 0x61, 0x74, - 0x75, 0x73, 0x2e, 0x45, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x72, 0x52, 0x08, 0x65, 0x6d, 0x69, 0x74, - 0x74, 0x65, 0x72, 0x73, 0x12, 0x3c, 0x0a, 0x1b, 0x73, 0x6d, 0x61, 0x6c, 0x6c, 0x5f, 0x74, 0x78, - 0x5f, 0x6e, 0x65, 0x74, 0x5f, 0x6e, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x5f, 0x76, 0x61, - 0x6c, 0x75, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x17, 0x73, 0x6d, 0x61, 0x6c, 0x6c, - 0x54, 0x78, 0x4e, 0x65, 0x74, 0x4e, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x56, 0x61, 0x6c, - 0x75, 0x65, 0x12, 0x46, 0x0a, 0x20, 0x73, 0x6d, 0x61, 0x6c, 0x6c, 0x5f, 0x74, 0x78, 0x5f, 0x6f, - 0x75, 0x74, 0x67, 0x6f, 0x69, 0x6e, 0x67, 0x5f, 0x6e, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, - 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x1c, 0x73, 0x6d, - 0x61, 0x6c, 0x6c, 0x54, 0x78, 0x4f, 0x75, 0x74, 0x67, 0x6f, 0x69, 0x6e, 0x67, 0x4e, 0x6f, 0x74, - 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x3b, 0x0a, 0x1a, 0x66, 0x6c, - 0x6f, 0x77, 0x5f, 0x63, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x5f, 0x6e, 0x6f, 0x74, 0x69, 0x6f, 0x6e, - 0x61, 0x6c, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x04, 0x52, 0x17, - 0x66, 0x6c, 0x6f, 0x77, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x4e, 0x6f, 0x74, 0x69, 0x6f, 0x6e, - 0x61, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x57, 0x0a, 0x12, 0x53, 0x69, 0x67, 0x6e, 0x65, - 0x64, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x23, 0x0a, - 0x0d, 0x71, 0x75, 0x65, 0x72, 0x79, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x71, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, - 0x22, 0x5a, 0x0a, 0x13, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x71, 0x75, 0x65, 0x72, 0x79, - 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, - 0x0d, 0x71, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1c, - 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, 0x68, 0x0a, 0x16, - 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x4f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x12, 0x12, 0x0a, 0x04, 0x61, 0x64, 0x64, 0x72, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x61, 0x64, 0x64, 0x72, 0x12, 0x3a, 0x0a, 0x0c, 0x6f, 0x62, - 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x16, 0x2e, 0x67, 0x6f, 0x73, 0x73, 0x69, 0x70, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x62, 0x73, - 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0c, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x77, 0x0a, 0x0b, 0x4f, 0x62, 0x73, 0x65, 0x72, 0x76, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0c, 0x52, 0x04, 0x68, 0x61, 0x73, 0x68, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, - 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, - 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x74, 0x78, 0x5f, 0x68, 0x61, - 0x73, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x74, 0x78, 0x48, 0x61, 0x73, 0x68, - 0x12, 0x1d, 0x0a, 0x0a, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x04, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x49, 0x64, 0x42, - 0x41, 0x5a, 0x3f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x65, - 0x72, 0x74, 0x75, 0x73, 0x6f, 0x6e, 0x65, 0x2f, 0x77, 0x6f, 0x72, 0x6d, 0x68, 0x6f, 0x6c, 0x65, - 0x2f, 0x6e, 0x6f, 0x64, 0x65, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, - 0x67, 0x6f, 0x73, 0x73, 0x69, 0x70, 0x2f, 0x76, 0x31, 0x3b, 0x67, 0x6f, 0x73, 0x73, 0x69, 0x70, - 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x45, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x72, 0x52, 0x08, 0x65, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x72, + 0x73, 0x12, 0x3c, 0x0a, 0x1b, 0x73, 0x6d, 0x61, 0x6c, 0x6c, 0x5f, 0x74, 0x78, 0x5f, 0x6e, 0x65, + 0x74, 0x5f, 0x6e, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x17, 0x73, 0x6d, 0x61, 0x6c, 0x6c, 0x54, 0x78, 0x4e, + 0x65, 0x74, 0x4e, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, + 0x46, 0x0a, 0x20, 0x73, 0x6d, 0x61, 0x6c, 0x6c, 0x5f, 0x74, 0x78, 0x5f, 0x6f, 0x75, 0x74, 0x67, + 0x6f, 0x69, 0x6e, 0x67, 0x5f, 0x6e, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x5f, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x1c, 0x73, 0x6d, 0x61, 0x6c, 0x6c, + 0x54, 0x78, 0x4f, 0x75, 0x74, 0x67, 0x6f, 0x69, 0x6e, 0x67, 0x4e, 0x6f, 0x74, 0x69, 0x6f, 0x6e, + 0x61, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x3b, 0x0a, 0x1a, 0x66, 0x6c, 0x6f, 0x77, 0x5f, + 0x63, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x5f, 0x6e, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x5f, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x04, 0x52, 0x17, 0x66, 0x6c, 0x6f, + 0x77, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x4e, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x56, + 0x61, 0x6c, 0x75, 0x65, 0x22, 0x57, 0x0a, 0x12, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x51, 0x75, + 0x65, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x23, 0x0a, 0x0d, 0x71, 0x75, + 0x65, 0x72, 0x79, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x0c, 0x71, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, 0x5a, 0x0a, + 0x13, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x5f, 0x72, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0d, 0x71, 0x75, + 0x65, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x73, + 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, + 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, 0x68, 0x0a, 0x16, 0x53, 0x69, 0x67, + 0x6e, 0x65, 0x64, 0x4f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x61, + 0x74, 0x63, 0x68, 0x12, 0x12, 0x0a, 0x04, 0x61, 0x64, 0x64, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x04, 0x61, 0x64, 0x64, 0x72, 0x12, 0x3a, 0x0a, 0x0c, 0x6f, 0x62, 0x73, 0x65, 0x72, + 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, + 0x67, 0x6f, 0x73, 0x73, 0x69, 0x70, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x62, 0x73, 0x65, 0x72, 0x76, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0c, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x22, 0x77, 0x0a, 0x0b, 0x4f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x04, 0x68, 0x61, 0x73, 0x68, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, + 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, + 0x74, 0x75, 0x72, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x74, 0x78, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x74, 0x78, 0x48, 0x61, 0x73, 0x68, 0x12, 0x1d, 0x0a, + 0x0a, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x09, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x49, 0x64, 0x42, 0x41, 0x5a, 0x3f, + 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x65, 0x72, 0x74, 0x75, + 0x73, 0x6f, 0x6e, 0x65, 0x2f, 0x77, 0x6f, 0x72, 0x6d, 0x68, 0x6f, 0x6c, 0x65, 0x2f, 0x6e, 0x6f, + 0x64, 0x65, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x73, + 0x73, 0x69, 0x70, 0x2f, 0x76, 0x31, 0x3b, 0x67, 0x6f, 0x73, 0x73, 0x69, 0x70, 0x76, 0x31, 0x62, + 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -1914,52 +1788,50 @@ func file_gossip_v1_gossip_proto_rawDescGZIP() []byte { return file_gossip_v1_gossip_proto_rawDescData } -var file_gossip_v1_gossip_proto_msgTypes = make([]protoimpl.MessageInfo, 21) +var file_gossip_v1_gossip_proto_msgTypes = make([]protoimpl.MessageInfo, 20) var file_gossip_v1_gossip_proto_goTypes = []interface{}{ (*GossipMessage)(nil), // 0: gossip.v1.GossipMessage (*SignedHeartbeat)(nil), // 1: gossip.v1.SignedHeartbeat (*Heartbeat)(nil), // 2: gossip.v1.Heartbeat - (*SignedObservation)(nil), // 3: gossip.v1.SignedObservation - (*SignedVAAWithQuorum)(nil), // 4: gossip.v1.SignedVAAWithQuorum - (*SignedObservationRequest)(nil), // 5: gossip.v1.SignedObservationRequest - (*ObservationRequest)(nil), // 6: gossip.v1.ObservationRequest - (*SignedChainGovernorConfig)(nil), // 7: gossip.v1.SignedChainGovernorConfig - (*ChainGovernorConfig)(nil), // 8: gossip.v1.ChainGovernorConfig - (*SignedChainGovernorStatus)(nil), // 9: gossip.v1.SignedChainGovernorStatus - (*ChainGovernorStatus)(nil), // 10: gossip.v1.ChainGovernorStatus - (*SignedQueryRequest)(nil), // 11: gossip.v1.SignedQueryRequest - (*SignedQueryResponse)(nil), // 12: gossip.v1.SignedQueryResponse - (*SignedObservationBatch)(nil), // 13: gossip.v1.SignedObservationBatch - (*Observation)(nil), // 14: gossip.v1.Observation - (*Heartbeat_Network)(nil), // 15: gossip.v1.Heartbeat.Network - (*ChainGovernorConfig_Chain)(nil), // 16: gossip.v1.ChainGovernorConfig.Chain - (*ChainGovernorConfig_Token)(nil), // 17: gossip.v1.ChainGovernorConfig.Token - (*ChainGovernorStatus_EnqueuedVAA)(nil), // 18: gossip.v1.ChainGovernorStatus.EnqueuedVAA - (*ChainGovernorStatus_Emitter)(nil), // 19: gossip.v1.ChainGovernorStatus.Emitter - (*ChainGovernorStatus_Chain)(nil), // 20: gossip.v1.ChainGovernorStatus.Chain + (*SignedVAAWithQuorum)(nil), // 3: gossip.v1.SignedVAAWithQuorum + (*SignedObservationRequest)(nil), // 4: gossip.v1.SignedObservationRequest + (*ObservationRequest)(nil), // 5: gossip.v1.ObservationRequest + (*SignedChainGovernorConfig)(nil), // 6: gossip.v1.SignedChainGovernorConfig + (*ChainGovernorConfig)(nil), // 7: gossip.v1.ChainGovernorConfig + (*SignedChainGovernorStatus)(nil), // 8: gossip.v1.SignedChainGovernorStatus + (*ChainGovernorStatus)(nil), // 9: gossip.v1.ChainGovernorStatus + (*SignedQueryRequest)(nil), // 10: gossip.v1.SignedQueryRequest + (*SignedQueryResponse)(nil), // 11: gossip.v1.SignedQueryResponse + (*SignedObservationBatch)(nil), // 12: gossip.v1.SignedObservationBatch + (*Observation)(nil), // 13: gossip.v1.Observation + (*Heartbeat_Network)(nil), // 14: gossip.v1.Heartbeat.Network + (*ChainGovernorConfig_Chain)(nil), // 15: gossip.v1.ChainGovernorConfig.Chain + (*ChainGovernorConfig_Token)(nil), // 16: gossip.v1.ChainGovernorConfig.Token + (*ChainGovernorStatus_EnqueuedVAA)(nil), // 17: gossip.v1.ChainGovernorStatus.EnqueuedVAA + (*ChainGovernorStatus_Emitter)(nil), // 18: gossip.v1.ChainGovernorStatus.Emitter + (*ChainGovernorStatus_Chain)(nil), // 19: gossip.v1.ChainGovernorStatus.Chain } var file_gossip_v1_gossip_proto_depIdxs = []int32{ - 3, // 0: gossip.v1.GossipMessage.signed_observation:type_name -> gossip.v1.SignedObservation - 1, // 1: gossip.v1.GossipMessage.signed_heartbeat:type_name -> gossip.v1.SignedHeartbeat - 4, // 2: gossip.v1.GossipMessage.signed_vaa_with_quorum:type_name -> gossip.v1.SignedVAAWithQuorum - 5, // 3: gossip.v1.GossipMessage.signed_observation_request:type_name -> gossip.v1.SignedObservationRequest - 7, // 4: gossip.v1.GossipMessage.signed_chain_governor_config:type_name -> gossip.v1.SignedChainGovernorConfig - 9, // 5: gossip.v1.GossipMessage.signed_chain_governor_status:type_name -> gossip.v1.SignedChainGovernorStatus - 11, // 6: gossip.v1.GossipMessage.signed_query_request:type_name -> gossip.v1.SignedQueryRequest - 12, // 7: gossip.v1.GossipMessage.signed_query_response:type_name -> gossip.v1.SignedQueryResponse - 13, // 8: gossip.v1.GossipMessage.signed_observation_batch:type_name -> gossip.v1.SignedObservationBatch - 15, // 9: gossip.v1.Heartbeat.networks:type_name -> gossip.v1.Heartbeat.Network - 16, // 10: gossip.v1.ChainGovernorConfig.chains:type_name -> gossip.v1.ChainGovernorConfig.Chain - 17, // 11: gossip.v1.ChainGovernorConfig.tokens:type_name -> gossip.v1.ChainGovernorConfig.Token - 20, // 12: gossip.v1.ChainGovernorStatus.chains:type_name -> gossip.v1.ChainGovernorStatus.Chain - 14, // 13: gossip.v1.SignedObservationBatch.observations:type_name -> gossip.v1.Observation - 18, // 14: gossip.v1.ChainGovernorStatus.Emitter.enqueued_vaas:type_name -> gossip.v1.ChainGovernorStatus.EnqueuedVAA - 19, // 15: gossip.v1.ChainGovernorStatus.Chain.emitters:type_name -> gossip.v1.ChainGovernorStatus.Emitter - 16, // [16:16] is the sub-list for method output_type - 16, // [16:16] is the sub-list for method input_type - 16, // [16:16] is the sub-list for extension type_name - 16, // [16:16] is the sub-list for extension extendee - 0, // [0:16] is the sub-list for field type_name + 1, // 0: gossip.v1.GossipMessage.signed_heartbeat:type_name -> gossip.v1.SignedHeartbeat + 3, // 1: gossip.v1.GossipMessage.signed_vaa_with_quorum:type_name -> gossip.v1.SignedVAAWithQuorum + 4, // 2: gossip.v1.GossipMessage.signed_observation_request:type_name -> gossip.v1.SignedObservationRequest + 6, // 3: gossip.v1.GossipMessage.signed_chain_governor_config:type_name -> gossip.v1.SignedChainGovernorConfig + 8, // 4: gossip.v1.GossipMessage.signed_chain_governor_status:type_name -> gossip.v1.SignedChainGovernorStatus + 10, // 5: gossip.v1.GossipMessage.signed_query_request:type_name -> gossip.v1.SignedQueryRequest + 11, // 6: gossip.v1.GossipMessage.signed_query_response:type_name -> gossip.v1.SignedQueryResponse + 12, // 7: gossip.v1.GossipMessage.signed_observation_batch:type_name -> gossip.v1.SignedObservationBatch + 14, // 8: gossip.v1.Heartbeat.networks:type_name -> gossip.v1.Heartbeat.Network + 15, // 9: gossip.v1.ChainGovernorConfig.chains:type_name -> gossip.v1.ChainGovernorConfig.Chain + 16, // 10: gossip.v1.ChainGovernorConfig.tokens:type_name -> gossip.v1.ChainGovernorConfig.Token + 19, // 11: gossip.v1.ChainGovernorStatus.chains:type_name -> gossip.v1.ChainGovernorStatus.Chain + 13, // 12: gossip.v1.SignedObservationBatch.observations:type_name -> gossip.v1.Observation + 17, // 13: gossip.v1.ChainGovernorStatus.Emitter.enqueued_vaas:type_name -> gossip.v1.ChainGovernorStatus.EnqueuedVAA + 18, // 14: gossip.v1.ChainGovernorStatus.Chain.emitters:type_name -> gossip.v1.ChainGovernorStatus.Emitter + 15, // [15:15] is the sub-list for method output_type + 15, // [15:15] is the sub-list for method input_type + 15, // [15:15] is the sub-list for extension type_name + 15, // [15:15] is the sub-list for extension extendee + 0, // [0:15] is the sub-list for field type_name } func init() { file_gossip_v1_gossip_proto_init() } @@ -2005,18 +1877,6 @@ func file_gossip_v1_gossip_proto_init() { } } file_gossip_v1_gossip_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SignedObservation); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_gossip_v1_gossip_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*SignedVAAWithQuorum); i { case 0: return &v.state @@ -2028,7 +1888,7 @@ func file_gossip_v1_gossip_proto_init() { return nil } } - file_gossip_v1_gossip_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + file_gossip_v1_gossip_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*SignedObservationRequest); i { case 0: return &v.state @@ -2040,7 +1900,7 @@ func file_gossip_v1_gossip_proto_init() { return nil } } - file_gossip_v1_gossip_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + file_gossip_v1_gossip_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ObservationRequest); i { case 0: return &v.state @@ -2052,7 +1912,7 @@ func file_gossip_v1_gossip_proto_init() { return nil } } - file_gossip_v1_gossip_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + file_gossip_v1_gossip_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*SignedChainGovernorConfig); i { case 0: return &v.state @@ -2064,7 +1924,7 @@ func file_gossip_v1_gossip_proto_init() { return nil } } - file_gossip_v1_gossip_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + file_gossip_v1_gossip_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ChainGovernorConfig); i { case 0: return &v.state @@ -2076,7 +1936,7 @@ func file_gossip_v1_gossip_proto_init() { return nil } } - file_gossip_v1_gossip_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + file_gossip_v1_gossip_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*SignedChainGovernorStatus); i { case 0: return &v.state @@ -2088,7 +1948,7 @@ func file_gossip_v1_gossip_proto_init() { return nil } } - file_gossip_v1_gossip_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { + file_gossip_v1_gossip_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ChainGovernorStatus); i { case 0: return &v.state @@ -2100,7 +1960,7 @@ func file_gossip_v1_gossip_proto_init() { return nil } } - file_gossip_v1_gossip_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { + file_gossip_v1_gossip_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*SignedQueryRequest); i { case 0: return &v.state @@ -2112,7 +1972,7 @@ func file_gossip_v1_gossip_proto_init() { return nil } } - file_gossip_v1_gossip_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { + file_gossip_v1_gossip_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*SignedQueryResponse); i { case 0: return &v.state @@ -2124,7 +1984,7 @@ func file_gossip_v1_gossip_proto_init() { return nil } } - file_gossip_v1_gossip_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { + file_gossip_v1_gossip_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*SignedObservationBatch); i { case 0: return &v.state @@ -2136,7 +1996,7 @@ func file_gossip_v1_gossip_proto_init() { return nil } } - file_gossip_v1_gossip_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { + file_gossip_v1_gossip_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Observation); i { case 0: return &v.state @@ -2148,7 +2008,7 @@ func file_gossip_v1_gossip_proto_init() { return nil } } - file_gossip_v1_gossip_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { + file_gossip_v1_gossip_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Heartbeat_Network); i { case 0: return &v.state @@ -2160,7 +2020,7 @@ func file_gossip_v1_gossip_proto_init() { return nil } } - file_gossip_v1_gossip_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { + file_gossip_v1_gossip_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ChainGovernorConfig_Chain); i { case 0: return &v.state @@ -2172,7 +2032,7 @@ func file_gossip_v1_gossip_proto_init() { return nil } } - file_gossip_v1_gossip_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { + file_gossip_v1_gossip_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ChainGovernorConfig_Token); i { case 0: return &v.state @@ -2184,7 +2044,7 @@ func file_gossip_v1_gossip_proto_init() { return nil } } - file_gossip_v1_gossip_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { + file_gossip_v1_gossip_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ChainGovernorStatus_EnqueuedVAA); i { case 0: return &v.state @@ -2196,7 +2056,7 @@ func file_gossip_v1_gossip_proto_init() { return nil } } - file_gossip_v1_gossip_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { + file_gossip_v1_gossip_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ChainGovernorStatus_Emitter); i { case 0: return &v.state @@ -2208,7 +2068,7 @@ func file_gossip_v1_gossip_proto_init() { return nil } } - file_gossip_v1_gossip_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { + file_gossip_v1_gossip_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ChainGovernorStatus_Chain); i { case 0: return &v.state @@ -2222,7 +2082,6 @@ func file_gossip_v1_gossip_proto_init() { } } file_gossip_v1_gossip_proto_msgTypes[0].OneofWrappers = []interface{}{ - (*GossipMessage_SignedObservation)(nil), (*GossipMessage_SignedHeartbeat)(nil), (*GossipMessage_SignedVaaWithQuorum)(nil), (*GossipMessage_SignedObservationRequest)(nil), @@ -2238,7 +2097,7 @@ func file_gossip_v1_gossip_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_gossip_v1_gossip_proto_rawDesc, NumEnums: 0, - NumMessages: 21, + NumMessages: 20, NumExtensions: 0, NumServices: 0, }, diff --git a/node/pkg/proto/publicrpc/v1/publicrpc.pb.go b/node/pkg/proto/publicrpc/v1/publicrpc.pb.go index 87a9bd8e38..f2d012d675 100644 --- a/node/pkg/proto/publicrpc/v1/publicrpc.pb.go +++ b/node/pkg/proto/publicrpc/v1/publicrpc.pb.go @@ -43,18 +43,20 @@ const ( ChainID_CHAIN_ID_NEAR ChainID = 15 ChainID_CHAIN_ID_MOONBEAM ChainID = 16 // OBSOLETE: CHAIN_ID_NEON = 17; - ChainID_CHAIN_ID_TERRA2 ChainID = 18 - ChainID_CHAIN_ID_INJECTIVE ChainID = 19 - ChainID_CHAIN_ID_OSMOSIS ChainID = 20 - ChainID_CHAIN_ID_SUI ChainID = 21 - ChainID_CHAIN_ID_APTOS ChainID = 22 - ChainID_CHAIN_ID_ARBITRUM ChainID = 23 - ChainID_CHAIN_ID_OPTIMISM ChainID = 24 - ChainID_CHAIN_ID_GNOSIS ChainID = 25 - ChainID_CHAIN_ID_PYTHNET ChainID = 26 + ChainID_CHAIN_ID_TERRA2 ChainID = 18 + ChainID_CHAIN_ID_INJECTIVE ChainID = 19 + ChainID_CHAIN_ID_OSMOSIS ChainID = 20 + ChainID_CHAIN_ID_SUI ChainID = 21 + ChainID_CHAIN_ID_APTOS ChainID = 22 + ChainID_CHAIN_ID_ARBITRUM ChainID = 23 + ChainID_CHAIN_ID_OPTIMISM ChainID = 24 + ChainID_CHAIN_ID_GNOSIS ChainID = 25 + ChainID_CHAIN_ID_PYTHNET ChainID = 26 + // 27 belongs to a chain that was never deployed. ChainID_CHAIN_ID_XPLA ChainID = 28 ChainID_CHAIN_ID_BTC ChainID = 29 ChainID_CHAIN_ID_BASE ChainID = 30 + ChainID_CHAIN_ID_FILECOIN ChainID = 31 ChainID_CHAIN_ID_SEI ChainID = 32 ChainID_CHAIN_ID_ROOTSTOCK ChainID = 33 ChainID_CHAIN_ID_SCROLL ChainID = 34 @@ -64,10 +66,15 @@ const ( ChainID_CHAIN_ID_LINEA ChainID = 38 ChainID_CHAIN_ID_BERACHAIN ChainID = 39 ChainID_CHAIN_ID_SEIEVM ChainID = 40 + ChainID_CHAIN_ID_ECLIPSE ChainID = 41 + ChainID_CHAIN_ID_BOB ChainID = 42 ChainID_CHAIN_ID_SNAXCHAIN ChainID = 43 ChainID_CHAIN_ID_UNICHAIN ChainID = 44 ChainID_CHAIN_ID_WORLDCHAIN ChainID = 45 ChainID_CHAIN_ID_INK ChainID = 46 + ChainID_CHAIN_ID_HYPER_EVM ChainID = 47 + ChainID_CHAIN_ID_MONAD ChainID = 48 + ChainID_CHAIN_ID_MOVEMENT ChainID = 49 ChainID_CHAIN_ID_WORMCHAIN ChainID = 3104 ChainID_CHAIN_ID_COSMOSHUB ChainID = 4000 ChainID_CHAIN_ID_EVMOS ChainID = 4001 @@ -78,6 +85,7 @@ const ( ChainID_CHAIN_ID_SEDA ChainID = 4006 ChainID_CHAIN_ID_DYMENSION ChainID = 4007 ChainID_CHAIN_ID_PROVENANCE ChainID = 4008 + ChainID_CHAIN_ID_NOBLE ChainID = 4009 ChainID_CHAIN_ID_SEPOLIA ChainID = 10002 ChainID_CHAIN_ID_ARBITRUM_SEPOLIA ChainID = 10003 ChainID_CHAIN_ID_BASE_SEPOLIA ChainID = 10004 @@ -119,6 +127,7 @@ var ( 28: "CHAIN_ID_XPLA", 29: "CHAIN_ID_BTC", 30: "CHAIN_ID_BASE", + 31: "CHAIN_ID_FILECOIN", 32: "CHAIN_ID_SEI", 33: "CHAIN_ID_ROOTSTOCK", 34: "CHAIN_ID_SCROLL", @@ -128,10 +137,15 @@ var ( 38: "CHAIN_ID_LINEA", 39: "CHAIN_ID_BERACHAIN", 40: "CHAIN_ID_SEIEVM", + 41: "CHAIN_ID_ECLIPSE", + 42: "CHAIN_ID_BOB", 43: "CHAIN_ID_SNAXCHAIN", 44: "CHAIN_ID_UNICHAIN", 45: "CHAIN_ID_WORLDCHAIN", 46: "CHAIN_ID_INK", + 47: "CHAIN_ID_HYPER_EVM", + 48: "CHAIN_ID_MONAD", + 49: "CHAIN_ID_MOVEMENT", 3104: "CHAIN_ID_WORMCHAIN", 4000: "CHAIN_ID_COSMOSHUB", 4001: "CHAIN_ID_EVMOS", @@ -142,6 +156,7 @@ var ( 4006: "CHAIN_ID_SEDA", 4007: "CHAIN_ID_DYMENSION", 4008: "CHAIN_ID_PROVENANCE", + 4009: "CHAIN_ID_NOBLE", 10002: "CHAIN_ID_SEPOLIA", 10003: "CHAIN_ID_ARBITRUM_SEPOLIA", 10004: "CHAIN_ID_BASE_SEPOLIA", @@ -180,6 +195,7 @@ var ( "CHAIN_ID_XPLA": 28, "CHAIN_ID_BTC": 29, "CHAIN_ID_BASE": 30, + "CHAIN_ID_FILECOIN": 31, "CHAIN_ID_SEI": 32, "CHAIN_ID_ROOTSTOCK": 33, "CHAIN_ID_SCROLL": 34, @@ -189,10 +205,15 @@ var ( "CHAIN_ID_LINEA": 38, "CHAIN_ID_BERACHAIN": 39, "CHAIN_ID_SEIEVM": 40, + "CHAIN_ID_ECLIPSE": 41, + "CHAIN_ID_BOB": 42, "CHAIN_ID_SNAXCHAIN": 43, "CHAIN_ID_UNICHAIN": 44, "CHAIN_ID_WORLDCHAIN": 45, "CHAIN_ID_INK": 46, + "CHAIN_ID_HYPER_EVM": 47, + "CHAIN_ID_MONAD": 48, + "CHAIN_ID_MOVEMENT": 49, "CHAIN_ID_WORMCHAIN": 3104, "CHAIN_ID_COSMOSHUB": 4000, "CHAIN_ID_EVMOS": 4001, @@ -203,6 +224,7 @@ var ( "CHAIN_ID_SEDA": 4006, "CHAIN_ID_DYMENSION": 4007, "CHAIN_ID_PROVENANCE": 4008, + "CHAIN_ID_NOBLE": 4009, "CHAIN_ID_SEPOLIA": 10002, "CHAIN_ID_ARBITRUM_SEPOLIA": 10003, "CHAIN_ID_BASE_SEPOLIA": 10004, @@ -1400,7 +1422,7 @@ var file_publicrpc_v1_publicrpc_proto_rawDesc = []byte{ 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x70, 0x72, 0x69, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x02, 0x52, 0x05, 0x70, 0x72, 0x69, - 0x63, 0x65, 0x2a, 0xb5, 0x0a, 0x0a, 0x07, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x44, 0x12, 0x18, + 0x63, 0x65, 0x2a, 0xcc, 0x0b, 0x0a, 0x07, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x44, 0x12, 0x18, 0x0a, 0x14, 0x43, 0x48, 0x41, 0x49, 0x4e, 0x5f, 0x49, 0x44, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x13, 0x0a, 0x0f, 0x43, 0x48, 0x41, 0x49, 0x4e, 0x5f, 0x49, 0x44, 0x5f, 0x53, 0x4f, 0x4c, 0x41, 0x4e, 0x41, 0x10, 0x01, 0x12, 0x15, 0x0a, @@ -1439,133 +1461,142 @@ var file_publicrpc_v1_publicrpc_proto_rawDesc = []byte{ 0x41, 0x49, 0x4e, 0x5f, 0x49, 0x44, 0x5f, 0x58, 0x50, 0x4c, 0x41, 0x10, 0x1c, 0x12, 0x10, 0x0a, 0x0c, 0x43, 0x48, 0x41, 0x49, 0x4e, 0x5f, 0x49, 0x44, 0x5f, 0x42, 0x54, 0x43, 0x10, 0x1d, 0x12, 0x11, 0x0a, 0x0d, 0x43, 0x48, 0x41, 0x49, 0x4e, 0x5f, 0x49, 0x44, 0x5f, 0x42, 0x41, 0x53, 0x45, - 0x10, 0x1e, 0x12, 0x10, 0x0a, 0x0c, 0x43, 0x48, 0x41, 0x49, 0x4e, 0x5f, 0x49, 0x44, 0x5f, 0x53, - 0x45, 0x49, 0x10, 0x20, 0x12, 0x16, 0x0a, 0x12, 0x43, 0x48, 0x41, 0x49, 0x4e, 0x5f, 0x49, 0x44, - 0x5f, 0x52, 0x4f, 0x4f, 0x54, 0x53, 0x54, 0x4f, 0x43, 0x4b, 0x10, 0x21, 0x12, 0x13, 0x0a, 0x0f, - 0x43, 0x48, 0x41, 0x49, 0x4e, 0x5f, 0x49, 0x44, 0x5f, 0x53, 0x43, 0x52, 0x4f, 0x4c, 0x4c, 0x10, - 0x22, 0x12, 0x13, 0x0a, 0x0f, 0x43, 0x48, 0x41, 0x49, 0x4e, 0x5f, 0x49, 0x44, 0x5f, 0x4d, 0x41, - 0x4e, 0x54, 0x4c, 0x45, 0x10, 0x23, 0x12, 0x12, 0x0a, 0x0e, 0x43, 0x48, 0x41, 0x49, 0x4e, 0x5f, - 0x49, 0x44, 0x5f, 0x42, 0x4c, 0x41, 0x53, 0x54, 0x10, 0x24, 0x12, 0x13, 0x0a, 0x0f, 0x43, 0x48, - 0x41, 0x49, 0x4e, 0x5f, 0x49, 0x44, 0x5f, 0x58, 0x4c, 0x41, 0x59, 0x45, 0x52, 0x10, 0x25, 0x12, - 0x12, 0x0a, 0x0e, 0x43, 0x48, 0x41, 0x49, 0x4e, 0x5f, 0x49, 0x44, 0x5f, 0x4c, 0x49, 0x4e, 0x45, - 0x41, 0x10, 0x26, 0x12, 0x16, 0x0a, 0x12, 0x43, 0x48, 0x41, 0x49, 0x4e, 0x5f, 0x49, 0x44, 0x5f, - 0x42, 0x45, 0x52, 0x41, 0x43, 0x48, 0x41, 0x49, 0x4e, 0x10, 0x27, 0x12, 0x13, 0x0a, 0x0f, 0x43, - 0x48, 0x41, 0x49, 0x4e, 0x5f, 0x49, 0x44, 0x5f, 0x53, 0x45, 0x49, 0x45, 0x56, 0x4d, 0x10, 0x28, - 0x12, 0x16, 0x0a, 0x12, 0x43, 0x48, 0x41, 0x49, 0x4e, 0x5f, 0x49, 0x44, 0x5f, 0x53, 0x4e, 0x41, - 0x58, 0x43, 0x48, 0x41, 0x49, 0x4e, 0x10, 0x2b, 0x12, 0x15, 0x0a, 0x11, 0x43, 0x48, 0x41, 0x49, - 0x4e, 0x5f, 0x49, 0x44, 0x5f, 0x55, 0x4e, 0x49, 0x43, 0x48, 0x41, 0x49, 0x4e, 0x10, 0x2c, 0x12, - 0x17, 0x0a, 0x13, 0x43, 0x48, 0x41, 0x49, 0x4e, 0x5f, 0x49, 0x44, 0x5f, 0x57, 0x4f, 0x52, 0x4c, - 0x44, 0x43, 0x48, 0x41, 0x49, 0x4e, 0x10, 0x2d, 0x12, 0x10, 0x0a, 0x0c, 0x43, 0x48, 0x41, 0x49, - 0x4e, 0x5f, 0x49, 0x44, 0x5f, 0x49, 0x4e, 0x4b, 0x10, 0x2e, 0x12, 0x17, 0x0a, 0x12, 0x43, 0x48, - 0x41, 0x49, 0x4e, 0x5f, 0x49, 0x44, 0x5f, 0x57, 0x4f, 0x52, 0x4d, 0x43, 0x48, 0x41, 0x49, 0x4e, - 0x10, 0xa0, 0x18, 0x12, 0x17, 0x0a, 0x12, 0x43, 0x48, 0x41, 0x49, 0x4e, 0x5f, 0x49, 0x44, 0x5f, - 0x43, 0x4f, 0x53, 0x4d, 0x4f, 0x53, 0x48, 0x55, 0x42, 0x10, 0xa0, 0x1f, 0x12, 0x13, 0x0a, 0x0e, - 0x43, 0x48, 0x41, 0x49, 0x4e, 0x5f, 0x49, 0x44, 0x5f, 0x45, 0x56, 0x4d, 0x4f, 0x53, 0x10, 0xa1, - 0x1f, 0x12, 0x14, 0x0a, 0x0f, 0x43, 0x48, 0x41, 0x49, 0x4e, 0x5f, 0x49, 0x44, 0x5f, 0x4b, 0x55, - 0x4a, 0x49, 0x52, 0x41, 0x10, 0xa2, 0x1f, 0x12, 0x15, 0x0a, 0x10, 0x43, 0x48, 0x41, 0x49, 0x4e, - 0x5f, 0x49, 0x44, 0x5f, 0x4e, 0x45, 0x55, 0x54, 0x52, 0x4f, 0x4e, 0x10, 0xa3, 0x1f, 0x12, 0x16, - 0x0a, 0x11, 0x43, 0x48, 0x41, 0x49, 0x4e, 0x5f, 0x49, 0x44, 0x5f, 0x43, 0x45, 0x4c, 0x45, 0x53, - 0x54, 0x49, 0x41, 0x10, 0xa4, 0x1f, 0x12, 0x16, 0x0a, 0x11, 0x43, 0x48, 0x41, 0x49, 0x4e, 0x5f, - 0x49, 0x44, 0x5f, 0x53, 0x54, 0x41, 0x52, 0x47, 0x41, 0x5a, 0x45, 0x10, 0xa5, 0x1f, 0x12, 0x12, - 0x0a, 0x0d, 0x43, 0x48, 0x41, 0x49, 0x4e, 0x5f, 0x49, 0x44, 0x5f, 0x53, 0x45, 0x44, 0x41, 0x10, - 0xa6, 0x1f, 0x12, 0x17, 0x0a, 0x12, 0x43, 0x48, 0x41, 0x49, 0x4e, 0x5f, 0x49, 0x44, 0x5f, 0x44, - 0x59, 0x4d, 0x45, 0x4e, 0x53, 0x49, 0x4f, 0x4e, 0x10, 0xa7, 0x1f, 0x12, 0x18, 0x0a, 0x13, 0x43, - 0x48, 0x41, 0x49, 0x4e, 0x5f, 0x49, 0x44, 0x5f, 0x50, 0x52, 0x4f, 0x56, 0x45, 0x4e, 0x41, 0x4e, - 0x43, 0x45, 0x10, 0xa8, 0x1f, 0x12, 0x15, 0x0a, 0x10, 0x43, 0x48, 0x41, 0x49, 0x4e, 0x5f, 0x49, - 0x44, 0x5f, 0x53, 0x45, 0x50, 0x4f, 0x4c, 0x49, 0x41, 0x10, 0x92, 0x4e, 0x12, 0x1e, 0x0a, 0x19, - 0x43, 0x48, 0x41, 0x49, 0x4e, 0x5f, 0x49, 0x44, 0x5f, 0x41, 0x52, 0x42, 0x49, 0x54, 0x52, 0x55, - 0x4d, 0x5f, 0x53, 0x45, 0x50, 0x4f, 0x4c, 0x49, 0x41, 0x10, 0x93, 0x4e, 0x12, 0x1a, 0x0a, 0x15, - 0x43, 0x48, 0x41, 0x49, 0x4e, 0x5f, 0x49, 0x44, 0x5f, 0x42, 0x41, 0x53, 0x45, 0x5f, 0x53, 0x45, - 0x50, 0x4f, 0x4c, 0x49, 0x41, 0x10, 0x94, 0x4e, 0x12, 0x1e, 0x0a, 0x19, 0x43, 0x48, 0x41, 0x49, - 0x4e, 0x5f, 0x49, 0x44, 0x5f, 0x4f, 0x50, 0x54, 0x49, 0x4d, 0x49, 0x53, 0x4d, 0x5f, 0x53, 0x45, - 0x50, 0x4f, 0x4c, 0x49, 0x41, 0x10, 0x95, 0x4e, 0x12, 0x15, 0x0a, 0x10, 0x43, 0x48, 0x41, 0x49, - 0x4e, 0x5f, 0x49, 0x44, 0x5f, 0x48, 0x4f, 0x4c, 0x45, 0x53, 0x4b, 0x59, 0x10, 0x96, 0x4e, 0x12, - 0x1d, 0x0a, 0x18, 0x43, 0x48, 0x41, 0x49, 0x4e, 0x5f, 0x49, 0x44, 0x5f, 0x50, 0x4f, 0x4c, 0x59, - 0x47, 0x4f, 0x4e, 0x5f, 0x53, 0x45, 0x50, 0x4f, 0x4c, 0x49, 0x41, 0x10, 0x97, 0x4e, 0x12, 0x1a, - 0x0a, 0x15, 0x43, 0x48, 0x41, 0x49, 0x4e, 0x5f, 0x49, 0x44, 0x5f, 0x4d, 0x4f, 0x4e, 0x41, 0x44, - 0x5f, 0x44, 0x45, 0x56, 0x4e, 0x45, 0x54, 0x10, 0x98, 0x4e, 0x32, 0xc6, 0x09, 0x0a, 0x10, 0x50, - 0x75, 0x62, 0x6c, 0x69, 0x63, 0x52, 0x50, 0x43, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, - 0x7c, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x4c, 0x61, 0x73, 0x74, 0x48, 0x65, 0x61, 0x72, 0x74, 0x62, - 0x65, 0x61, 0x74, 0x73, 0x12, 0x26, 0x2e, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x72, 0x70, 0x63, - 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4c, 0x61, 0x73, 0x74, 0x48, 0x65, 0x61, 0x72, 0x74, - 0x62, 0x65, 0x61, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x70, - 0x75, 0x62, 0x6c, 0x69, 0x63, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4c, - 0x61, 0x73, 0x74, 0x48, 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x73, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x16, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x10, 0x12, 0x0e, 0x2f, - 0x76, 0x31, 0x2f, 0x68, 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x73, 0x12, 0xbb, 0x01, - 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x56, 0x41, 0x41, 0x12, 0x21, - 0x2e, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, - 0x74, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x56, 0x41, 0x41, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x22, 0x2e, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, - 0x2e, 0x47, 0x65, 0x74, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x56, 0x41, 0x41, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x64, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x5e, 0x12, 0x5c, 0x2f, - 0x76, 0x31, 0x2f, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x5f, 0x76, 0x61, 0x61, 0x2f, 0x7b, 0x6d, - 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x69, 0x64, 0x2e, 0x65, 0x6d, 0x69, 0x74, 0x74, 0x65, - 0x72, 0x5f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x7d, 0x2f, 0x7b, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, - 0x65, 0x5f, 0x69, 0x64, 0x2e, 0x65, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x72, 0x5f, 0x61, 0x64, 0x64, - 0x72, 0x65, 0x73, 0x73, 0x7d, 0x2f, 0x7b, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x69, - 0x64, 0x2e, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x7d, 0x12, 0x91, 0x01, 0x0a, 0x15, - 0x47, 0x65, 0x74, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x47, 0x75, 0x61, 0x72, 0x64, 0x69, - 0x61, 0x6e, 0x53, 0x65, 0x74, 0x12, 0x2a, 0x2e, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x72, 0x70, - 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x47, - 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x53, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x2b, 0x2e, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, - 0x2e, 0x47, 0x65, 0x74, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x47, 0x75, 0x61, 0x72, 0x64, - 0x69, 0x61, 0x6e, 0x53, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1f, - 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x19, 0x12, 0x17, 0x2f, 0x76, 0x31, 0x2f, 0x67, 0x75, 0x61, 0x72, - 0x64, 0x69, 0x61, 0x6e, 0x73, 0x65, 0x74, 0x2f, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x12, - 0xcc, 0x01, 0x0a, 0x23, 0x47, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72, 0x47, 0x65, 0x74, 0x41, - 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, - 0x42, 0x79, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x12, 0x38, 0x2e, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, - 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72, 0x47, - 0x65, 0x74, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x6f, 0x74, 0x69, 0x6f, - 0x6e, 0x61, 0x6c, 0x42, 0x79, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x39, 0x2e, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, - 0x2e, 0x47, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72, 0x47, 0x65, 0x74, 0x41, 0x76, 0x61, 0x69, - 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x42, 0x79, 0x43, - 0x68, 0x61, 0x69, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x30, 0x82, 0xd3, - 0xe4, 0x93, 0x02, 0x2a, 0x12, 0x28, 0x2f, 0x76, 0x31, 0x2f, 0x67, 0x6f, 0x76, 0x65, 0x72, 0x6e, - 0x6f, 0x72, 0x2f, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x6e, 0x6f, 0x74, - 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x5f, 0x62, 0x79, 0x5f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x12, 0x9a, - 0x01, 0x0a, 0x17, 0x47, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72, 0x47, 0x65, 0x74, 0x45, 0x6e, - 0x71, 0x75, 0x65, 0x75, 0x65, 0x64, 0x56, 0x41, 0x41, 0x73, 0x12, 0x2c, 0x2e, 0x70, 0x75, 0x62, - 0x6c, 0x69, 0x63, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x6f, 0x76, 0x65, 0x72, 0x6e, - 0x6f, 0x72, 0x47, 0x65, 0x74, 0x45, 0x6e, 0x71, 0x75, 0x65, 0x75, 0x65, 0x64, 0x56, 0x41, 0x41, - 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2d, 0x2e, 0x70, 0x75, 0x62, 0x6c, 0x69, - 0x63, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72, - 0x47, 0x65, 0x74, 0x45, 0x6e, 0x71, 0x75, 0x65, 0x75, 0x65, 0x64, 0x56, 0x41, 0x41, 0x73, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x22, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1c, 0x12, - 0x1a, 0x2f, 0x76, 0x31, 0x2f, 0x67, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72, 0x2f, 0x65, 0x6e, - 0x71, 0x75, 0x65, 0x75, 0x65, 0x64, 0x5f, 0x76, 0x61, 0x61, 0x73, 0x12, 0xe4, 0x01, 0x0a, 0x15, - 0x47, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72, 0x49, 0x73, 0x56, 0x41, 0x41, 0x45, 0x6e, 0x71, - 0x75, 0x65, 0x75, 0x65, 0x64, 0x12, 0x2a, 0x2e, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x72, 0x70, - 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72, 0x49, 0x73, 0x56, - 0x41, 0x41, 0x45, 0x6e, 0x71, 0x75, 0x65, 0x75, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x2b, 0x2e, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, - 0x2e, 0x47, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72, 0x49, 0x73, 0x56, 0x41, 0x41, 0x45, 0x6e, - 0x71, 0x75, 0x65, 0x75, 0x65, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x72, - 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x6c, 0x12, 0x6a, 0x2f, 0x76, 0x31, 0x2f, 0x67, 0x6f, 0x76, 0x65, - 0x72, 0x6e, 0x6f, 0x72, 0x2f, 0x69, 0x73, 0x5f, 0x76, 0x61, 0x61, 0x5f, 0x65, 0x6e, 0x71, 0x75, - 0x65, 0x75, 0x65, 0x64, 0x2f, 0x7b, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x69, 0x64, + 0x10, 0x1e, 0x12, 0x15, 0x0a, 0x11, 0x43, 0x48, 0x41, 0x49, 0x4e, 0x5f, 0x49, 0x44, 0x5f, 0x46, + 0x49, 0x4c, 0x45, 0x43, 0x4f, 0x49, 0x4e, 0x10, 0x1f, 0x12, 0x10, 0x0a, 0x0c, 0x43, 0x48, 0x41, + 0x49, 0x4e, 0x5f, 0x49, 0x44, 0x5f, 0x53, 0x45, 0x49, 0x10, 0x20, 0x12, 0x16, 0x0a, 0x12, 0x43, + 0x48, 0x41, 0x49, 0x4e, 0x5f, 0x49, 0x44, 0x5f, 0x52, 0x4f, 0x4f, 0x54, 0x53, 0x54, 0x4f, 0x43, + 0x4b, 0x10, 0x21, 0x12, 0x13, 0x0a, 0x0f, 0x43, 0x48, 0x41, 0x49, 0x4e, 0x5f, 0x49, 0x44, 0x5f, + 0x53, 0x43, 0x52, 0x4f, 0x4c, 0x4c, 0x10, 0x22, 0x12, 0x13, 0x0a, 0x0f, 0x43, 0x48, 0x41, 0x49, + 0x4e, 0x5f, 0x49, 0x44, 0x5f, 0x4d, 0x41, 0x4e, 0x54, 0x4c, 0x45, 0x10, 0x23, 0x12, 0x12, 0x0a, + 0x0e, 0x43, 0x48, 0x41, 0x49, 0x4e, 0x5f, 0x49, 0x44, 0x5f, 0x42, 0x4c, 0x41, 0x53, 0x54, 0x10, + 0x24, 0x12, 0x13, 0x0a, 0x0f, 0x43, 0x48, 0x41, 0x49, 0x4e, 0x5f, 0x49, 0x44, 0x5f, 0x58, 0x4c, + 0x41, 0x59, 0x45, 0x52, 0x10, 0x25, 0x12, 0x12, 0x0a, 0x0e, 0x43, 0x48, 0x41, 0x49, 0x4e, 0x5f, + 0x49, 0x44, 0x5f, 0x4c, 0x49, 0x4e, 0x45, 0x41, 0x10, 0x26, 0x12, 0x16, 0x0a, 0x12, 0x43, 0x48, + 0x41, 0x49, 0x4e, 0x5f, 0x49, 0x44, 0x5f, 0x42, 0x45, 0x52, 0x41, 0x43, 0x48, 0x41, 0x49, 0x4e, + 0x10, 0x27, 0x12, 0x13, 0x0a, 0x0f, 0x43, 0x48, 0x41, 0x49, 0x4e, 0x5f, 0x49, 0x44, 0x5f, 0x53, + 0x45, 0x49, 0x45, 0x56, 0x4d, 0x10, 0x28, 0x12, 0x14, 0x0a, 0x10, 0x43, 0x48, 0x41, 0x49, 0x4e, + 0x5f, 0x49, 0x44, 0x5f, 0x45, 0x43, 0x4c, 0x49, 0x50, 0x53, 0x45, 0x10, 0x29, 0x12, 0x10, 0x0a, + 0x0c, 0x43, 0x48, 0x41, 0x49, 0x4e, 0x5f, 0x49, 0x44, 0x5f, 0x42, 0x4f, 0x42, 0x10, 0x2a, 0x12, + 0x16, 0x0a, 0x12, 0x43, 0x48, 0x41, 0x49, 0x4e, 0x5f, 0x49, 0x44, 0x5f, 0x53, 0x4e, 0x41, 0x58, + 0x43, 0x48, 0x41, 0x49, 0x4e, 0x10, 0x2b, 0x12, 0x15, 0x0a, 0x11, 0x43, 0x48, 0x41, 0x49, 0x4e, + 0x5f, 0x49, 0x44, 0x5f, 0x55, 0x4e, 0x49, 0x43, 0x48, 0x41, 0x49, 0x4e, 0x10, 0x2c, 0x12, 0x17, + 0x0a, 0x13, 0x43, 0x48, 0x41, 0x49, 0x4e, 0x5f, 0x49, 0x44, 0x5f, 0x57, 0x4f, 0x52, 0x4c, 0x44, + 0x43, 0x48, 0x41, 0x49, 0x4e, 0x10, 0x2d, 0x12, 0x10, 0x0a, 0x0c, 0x43, 0x48, 0x41, 0x49, 0x4e, + 0x5f, 0x49, 0x44, 0x5f, 0x49, 0x4e, 0x4b, 0x10, 0x2e, 0x12, 0x16, 0x0a, 0x12, 0x43, 0x48, 0x41, + 0x49, 0x4e, 0x5f, 0x49, 0x44, 0x5f, 0x48, 0x59, 0x50, 0x45, 0x52, 0x5f, 0x45, 0x56, 0x4d, 0x10, + 0x2f, 0x12, 0x12, 0x0a, 0x0e, 0x43, 0x48, 0x41, 0x49, 0x4e, 0x5f, 0x49, 0x44, 0x5f, 0x4d, 0x4f, + 0x4e, 0x41, 0x44, 0x10, 0x30, 0x12, 0x15, 0x0a, 0x11, 0x43, 0x48, 0x41, 0x49, 0x4e, 0x5f, 0x49, + 0x44, 0x5f, 0x4d, 0x4f, 0x56, 0x45, 0x4d, 0x45, 0x4e, 0x54, 0x10, 0x31, 0x12, 0x17, 0x0a, 0x12, + 0x43, 0x48, 0x41, 0x49, 0x4e, 0x5f, 0x49, 0x44, 0x5f, 0x57, 0x4f, 0x52, 0x4d, 0x43, 0x48, 0x41, + 0x49, 0x4e, 0x10, 0xa0, 0x18, 0x12, 0x17, 0x0a, 0x12, 0x43, 0x48, 0x41, 0x49, 0x4e, 0x5f, 0x49, + 0x44, 0x5f, 0x43, 0x4f, 0x53, 0x4d, 0x4f, 0x53, 0x48, 0x55, 0x42, 0x10, 0xa0, 0x1f, 0x12, 0x13, + 0x0a, 0x0e, 0x43, 0x48, 0x41, 0x49, 0x4e, 0x5f, 0x49, 0x44, 0x5f, 0x45, 0x56, 0x4d, 0x4f, 0x53, + 0x10, 0xa1, 0x1f, 0x12, 0x14, 0x0a, 0x0f, 0x43, 0x48, 0x41, 0x49, 0x4e, 0x5f, 0x49, 0x44, 0x5f, + 0x4b, 0x55, 0x4a, 0x49, 0x52, 0x41, 0x10, 0xa2, 0x1f, 0x12, 0x15, 0x0a, 0x10, 0x43, 0x48, 0x41, + 0x49, 0x4e, 0x5f, 0x49, 0x44, 0x5f, 0x4e, 0x45, 0x55, 0x54, 0x52, 0x4f, 0x4e, 0x10, 0xa3, 0x1f, + 0x12, 0x16, 0x0a, 0x11, 0x43, 0x48, 0x41, 0x49, 0x4e, 0x5f, 0x49, 0x44, 0x5f, 0x43, 0x45, 0x4c, + 0x45, 0x53, 0x54, 0x49, 0x41, 0x10, 0xa4, 0x1f, 0x12, 0x16, 0x0a, 0x11, 0x43, 0x48, 0x41, 0x49, + 0x4e, 0x5f, 0x49, 0x44, 0x5f, 0x53, 0x54, 0x41, 0x52, 0x47, 0x41, 0x5a, 0x45, 0x10, 0xa5, 0x1f, + 0x12, 0x12, 0x0a, 0x0d, 0x43, 0x48, 0x41, 0x49, 0x4e, 0x5f, 0x49, 0x44, 0x5f, 0x53, 0x45, 0x44, + 0x41, 0x10, 0xa6, 0x1f, 0x12, 0x17, 0x0a, 0x12, 0x43, 0x48, 0x41, 0x49, 0x4e, 0x5f, 0x49, 0x44, + 0x5f, 0x44, 0x59, 0x4d, 0x45, 0x4e, 0x53, 0x49, 0x4f, 0x4e, 0x10, 0xa7, 0x1f, 0x12, 0x18, 0x0a, + 0x13, 0x43, 0x48, 0x41, 0x49, 0x4e, 0x5f, 0x49, 0x44, 0x5f, 0x50, 0x52, 0x4f, 0x56, 0x45, 0x4e, + 0x41, 0x4e, 0x43, 0x45, 0x10, 0xa8, 0x1f, 0x12, 0x13, 0x0a, 0x0e, 0x43, 0x48, 0x41, 0x49, 0x4e, + 0x5f, 0x49, 0x44, 0x5f, 0x4e, 0x4f, 0x42, 0x4c, 0x45, 0x10, 0xa9, 0x1f, 0x12, 0x15, 0x0a, 0x10, + 0x43, 0x48, 0x41, 0x49, 0x4e, 0x5f, 0x49, 0x44, 0x5f, 0x53, 0x45, 0x50, 0x4f, 0x4c, 0x49, 0x41, + 0x10, 0x92, 0x4e, 0x12, 0x1e, 0x0a, 0x19, 0x43, 0x48, 0x41, 0x49, 0x4e, 0x5f, 0x49, 0x44, 0x5f, + 0x41, 0x52, 0x42, 0x49, 0x54, 0x52, 0x55, 0x4d, 0x5f, 0x53, 0x45, 0x50, 0x4f, 0x4c, 0x49, 0x41, + 0x10, 0x93, 0x4e, 0x12, 0x1a, 0x0a, 0x15, 0x43, 0x48, 0x41, 0x49, 0x4e, 0x5f, 0x49, 0x44, 0x5f, + 0x42, 0x41, 0x53, 0x45, 0x5f, 0x53, 0x45, 0x50, 0x4f, 0x4c, 0x49, 0x41, 0x10, 0x94, 0x4e, 0x12, + 0x1e, 0x0a, 0x19, 0x43, 0x48, 0x41, 0x49, 0x4e, 0x5f, 0x49, 0x44, 0x5f, 0x4f, 0x50, 0x54, 0x49, + 0x4d, 0x49, 0x53, 0x4d, 0x5f, 0x53, 0x45, 0x50, 0x4f, 0x4c, 0x49, 0x41, 0x10, 0x95, 0x4e, 0x12, + 0x15, 0x0a, 0x10, 0x43, 0x48, 0x41, 0x49, 0x4e, 0x5f, 0x49, 0x44, 0x5f, 0x48, 0x4f, 0x4c, 0x45, + 0x53, 0x4b, 0x59, 0x10, 0x96, 0x4e, 0x12, 0x1d, 0x0a, 0x18, 0x43, 0x48, 0x41, 0x49, 0x4e, 0x5f, + 0x49, 0x44, 0x5f, 0x50, 0x4f, 0x4c, 0x59, 0x47, 0x4f, 0x4e, 0x5f, 0x53, 0x45, 0x50, 0x4f, 0x4c, + 0x49, 0x41, 0x10, 0x97, 0x4e, 0x12, 0x1a, 0x0a, 0x15, 0x43, 0x48, 0x41, 0x49, 0x4e, 0x5f, 0x49, + 0x44, 0x5f, 0x4d, 0x4f, 0x4e, 0x41, 0x44, 0x5f, 0x44, 0x45, 0x56, 0x4e, 0x45, 0x54, 0x10, 0x98, + 0x4e, 0x32, 0xc6, 0x09, 0x0a, 0x10, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x52, 0x50, 0x43, 0x53, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x7c, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x4c, 0x61, 0x73, + 0x74, 0x48, 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x73, 0x12, 0x26, 0x2e, 0x70, 0x75, + 0x62, 0x6c, 0x69, 0x63, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4c, 0x61, + 0x73, 0x74, 0x48, 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x72, 0x70, 0x63, 0x2e, + 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4c, 0x61, 0x73, 0x74, 0x48, 0x65, 0x61, 0x72, 0x74, 0x62, + 0x65, 0x61, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x16, 0x82, 0xd3, + 0xe4, 0x93, 0x02, 0x10, 0x12, 0x0e, 0x2f, 0x76, 0x31, 0x2f, 0x68, 0x65, 0x61, 0x72, 0x74, 0x62, + 0x65, 0x61, 0x74, 0x73, 0x12, 0xbb, 0x01, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x53, 0x69, 0x67, 0x6e, + 0x65, 0x64, 0x56, 0x41, 0x41, 0x12, 0x21, 0x2e, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x72, 0x70, + 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x56, 0x41, + 0x41, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x70, 0x75, 0x62, 0x6c, 0x69, + 0x63, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x69, 0x67, 0x6e, 0x65, + 0x64, 0x56, 0x41, 0x41, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x64, 0x82, 0xd3, + 0xe4, 0x93, 0x02, 0x5e, 0x12, 0x5c, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, + 0x5f, 0x76, 0x61, 0x61, 0x2f, 0x7b, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x69, 0x64, 0x2e, 0x65, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x72, 0x5f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x7d, 0x2f, 0x7b, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x69, 0x64, 0x2e, 0x65, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x7d, 0x2f, 0x7b, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x69, 0x64, 0x2e, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, - 0x65, 0x7d, 0x12, 0x8e, 0x01, 0x0a, 0x14, 0x47, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72, 0x47, - 0x65, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x29, 0x2e, 0x70, 0x75, - 0x62, 0x6c, 0x69, 0x63, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x6f, 0x76, 0x65, 0x72, - 0x6e, 0x6f, 0x72, 0x47, 0x65, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x4c, 0x69, 0x73, 0x74, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x72, - 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72, 0x47, 0x65, - 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x1f, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x19, 0x12, 0x17, 0x2f, 0x76, 0x31, 0x2f, - 0x67, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72, 0x2f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x5f, 0x6c, - 0x69, 0x73, 0x74, 0x42, 0x47, 0x5a, 0x45, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, - 0x6d, 0x2f, 0x63, 0x65, 0x72, 0x74, 0x75, 0x73, 0x6f, 0x6e, 0x65, 0x2f, 0x77, 0x6f, 0x72, 0x6d, - 0x68, 0x6f, 0x6c, 0x65, 0x2f, 0x6e, 0x6f, 0x64, 0x65, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x2f, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x72, 0x70, 0x63, 0x2f, 0x76, 0x31, - 0x3b, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x72, 0x70, 0x63, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x33, + 0x65, 0x7d, 0x12, 0x91, 0x01, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, + 0x74, 0x47, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x53, 0x65, 0x74, 0x12, 0x2a, 0x2e, 0x70, + 0x75, 0x62, 0x6c, 0x69, 0x63, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x43, + 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x47, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x53, 0x65, + 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x70, 0x75, 0x62, 0x6c, 0x69, + 0x63, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x75, 0x72, 0x72, 0x65, + 0x6e, 0x74, 0x47, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x53, 0x65, 0x74, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1f, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x19, 0x12, 0x17, 0x2f, + 0x76, 0x31, 0x2f, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x73, 0x65, 0x74, 0x2f, 0x63, + 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x12, 0xcc, 0x01, 0x0a, 0x23, 0x47, 0x6f, 0x76, 0x65, 0x72, + 0x6e, 0x6f, 0x72, 0x47, 0x65, 0x74, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x4e, + 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x42, 0x79, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x12, 0x38, + 0x2e, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x6f, + 0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72, 0x47, 0x65, 0x74, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, + 0x6c, 0x65, 0x4e, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x42, 0x79, 0x43, 0x68, 0x61, 0x69, + 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x39, 0x2e, 0x70, 0x75, 0x62, 0x6c, 0x69, + 0x63, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72, + 0x47, 0x65, 0x74, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x6f, 0x74, 0x69, + 0x6f, 0x6e, 0x61, 0x6c, 0x42, 0x79, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x30, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2a, 0x12, 0x28, 0x2f, 0x76, 0x31, + 0x2f, 0x67, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72, 0x2f, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, + 0x62, 0x6c, 0x65, 0x5f, 0x6e, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x5f, 0x62, 0x79, 0x5f, + 0x63, 0x68, 0x61, 0x69, 0x6e, 0x12, 0x9a, 0x01, 0x0a, 0x17, 0x47, 0x6f, 0x76, 0x65, 0x72, 0x6e, + 0x6f, 0x72, 0x47, 0x65, 0x74, 0x45, 0x6e, 0x71, 0x75, 0x65, 0x75, 0x65, 0x64, 0x56, 0x41, 0x41, + 0x73, 0x12, 0x2c, 0x2e, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, + 0x2e, 0x47, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72, 0x47, 0x65, 0x74, 0x45, 0x6e, 0x71, 0x75, + 0x65, 0x75, 0x65, 0x64, 0x56, 0x41, 0x41, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x2d, 0x2e, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x47, + 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72, 0x47, 0x65, 0x74, 0x45, 0x6e, 0x71, 0x75, 0x65, 0x75, + 0x65, 0x64, 0x56, 0x41, 0x41, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x22, + 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1c, 0x12, 0x1a, 0x2f, 0x76, 0x31, 0x2f, 0x67, 0x6f, 0x76, 0x65, + 0x72, 0x6e, 0x6f, 0x72, 0x2f, 0x65, 0x6e, 0x71, 0x75, 0x65, 0x75, 0x65, 0x64, 0x5f, 0x76, 0x61, + 0x61, 0x73, 0x12, 0xe4, 0x01, 0x0a, 0x15, 0x47, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72, 0x49, + 0x73, 0x56, 0x41, 0x41, 0x45, 0x6e, 0x71, 0x75, 0x65, 0x75, 0x65, 0x64, 0x12, 0x2a, 0x2e, 0x70, + 0x75, 0x62, 0x6c, 0x69, 0x63, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x6f, 0x76, 0x65, + 0x72, 0x6e, 0x6f, 0x72, 0x49, 0x73, 0x56, 0x41, 0x41, 0x45, 0x6e, 0x71, 0x75, 0x65, 0x75, 0x65, + 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x70, 0x75, 0x62, 0x6c, 0x69, + 0x63, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72, + 0x49, 0x73, 0x56, 0x41, 0x41, 0x45, 0x6e, 0x71, 0x75, 0x65, 0x75, 0x65, 0x64, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x72, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x6c, 0x12, 0x6a, 0x2f, + 0x76, 0x31, 0x2f, 0x67, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72, 0x2f, 0x69, 0x73, 0x5f, 0x76, + 0x61, 0x61, 0x5f, 0x65, 0x6e, 0x71, 0x75, 0x65, 0x75, 0x65, 0x64, 0x2f, 0x7b, 0x6d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x5f, 0x69, 0x64, 0x2e, 0x65, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x72, 0x5f, + 0x63, 0x68, 0x61, 0x69, 0x6e, 0x7d, 0x2f, 0x7b, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, + 0x69, 0x64, 0x2e, 0x65, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, + 0x73, 0x73, 0x7d, 0x2f, 0x7b, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x69, 0x64, 0x2e, + 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x7d, 0x12, 0x8e, 0x01, 0x0a, 0x14, 0x47, 0x6f, + 0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72, 0x47, 0x65, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x4c, 0x69, + 0x73, 0x74, 0x12, 0x29, 0x2e, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x72, 0x70, 0x63, 0x2e, 0x76, + 0x31, 0x2e, 0x47, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72, 0x47, 0x65, 0x74, 0x54, 0x6f, 0x6b, + 0x65, 0x6e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, + 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x6f, 0x76, + 0x65, 0x72, 0x6e, 0x6f, 0x72, 0x47, 0x65, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x4c, 0x69, 0x73, + 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1f, 0x82, 0xd3, 0xe4, 0x93, 0x02, + 0x19, 0x12, 0x17, 0x2f, 0x76, 0x31, 0x2f, 0x67, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x6f, 0x72, 0x2f, + 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x42, 0x47, 0x5a, 0x45, 0x67, 0x69, + 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x65, 0x72, 0x74, 0x75, 0x73, 0x6f, + 0x6e, 0x65, 0x2f, 0x77, 0x6f, 0x72, 0x6d, 0x68, 0x6f, 0x6c, 0x65, 0x2f, 0x6e, 0x6f, 0x64, 0x65, + 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x70, 0x75, 0x62, 0x6c, 0x69, + 0x63, 0x72, 0x70, 0x63, 0x2f, 0x76, 0x31, 0x3b, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x72, 0x70, + 0x63, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/node/pkg/query/query.go b/node/pkg/query/query.go index 94d13e7413..43ddf437ff 100644 --- a/node/pkg/query/query.go +++ b/node/pkg/query/query.go @@ -142,6 +142,8 @@ var perChainConfig = map[vaa.ChainID]PerChainConfig{ vaa.ChainIDPolygonSepolia: {NumWorkers: 1, TimestampCacheSupported: true}, vaa.ChainIDMonadDevnet: {NumWorkers: 1, TimestampCacheSupported: true}, vaa.ChainIDHyperEVM: {NumWorkers: 1, TimestampCacheSupported: true}, + vaa.ChainIDMonad: {NumWorkers: 1, TimestampCacheSupported: true}, + vaa.ChainIDSeiEVM: {NumWorkers: 1, TimestampCacheSupported: true}, } // GetPerChainConfig returns the config for the specified chain. If the chain is not configured it returns an empty struct, diff --git a/node/pkg/txverifier/README.md b/node/pkg/txverifier/README.md new file mode 100644 index 0000000000..2982e4e87a --- /dev/null +++ b/node/pkg/txverifier/README.md @@ -0,0 +1,43 @@ +# Transfer Verifier - Package Documentation + +## Package Structure + +``` +├── README.md +├── transfer-verifier-evm-structs.go +├── transfer-verifier-evm-structs_test.go +├── transfer-verifier-evm.go +├── transfer-verifier-evm_test.go +├── transfer-verifier-sui-structs.go +├── transfer-verifier-sui.go +├── transfer-verifier-sui_test.go +├── transfer-verifier-utils.go +└── transfer-verifier-utils_test.go +``` + +The package is organized by runtime environment. Currently there are implementations for the Ethereum and Sui blockchains. +Because the Ethereum implementation is (hopefully) generalizable to other EVM-chains, it is referred to as +`transfer-verifier-evm` rather than `transfer-verifier-ethereum`. + +For each implementation, the code is divided into separate files. The core logic is contained in the main file +and the supporting structs and utility methods are defined in a separate file. The hope here is that this makes the +overall algorithm easier to reason about: a developer new to the program can focus on the main file and high-level +concepts rather and avoid low-level details. + +## Main file -- Core Algorithm + +The main file contains the algorithm for Transfer Verification, handling tasks such as tracking deposits and transfers +into the Token Bridge, cross-referencing these with messages emitted from the core bridge, and emitting errors when +suspicious activity is detected. + +## Structs file -- Parsing and Encapsulation + +The structs file defines the major conceptual building blocks used by the algorithm in the main file. It is also responsible +for lower-level operations such as establishing a subscription or polling mechanisms to a supported chain. This file +also handles parsing and conversions, transforming things like JSON blobs or byte slices into concepts like a +Message Receipt or Deposit. + +## Utilities file + +There is also a utilities file that contains functions used by more than one runtime implementation, such as +performing de/normalization of decimals. diff --git a/node/pkg/txverifier/evm.go b/node/pkg/txverifier/evm.go new file mode 100644 index 0000000000..dcdd91db7f --- /dev/null +++ b/node/pkg/txverifier/evm.go @@ -0,0 +1,652 @@ +package txverifier + +// TODOs +// add comments at the top of this file +// fix up contexts where it makes sense +// fix issue where cross-chain transfers show an invariant violation because of they cannot be found in the wrapped asset map + +import ( + "context" + "errors" + "fmt" + "math/big" + "time" + + "github.com/certusone/wormhole/node/pkg/watchers/evm/connectors/ethabi" + "github.com/ethereum/go-ethereum/common" + geth "github.com/ethereum/go-ethereum/core/types" + "github.com/wormhole-foundation/wormhole/sdk/vaa" + + "go.uber.org/zap" +) + +// // Global variables for caching RPC responses. +// var ( + +// ) + +const ( + // Seconds to wait before trying to reconnect to the core contract event subscription. + RECONNECT_DELAY = 5 * time.Second +) + +// ProcessEvent processes a LogMessagePublished event, and is either called +// from a watcher or from the transfer verifier standalone process. It fetches +// the full transaction receipt associated with the log, and parses all +// events emitted in the transaction, tracking LogMessagePublished events as outbound +// transfers and token deposits into the token bridge as inbound transfers. It then +// verifies that the sum of the inbound transfers is at least as much as the sum of +// the outbound transfers. +// If the return value is true, it implies that the event was processed successfully. +// If the return value is false, it implies that something serious has gone wrong. +func (tv *TransferVerifier[ethClient, Connector]) ProcessEvent( + ctx context.Context, + vLog *ethabi.AbiLogMessagePublished, + // If nil, this code will fetch the receipt using the TransferVerifier's connector. + receipt *geth.Receipt, +) bool { + + // Use this opportunity to prune old transaction information from the cache. + tv.pruneCache() + + tv.logger.Debug("detected LogMessagePublished event", + zap.String("txHash", vLog.Raw.TxHash.String())) + + // Caching: record used/inspected tx hash. + if _, exists := tv.processedTransactions[vLog.Raw.TxHash]; exists { + tv.logger.Debug("skip: transaction hash already processed", + zap.String("txHash", vLog.Raw.TxHash.String())) + return true + } + + // This check also occurs when processing a receipt but skipping here avoids unnecessary + // processing. + if cmp(vLog.Sender, tv.Addresses.TokenBridgeAddr) != 0 { + tv.logger.Debug("skip: sender is not token bridge", + zap.String("txHash", vLog.Raw.TxHash.String()), + zap.String("sender", vLog.Sender.String()), + zap.String("tokenBridge", tv.Addresses.TokenBridgeAddr.String())) + return true + } + + if receipt == nil { + tv.logger.Debug("receipt was not passed as an argument. fetching it using the connector") + // Get the full transaction receipt for this log if it was not provided as an argument. + var txReceiptErr error + receipt, txReceiptErr = tv.evmConnector.TransactionReceipt(ctx, vLog.Raw.TxHash) + if txReceiptErr != nil { + tv.logger.Warn("could not find core bridge receipt", zap.Error(txReceiptErr)) + return true + } + } + + // Caching: record a new lastBlockNumber. + tv.lastBlockNumber = receipt.BlockNumber.Uint64() + tv.processedTransactions[vLog.Raw.TxHash] = receipt + + // Parse raw transaction receipt into high-level struct containing transfer details. + transferReceipt, parseErr := tv.ParseReceipt(receipt) + if parseErr != nil || transferReceipt == nil { + tv.logger.Warn("error when parsing receipt. skipping validation", + zap.String("receipt hash", receipt.TxHash.String()), + zap.Error(parseErr)) + return true + } + + // Add wormhole-specific data to the receipt by making + // RPC calls for data that is not included in the logs, + // such as a token's native address and its decimals. + updateErr := tv.UpdateReceiptDetails(transferReceipt) + if updateErr != nil { + tv.logger.Warn("error when fetching receipt details from the token bridge. can't continue processing", + zap.String("receipt hash", receipt.TxHash.String()), + zap.Error(updateErr)) + return true + } + + // Ensure that the amount coming in is at least as much as the amount requested out. + summary, processErr := tv.ProcessReceipt(transferReceipt) + tv.logger.Debug("finished processing receipt", zap.String("summary", summary.String())) + + if processErr != nil { + // This represents a serious error. Normal, valid transactions should return an + // error here. If this error is returned, it means that the core invariant that + // transfer verifier is monitoring is broken. + tv.logger.Error("error when processing receipt. can't continue processing", + zap.Error(processErr), + zap.String("txHash", vLog.Raw.TxHash.String())) + return false + } + + // Update statistics + if summary.logsProcessed == 0 { + tv.logger.Warn("receipt logs empty for tx", zap.String("txHash", vLog.Raw.TxHash.Hex())) + return true + } + + return true +} + +func (tv *TransferVerifier[ethClient, Connector]) pruneCache() { + // Prune the cache of processed receipts + numPrunedReceipts := int(0) + // Iterate over recorded transaction hashes, and clear receipts older than `pruneDelta` blocks + for hash, receipt := range tv.processedTransactions { + if receipt.BlockNumber.Uint64() < tv.lastBlockNumber-tv.pruneHeightDelta { + numPrunedReceipts++ + delete(tv.processedTransactions, hash) + } + } + + tv.logger.Debug("pruned cached transaction receipts", + zap.Int("numPrunedReceipts", numPrunedReceipts)) +} + +// Do additional processing on the raw data that has been parsed. This +// consists of checking whether assets are wrapped for both ERC20 +// Transfer logs and LogMessagePublished events. If so, unwrap the +// assets and fetch information about the native chain, native address, +// and token decimals. All of this information is required to determine +// whether the amounts deposited into the token bridge match the amount +// that was requested out. This is done separately from parsing step so +// that RPC calls are done independently of parsing code, which +// facilitates testing. +// Updates the receipt parameter directly. +func (tv *TransferVerifier[ethClient, Connector]) UpdateReceiptDetails( + receipt *TransferReceipt, +) (updateErr error) { + + tv.logger.Debug( + "updating details for receipt", + zap.String("receiptRaw", receipt.String()), + ) + + // Populate details for all transfers in this receipt. + tv.logger.Debug("populating native data for ERC20 Transfers") + for _, transfer := range *receipt.Transfers { + // The native address is returned here, but it is ignored. The goal here is only to correct + // the native chain ID so that it can be compared against the destination asset in the + // LogMessagePublished payload. + nativeChainID, _, fetchErr := tv.fetchNativeInfo(transfer.TokenAddress, transfer.TokenChain) + if fetchErr != nil { + // It's somewhat common for transfers to be made across the bridge for assets + // that are not properly registered. In this case, calls to isWrappedAsset() on + // the Token Bridge will return true but the calls to wrappedAsset() will return + // the zero address. In this case it's impossible to determine the decimals and + // therefore there is no way to compare the amount transferred or burned with + // the LogMessagePublished payload. In this case, we can't process this receipt. + + return errors.Join(errors.New("error when fetching native info for ERC20 Transfer. Can't continue to process this receipt"), fetchErr) + } + + // Update ChainID if this is a wrapped asset + if nativeChainID != 0 { + tv.logger.Debug("updating chain ID for Token with its native chain ID", + zap.String("tokenAddr", transfer.TokenChain.String()), + zap.Uint16("new chainID", uint16(nativeChainID)), + zap.String("chain name", nativeChainID.String())) + transfer.TokenChain = nativeChainID + continue + } + + tv.logger.Debug("token is native. no info updated") + } + + // Populate the native asset information and token decimals for assets + // recorded in LogMessagePublished events for this receipt. + tv.logger.Debug("populating native data for LogMessagePublished assets") + for _, message := range *receipt.MessagePublicatons { + newDetails, logFetchErr := tv.fetchLogMessageDetails(message.TransferDetails) + if logFetchErr != nil { + // The unwrapped address and the denormalized amount are necessary for checking + // that the amount matches. + return errors.Join(errors.New("error when populating wormhole details. cannot verify receipt"), logFetchErr) + } + message.TransferDetails = newDetails + } + + tv.logger.Debug( + "new details for receipt", + zap.String("receipt", receipt.String()), + ) + + tv.logger.Debug("finished updating receipt details") + return nil +} + +// fetchNativeInfo queries the token bridge about whether the token address is wrapped, and if so, returns the native chain +// and address where the token was minted. +func (tv *TransferVerifier[ethClient, Connector]) fetchNativeInfo( + tokenAddr common.Address, + tokenChain vaa.ChainID, +) (nativeChain vaa.ChainID, nativeAddr common.Address, err error) { + tv.logger.Debug("checking if ERC20 asset is wrapped") + + wrapped, isWrappedErr := tv.isWrappedAsset(tokenAddr) + if isWrappedErr != nil { + return 0, ZERO_ADDRESS, errors.Join(errors.New("could not check if asset was wrapped"), isWrappedErr) + } + + if !wrapped { + tv.logger.Debug("asset is native (not wrapped)", zap.String("tokenAddr", tokenAddr.String())) + return 0, ZERO_ADDRESS, nil + } + + // Unwrap the asset + unwrapped, unwrapErr := tv.unwrapIfWrapped(tokenAddr.Bytes(), tokenChain) + if unwrapErr != nil { + return 0, ZERO_ADDRESS, errors.Join(errors.New("error when unwrapping asset"), unwrapErr) + } + + // Asset is wrapped but not in wrappedAsset map for the Token Bridge. + if cmp(unwrapped, ZERO_ADDRESS) == 0 { + return 0, ZERO_ADDRESS, errors.New("asset is wrapped but unwrapping gave the zero address. this is an unusual asset or there is a bug in the program") + } + + // Get the native chain ID + nativeChain, chainIdErr := tv.chainId(unwrapped) + if chainIdErr != nil { + return 0, ZERO_ADDRESS, errors.Join(errors.New("error when fetching chain ID"), chainIdErr) + } + + return nativeChain, nativeAddr, nil +} + +// ParseReceipt converts a go-ethereum receipt struct into a TransferReceipt. +// It makes use of the ethConnector to parse information from the logs within +// the receipt. This function is mainly helpful to isolate the parsing code +// from the verification logic, which makes the latter easier to test without +// needing an active RPC connection. + +// This function parses only events with topics needed for Transfer +// Verification. Any other events will be discarded. +// This function is not responsible for checking that the values for the +// various fields are relevant, only that they are well-formed. +func (tv *TransferVerifier[evmClient, connector]) ParseReceipt( + receipt *geth.Receipt, +) (*TransferReceipt, error) { + // Sanity checks. Shouldn't be necessary but no harm + if receipt == nil { + return &TransferReceipt{}, errors.New("receipt parameter is nil") + } + if receipt.Status != 1 { + return &TransferReceipt{}, errors.New("non-success transaction status") + } + if len(receipt.Logs) == 0 { + return &TransferReceipt{}, errors.New("no logs in receipt") + } + + var deposits []*NativeDeposit + var transfers []*ERC20Transfer + var messagePublications []*LogMessagePublished + + // Aggregate all errors without returning early + var receiptErr error + + for _, log := range receipt.Logs { + switch log.Topics[0] { + case common.HexToHash(EVENTHASH_WETH_DEPOSIT): + deposit, depositErr := DepositFromLog(log, tv.chainIds.wormholeChainId) + + if depositErr != nil { + tv.logger.Error("error when parsing Deposit from log", + zap.Error(depositErr), + zap.String("txHash", log.TxHash.String()), + ) + receiptErr = errors.Join(receiptErr, depositErr) + continue + } + + tv.logger.Debug("adding deposit", zap.String("deposit", deposit.String())) + deposits = append(deposits, deposit) + case common.HexToHash(EVENTHASH_ERC20_TRANSFER): + transfer, transferErr := ERC20TransferFromLog(log, tv.chainIds.wormholeChainId) + + if transferErr != nil { + tv.logger.Error("error when parsing ERC20 Transfer from log", + zap.Error(transferErr), + zap.String("txHash", log.TxHash.String()), + ) + receiptErr = errors.Join(receiptErr, transferErr) + continue + } + + tv.logger.Debug("adding transfer", zap.String("transfer", transfer.String())) + transfers = append(transfers, transfer) + case common.HexToHash(EVENTHASH_WORMHOLE_LOG_MESSAGE_PUBLISHED): + if len(log.Data) == 0 { + // tv.logger.Error("receipt data has length 0") + receiptErr = errors.Join(receiptErr, errors.New("receipt data has length 0")) + continue + } + + logMessagePublished, parseLogErr := tv.evmConnector.ParseLogMessagePublished(*log) + if parseLogErr != nil { + tv.logger.Error("failed to parse LogMessagePublished event") + receiptErr = errors.Join(receiptErr, parseLogErr) + continue + } + + // If there is no payload, then there's no point in further processing. + // This should never happen. + if len(logMessagePublished.Payload) == 0 { + emptyErr := errors.New("a LogMessagePayload event from the token bridge was received with a zero-sized payload") + tv.logger.Error( + "issue parsing receipt", + zap.Error(emptyErr), + zap.String("txhash", log.TxHash.String())) + receiptErr = errors.Join(receiptErr, emptyErr) + continue + } + + // This check is required. Payload parsing will fail if performed on a message emitted from another contract or sent + // by a contract other than the token bridge + if log.Address != tv.Addresses.CoreBridgeAddr { + tv.logger.Debug("skip: LogMessagePublished not emitted from the core bridge", + zap.String("emitter", log.Address.String())) + continue + } + + if log.Topics[1] != tv.Addresses.TokenBridgeAddr.Hash() { + tv.logger.Debug("skip: LogMessagePublished with sender not equal to the token bridge", + zap.String("sender", log.Topics[1].String()), + zap.String("tokenBridgeAddr", tv.Addresses.TokenBridgeAddr.Hex()), + ) + continue + } + + // Validation is complete. Now, parse the raw bytes of the payload into a TransferDetails instance. + transferDetails, parsePayloadErr := parseLogMessagePublishedPayload(logMessagePublished.Payload) + if parsePayloadErr != nil { + receiptErr = errors.Join(receiptErr, parsePayloadErr) + continue + } + + // If everything went well, append the message publication + messagePublications = append(messagePublications, &LogMessagePublished{ + EventEmitter: log.Address, + MsgSender: logMessagePublished.Sender, + TransferDetails: transferDetails, + }) + + } + } + + if len(messagePublications) == 0 { + receiptErr = errors.Join(receiptErr, errors.New("parsed receipts but received no LogMessagePublished events")) + } + + if receiptErr != nil { + return &TransferReceipt{}, receiptErr + } + + return &TransferReceipt{ + Deposits: &deposits, + Transfers: &transfers, + MessagePublicatons: &messagePublications}, + nil +} + +// Custom error type used to signal that a core invariant of the token bridge has been violated. +type InvariantError struct { + Msg string +} + +func (i InvariantError) Error() string { + return fmt.Sprintf("invariant violated: %s", i.Msg) +} + +// ProcessReceipt verifies that a receipt for a LogMessagedPublished event does +// not verify a fundamental invariant of Wormhole token transfers: when the +// core bridge reports a transfer has occurred, there must be a corresponding +// transfer in the token bridge. This is determined by iterating through the +// logs of the receipt and ensuring that the sum transferred into the token +// bridge does not exceed the sum emitted by the core bridge. +// If this function returns an error, that means there is some serious trouble. +// An error should be returned if a deposit or transfer in the receipt is missing +// crucial information, or else if the sum of the funds in are less than +// the funds out. +// When modifying this code, be cautious not to return errors unless something +// is really wrong. +func (tv *TransferVerifier[evmClient, connector]) ProcessReceipt( + receipt *TransferReceipt, +) (summary *ReceiptSummary, err error) { + + tv.logger.Debug("beginning to process receipt", + zap.String("receipt", receipt.String()), + ) + + summary = NewReceiptSummary() + + // Sanity checks. + if receipt == nil { + return summary, errors.New("got nil transfer receipt") + } + if len(*receipt.MessagePublicatons) == 0 { + return summary, errors.New("no message publications in receipt") + } + + if len(*receipt.Deposits) == 0 && len(*receipt.Transfers) == 0 { + return summary, errors.New("invalid receipt: no deposits and no transfers") + } + + // Process NativeDeposits + for _, deposit := range *receipt.Deposits { + + validateErr := validate[*NativeDeposit](deposit) + if validateErr != nil { + return summary, validateErr + } + + key, relevant := relevant[*NativeDeposit](deposit, tv.Addresses) + if !relevant { + tv.logger.Debug("skip: irrelevant deposit", + zap.String("emitter", deposit.Emitter().String()), + zap.String("deposit", deposit.String()), + ) + continue + } + if key == "" { + return summary, errors.New("couldn't get key") + } + + upsert(&summary.in, key, deposit.TransferAmount()) + + tv.logger.Debug("a deposit into the token bridge was recorded", + zap.String("tokenAddress", deposit.TokenAddress.String()), + zap.String("amount", deposit.Amount.String())) + } + + // Process ERC20Transfers + for _, transfer := range *receipt.Transfers { + validateErr := validate[*ERC20Transfer](transfer) + if validateErr != nil { + return summary, validateErr + } + + key, relevant := relevant[*ERC20Transfer](transfer, tv.Addresses) + if !relevant { + tv.logger.Debug("skipping irrelevant transfer", + zap.String("emitter", transfer.Emitter().String()), + zap.String("erc20Transfer", transfer.String())) + continue + } + if key == "" { + return summary, errors.New("couldn't get key") + } + + upsert(&summary.in, key, transfer.TransferAmount()) + + tv.logger.Debug("a transfer into the token bridge was recorded", + zap.String("tokenAddress", transfer.TokenAddress.String()), + zap.String("amount", transfer.Amount.String())) + } + + // Process LogMessagePublished events. + for _, message := range *receipt.MessagePublicatons { + td := message.TransferDetails + + validateErr := validate[*LogMessagePublished](message) + if validateErr != nil { + return summary, validateErr + } + + key, relevant := relevant[*LogMessagePublished](message, tv.Addresses) + if !relevant { + tv.logger.Debug("skip: irrelevant LogMessagePublished event") + continue + } + + upsert(&summary.out, key, message.TransferAmount()) + + tv.logger.Debug("successfully parsed a LogMessagePublished event payload", + zap.String("tokenAddress", td.OriginAddress.String()), + zap.String("tokenChain", td.TokenChain.String()), + zap.String("amount", td.Amount.String())) + + summary.logsProcessed++ + } + + err = nil + for key, amountOut := range summary.out { + var localErr error + if amountIn, exists := summary.in[key]; !exists { + tv.logger.Error("transfer-out request for tokens that were never deposited", + zap.String("key", key)) + localErr = &InvariantError{Msg: "transfer-out request for tokens that were never deposited"} + } else { + if amountOut.Cmp(amountIn) == 1 { + tv.logger.Error("requested amount out is larger than amount in") + localErr = &InvariantError{Msg: "requested amount out is larger than amount in"} + } + + // Normally the amounts should be equal. This case indicates + // an unusual transfer or else a bug in the program. + if amountOut.Cmp(amountIn) == -1 { + tv.logger.Info("requested amount in is larger than amount out.", + zap.String("key", key), + zap.String("amountIn", amountIn.String()), + zap.String("amountOut", amountOut.String()), + ) + } + + tv.logger.Debug("bridge request processed", + zap.String("key", key), + zap.String("amountOut", amountOut.String()), + zap.String("amountIn", amountIn.String())) + } + + if err != nil { + err = errors.Join(err, localErr) + } else { + err = localErr + } + } + + return +} + +// parseLogMessagePublishedPayload parses the details of a transfer from a +// LogMessagePublished event's Payload field. +func parseLogMessagePublishedPayload( + // Corresponds to LogMessagePublished.Payload as returned by the ABI parsing operation in the ethConnector. + data []byte, +) (*TransferDetails, error) { + // This method is already called by DecodeTransferPayloadHdr but the + // error message is unclear. Doing a manual check here lets us return a + // more helpful error message. + if !vaa.IsTransfer(data) { + return nil, errors.New("payload is not a transfer type. no need to process") + } + + // Note: vaa.DecodeTransferPayloadHdr performs validation on data, e.g. length checks. + hdr, err := vaa.DecodeTransferPayloadHdr(data) + if err != nil { + return nil, err + } + return &TransferDetails{ + PayloadType: VAAPayloadType(hdr.Type), + AmountRaw: hdr.Amount, + OriginAddressRaw: hdr.OriginAddress.Bytes(), + TokenChain: vaa.ChainID(hdr.OriginChain), + TargetAddress: hdr.TargetAddress, + // these fields are populated by RPC calls later + Amount: nil, + OriginAddress: common.Address{}, + }, nil +} + +// fetchLogMessageDetails makes requests to the token bridge and token contract to get detailed, wormhole-specific information about +// the transfer details parsed from a LogMessagePublished event. +func (tv *TransferVerifier[ethClient, connector]) fetchLogMessageDetails(details *TransferDetails) (newDetails *TransferDetails, decimalErr error) { + // This function adds information to a TransferDetails struct, filling out its uninitialized fields. + // It populates the following fields: + // - Amount: populate the Amount field by denormalizing details.AmountRaw. + // - OriginAddress: use the wormhole ChainID and OriginAddressRaw to determine whether the token is wrapped. + + // If the token was minted on the chain monitored by this program, set its OriginAddress equal to OriginAddressRaw. + var originAddress common.Address + if details.TokenChain == tv.chainIds.wormholeChainId { + // The token was minted on this chain. + originAddress = common.BytesToAddress(details.OriginAddressRaw) + tv.logger.Debug("token is native. no need to unwrap", + zap.String("originAddressRaw", fmt.Sprintf("%x", details.OriginAddressRaw)), + ) + } else { + // The token was minted on a foreign chain. Unwrap it. + tv.logger.Debug("unwrapping", + zap.String("originAddressRaw", fmt.Sprintf("%x", details.OriginAddressRaw)), + ) + // If the token was minted on another chain, try to unwrap it. + unwrappedAddress, unwrapErr := tv.unwrapIfWrapped(details.OriginAddressRaw, details.TokenChain) + if unwrapErr != nil { + return newDetails, unwrapErr + } + + if cmp(unwrappedAddress, ZERO_ADDRESS) == 0 { + // If the unwrap function returns the zero address, that means + // it has no knowledge of this token. In this case set the + // OriginAddress to OriginAddressRaw rather than to the zero + // address. The program will still be able to know that this is + // a non-native address by examining the chain ID. + // + // This case can occur if a token is transferred when the wrapped asset hasn't been set-up yet. + // https://github.com/wormhole-foundation/wormhole/blob/main/whitepapers/0003_token_bridge.md#setup-of-wrapped-assets + tv.logger.Warn("unwrap call for foreign asset returned the zero address. Either token has not been registered or there is a bug in the program. .", + zap.String("originAddressRaw", details.OriginAddress.String()), + zap.String("tokenChain", details.TokenChain.String()), + ) + return newDetails, errors.New("unwrap call for foreign asset returned the zero address. Either token has not been registered or there is a bug in the program") + } else { + originAddress = unwrappedAddress + } + } + + // Fetch the token's decimals and update TransferDetails with the denormalized amount. + // This must be done on the unwrapped address. + decimals, decimalErr := tv.getDecimals(originAddress) + if decimalErr != nil { + return newDetails, decimalErr + } + + denormalized := denormalize(details.AmountRaw, decimals) + + newDetails = details + newDetails.OriginAddress = originAddress + newDetails.Amount = denormalized + return newDetails, nil +} + +// upsert inserts a new key and value into a map or update the value if the key already exists. +func upsert( + dict *map[string]*big.Int, + key string, + amount *big.Int, +) { + d := *dict + if _, exists := d[key]; !exists { + d[key] = new(big.Int).Set(amount) + } else { + d[key] = new(big.Int).Add(d[key], amount) + } +} diff --git a/node/pkg/txverifier/evm_test.go b/node/pkg/txverifier/evm_test.go new file mode 100644 index 0000000000..e03c59d52c --- /dev/null +++ b/node/pkg/txverifier/evm_test.go @@ -0,0 +1,736 @@ +package txverifier + +// TODO: +// - more robust mocking of RPC return values so that we can test multiple cases +// - add tests checking amount values from ProcessReceipt + +import ( + "context" + "math/big" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/wormhole-foundation/wormhole/sdk/vaa" + + ethereum "github.com/ethereum/go-ethereum" + + "github.com/certusone/wormhole/node/pkg/watchers/evm/connectors/ethabi" + ipfslog "github.com/ipfs/go-log/v2" +) + +// Important addresses for testing. Arbitrary, but Ethereum mainnet values used here +var ( + coreBridgeAddr = common.HexToAddress("0x98f3c9e6E3fAce36bAAd05FE09d375Ef1464288B") + tokenBridgeAddr = common.HexToAddress("0x3ee18B2214AFF97000D974cf647E7C347E8fa585") + nativeAddr = common.HexToAddress("0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2") // weth + usdcAddr = common.HexToAddress("0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48") + eoaAddrGeth = common.HexToAddress("0xbeefcafe") + eoaAddrVAA, _ = vaa.BytesToAddress([]byte{0xbe, 0xef, 0xca, 0xfe}) +) + +type mockConnections struct { + transferVerifier *TransferVerifier[*mockClient, *mockConnector] + ctx *context.Context + ctxCancel context.CancelFunc +} + +// Stub struct, only exist to implement the interfaces +type mockClient struct{} + +// TODO add a helper method to actually populate the results of the mocked method +// TODO this should maybe be mocked differently. CallContract is used for both 'get decimals' and 'unwrap'. +// Depending on how much mocking we want to do, this might need edits. On the other hand, we don't really need to +// test geth's functions and this functionality is better handled by integration testing anyway +func (m *mockClient) CallContract(ctx context.Context, msg ethereum.CallMsg, blockNumber *big.Int) ([]byte, error) { + // this is used by the calling code only to get decimal values + // always return 8 + return common.LeftPadBytes([]byte{0x08}, 32), nil +} + +type mockConnector struct{} + +// TODO add a helper method to actually populate the results of the mocked method +// TODO add different results here so we can test different values +func (c *mockConnector) ParseLogMessagePublished(log types.Log) (*ethabi.AbiLogMessagePublished, error) { + // add mock data + return ðabi.AbiLogMessagePublished{ + Sender: tokenBridgeAddr, + Sequence: 0, + Nonce: 0, + Payload: transferTokensPayload(big.NewInt(1)), + Raw: log, + }, nil +} + +func (c *mockConnector) TransactionReceipt(ctx context.Context, txHash common.Hash) (*types.Receipt, error) { + return nil, nil +} + +// Create the connections and loggers expected by the functions we are testing +func setup() *mockConnections { + logger := ipfslog.Logger("wormhole-transfer-verifier-tests").Desugar() + ipfslog.SetAllLoggers(ipfslog.LevelDebug) + transferVerifier := &TransferVerifier[*mockClient, *mockConnector]{ + Addresses: &TVAddresses{ + CoreBridgeAddr: coreBridgeAddr, + TokenBridgeAddr: tokenBridgeAddr, + WrappedNativeAddr: nativeAddr, + }, + chainIds: &chainIds{evmChainId: 1, wormholeChainId: vaa.ChainIDEthereum}, + evmConnector: &mockConnector{}, + client: &mockClient{}, + logger: *logger, + } + ctx, ctxCancel := context.WithCancel(context.Background()) + + return &mockConnections{ + transferVerifier, + &ctx, + ctxCancel, + } +} + +// Define some transfer logs to make it easier to write tests for parsing receipts. +// Typical receipt logs that can be included in various receipt test cases +var ( + // A valid transfer log for an ERC20 transfer event. + transferLog = &types.Log{ + Address: usdcAddr, + Topics: []common.Hash{ + // Transfer(address,address,uint256) + common.HexToHash(EVENTHASH_ERC20_TRANSFER), + // from + eoaAddrGeth.Hash(), + // to + tokenBridgeAddr.Hash(), + }, + // amount + Data: common.LeftPadBytes([]byte{0x01}, 32), + } + + // A valid transfer log for a log message published event. + validLogMessagedPublishedLog = &types.Log{ + Address: coreBridgeAddr, + Topics: []common.Hash{ + // LogMessagePublished(address indexed sender, uint64 sequence, uint32 nonce, bytes payload, uint8 consistencyLevel); + common.HexToHash(EVENTHASH_WORMHOLE_LOG_MESSAGE_PUBLISHED), + // sender + tokenBridgeAddr.Hash(), + }, + Data: receiptData(big.NewInt(255)), + } +) + +var ( + validTransferReceipt = &types.Receipt{ + Status: types.ReceiptStatusSuccessful, + Logs: []*types.Log{ + transferLog, + validLogMessagedPublishedLog, + }, + } + // Invalid: no erc20 transfer, so amount out > amount in + // invalidTransferReceipt = &types.Receipt{ + // Status: types.ReceiptStatusSuccessful, + // Logs: []*types.Log{ + // logMessagedPublishedLog, + // }, + // } + // TODO: Invalid: erc20 transfer amount is less than payload amount, so amount out > amount in + // invalidTransferReceipt = &types.Receipt{ + // Status: types.ReceiptStatusSuccessful, + // Logs: []*types.Log{logMessagedPublishedLog}, + // } +) + +func TestParseReceiptHappyPath(t *testing.T) { + mocks := setup() + defer mocks.ctxCancel() + + // t.Parallel() // marks TLog as capable of running in parallel with other tests + tests := map[string]struct { + receipt *types.Receipt + expected *TransferReceipt + }{ + "valid transfer receipt, single LogMessagePublished": { + validTransferReceipt, + &TransferReceipt{ + Deposits: &[]*NativeDeposit{}, + Transfers: &[]*ERC20Transfer{ + { + From: eoaAddrGeth, + To: tokenBridgeAddr, + TokenAddress: usdcAddr, + TokenChain: vaa.ChainIDEthereum, + Amount: big.NewInt(1), + }, + }, + MessagePublicatons: &[]*LogMessagePublished{ + { + EventEmitter: coreBridgeAddr, + MsgSender: tokenBridgeAddr, + TransferDetails: &TransferDetails{ + PayloadType: TransferTokens, + OriginAddressRaw: common.LeftPadBytes(usdcAddr.Bytes(), EVM_WORD_LENGTH), + TokenChain: 2, // Wormhole ethereum chain ID + AmountRaw: big.NewInt(1), + TargetAddress: eoaAddrVAA, + // Amount and OriginAddress are not populated by ParseReceipt + // Amount: big.NewInt(1), + // OriginAddress: erc20Addr, + }, + }, + }, + }, + }, + } + for name, test := range tests { + t.Run(name, func(t *testing.T) { + + transferReceipt, err := mocks.transferVerifier.ParseReceipt(test.receipt) + require.NoError(t, err) + + // Note: the data for this test uses only a single transfer. However, if multiple transfers + // are used, iteration over these slices will be non-deterministic which might result in a flaky + // test. + expectedTransfers := *test.expected.Transfers + assert.Equal(t, len(expectedTransfers), len(*transferReceipt.Transfers)) + for _, ret := range *transferReceipt.Transfers { + assert.Equal(t, expectedTransfers[0].To, ret.To) + assert.Equal(t, expectedTransfers[0].From, ret.From) + assert.Equal(t, expectedTransfers[0].TokenAddress, ret.TokenAddress) + assert.Zero(t, ret.Amount.Cmp(expectedTransfers[0].Amount)) + } + + expectedMessages := *test.expected.MessagePublicatons + assert.Equal(t, len(expectedMessages), len(*transferReceipt.MessagePublicatons)) + for _, ret := range *transferReceipt.MessagePublicatons { + // TODO: switch argument order to (expected, actual) + assert.Equal(t, ret.MsgSender, expectedMessages[0].MsgSender) + assert.Equal(t, ret.EventEmitter, expectedMessages[0].EventEmitter) + assert.Equal(t, ret.TransferDetails, expectedMessages[0].TransferDetails) + + t.Logf("Expected AmountRaw: %s", expectedMessages[0].TransferDetails.AmountRaw.String()) + t.Logf("Actual AmountRaw: %s", ret.TransferDetails.AmountRaw.String()) + assert.Zero(t, expectedMessages[0].TransferDetails.AmountRaw.Cmp(ret.TransferDetails.AmountRaw)) + + // Amount and OriginAddress are not populated by ParseReceipt + assert.Equal(t, common.BytesToAddress([]byte{0x00}), ret.TransferDetails.OriginAddress) + assert.Nil(t, ret.TransferDetails.Amount) + } + + }) + } +} + +func TestParseReceiptErrors(t *testing.T) { + mocks := setup() + defer mocks.ctxCancel() + + // Create a log containing an invalid deposit log + badDepositLog := *transferLog + badDepositLog.Topics = []common.Hash{ + common.HexToHash(EVENTHASH_WETH_DEPOSIT), + // Omit essential topics + } + + // Create a log containing an invalid transfer log + badTransferLog := *transferLog + badTransferLog.Topics = []common.Hash{ + common.HexToHash(EVENTHASH_ERC20_TRANSFER), + // Omit essential topics + } + + // Create a log containing a LogMessagePublished event without any payload + emptyPayloadLogMessagePublishedLog := *validLogMessagedPublishedLog + emptyPayloadLogMessagePublishedLog.Data = []byte{} + + // TODO: Create a receipt with the wrong payload type (not a token transfer). + // wrongPayloadTypeLogMessagePublishedLog := types.Log{ + // Address: coreBridgeAddr, + // Topics: []common.Hash{ + // // LogMessagePublished(address indexed sender, uint64 sequence, uint32 nonce, bytes payload, uint8 consistencyLevel); + // common.HexToHash(EVENTHASH_WORMHOLE_LOG_MESSAGE_PUBLISHED), + // // sender + // tokenBridgeAddr.Hash(), + // }, + // Data: receiptData(big.NewInt(1).SetBytes([]byte{0xaa})), + // } + // // The LogMessagePublished payload type occurs in the 6th EVM word slot, and is left-padded with zeroes. + // // Note that the value is 0-indexed + // payloadTypeOffset := EVM_WORD_LENGTH * 5 + // wrongPayloadTypeLogMessagePublishedLog.Data[payloadTypeOffset] = 0x02 + + tests := map[string]struct { + receipt *types.Receipt + }{ + "wrong receipt status": { + receipt: &types.Receipt{ + Status: types.ReceiptStatusFailed, + Logs: []*types.Log{ + validLogMessagedPublishedLog, + }, + }, + }, + "no logs": { + receipt: &types.Receipt{ + Status: types.ReceiptStatusSuccessful, + Logs: []*types.Log{}, + }, + }, + "invalid deposit log in receipt": { + receipt: &types.Receipt{ + Status: types.ReceiptStatusSuccessful, + Logs: []*types.Log{ + &badDepositLog, + }, + }, + }, + "invalid transfer log in receipt": { + receipt: &types.Receipt{ + Status: types.ReceiptStatusSuccessful, + Logs: []*types.Log{ + &badTransferLog, + }, + }, + }, + "LogMessagePublished with empty payload": { + receipt: &types.Receipt{ + Status: types.ReceiptStatusSuccessful, + Logs: []*types.Log{ + &emptyPayloadLogMessagePublishedLog, + }, + }, + }, + // TODO: Need to create a different mock for ParseLogMessagePublished in order to test this + // "LogMessagePublished with wrong payload type": { + // receipt: &types.Receipt{ + // Status: types.ReceiptStatusSuccessful, + // Logs: []*types.Log{ + // &wrongPayloadTypeLogMessagePublishedLog, + // }, + // }, + // }, + } + for name, test := range tests { + t.Run(name, func(t *testing.T) { + + receipt, err := mocks.transferVerifier.ParseReceipt(test.receipt) + require.Error(t, err) + assert.Equal(t, TransferReceipt{}, *receipt) + }) + } +} + +func TestParseERC20TransferEvent(t *testing.T) { + type parsedValues struct { + from common.Address + to common.Address + amount *big.Int + } + erc20TransferHash := common.HexToHash(EVENTHASH_ERC20_TRANSFER) + t.Parallel() // marks TLog as capable of running in parallel with other tests + tests := map[string]struct { + topics []common.Hash + data []byte + expected *parsedValues + }{ + "well-formed": { + topics: []common.Hash{ + erc20TransferHash, + eoaAddrGeth.Hash(), + tokenBridgeAddr.Hash(), + }, + data: common.LeftPadBytes([]byte{0x01}, 32), + expected: &parsedValues{ + from: eoaAddrGeth, + to: tokenBridgeAddr, + amount: new(big.Int).SetBytes([]byte{0x01}), + }, + }, + "data too short": { + topics: []common.Hash{ + erc20TransferHash, + eoaAddrGeth.Hash(), + tokenBridgeAddr.Hash(), + }, + // should be 32 bytes exactly + data: []byte{0x01}, + expected: &parsedValues{}, // everything nil for its type + }, + "wrong number of topics": { + // only 1 topic: should be 3 + topics: []common.Hash{ + erc20TransferHash, + }, + data: common.LeftPadBytes([]byte{0x01}, 32), + expected: &parsedValues{}, // everything nil for its type + }, + } + + for name, test := range tests { + t.Run(name, func(t *testing.T) { + t.Parallel() // marks each test case as capable of running in parallel with each other + + from, to, amount := parseERC20TransferEvent(test.topics, test.data) + assert.Equal(t, test.expected.from, from) + assert.Equal(t, test.expected.to, to) + assert.Zero(t, amount.Cmp(test.expected.amount)) + }) + } +} + +func TestParseWNativeDepositEvent(t *testing.T) { + { + type parsedValues struct { + destination common.Address + amount *big.Int + } + t.Parallel() // marks TLog as capable of running in parallel with other tests + + wethDepositHash := common.HexToHash(EVENTHASH_WETH_DEPOSIT) + tests := map[string]struct { + topics []common.Hash + data []byte + expected *parsedValues + }{ + "well-formed": { + topics: []common.Hash{ + wethDepositHash, + tokenBridgeAddr.Hash(), + }, + data: common.LeftPadBytes([]byte{0x01}, 32), + expected: &parsedValues{ + destination: tokenBridgeAddr, + amount: new(big.Int).SetBytes([]byte{0x01}), + }, + }, + "data too short": { + topics: []common.Hash{ + wethDepositHash, + tokenBridgeAddr.Hash(), + }, + // should be 32 bytes exactly + data: []byte{0x01}, + expected: &parsedValues{}, // everything nil for its type + }, + "wrong number of topics": { + // only 1 topic: should be 2 + topics: []common.Hash{ + wethDepositHash, + }, + data: common.LeftPadBytes([]byte{0x01}, 32), + expected: &parsedValues{}, // everything nil for its type + }, + } + + for name, test := range tests { + t.Run(name, func(t *testing.T) { + t.Parallel() // marks each test case as capable of running in parallel with each other + + destination, amount := parseWNativeDepositEvent(test.topics, test.data) + assert.Equal(t, test.expected.destination, destination) + assert.Zero(t, amount.Cmp(test.expected.amount)) + }) + } + } + +} + +func TestProcessReceipt(t *testing.T) { + mocks := setup() + + tests := map[string]struct { + transferReceipt *TransferReceipt + // number of receipts successfully processed + expected int + shouldError bool + }{ + // TODO test cases: + // - multiple transfers adding up to the right amount + // - multiple depoists adding up to the right amount + // - multiple LogMessagePublished events + "valid transfer: amounts match, deposit": { + transferReceipt: &TransferReceipt{ + Deposits: &[]*NativeDeposit{ + { + TokenAddress: nativeAddr, + TokenChain: vaa.ChainIDEthereum, + Receiver: tokenBridgeAddr, + Amount: big.NewInt(123), + }, + }, + Transfers: &[]*ERC20Transfer{}, + MessagePublicatons: &[]*LogMessagePublished{ + { + EventEmitter: coreBridgeAddr, + MsgSender: tokenBridgeAddr, + TransferDetails: &TransferDetails{ + PayloadType: TransferTokens, + OriginAddressRaw: nativeAddr.Bytes(), + OriginAddress: nativeAddr, + TargetAddress: eoaAddrVAA, + TokenChain: 2, + AmountRaw: big.NewInt(123), + Amount: big.NewInt(123), + }, + }, + }, + }, + expected: 1, + shouldError: false, + }, + "valid transfer: amounts match, transfer": { + transferReceipt: &TransferReceipt{ + Deposits: &[]*NativeDeposit{}, + Transfers: &[]*ERC20Transfer{ + { + TokenAddress: usdcAddr, + TokenChain: vaa.ChainIDEthereum, + From: eoaAddrGeth, + To: tokenBridgeAddr, + Amount: big.NewInt(456), + }, + }, + MessagePublicatons: &[]*LogMessagePublished{ + { + EventEmitter: coreBridgeAddr, + MsgSender: tokenBridgeAddr, + TransferDetails: &TransferDetails{ + PayloadType: TransferTokens, + OriginAddressRaw: usdcAddr.Bytes(), + OriginAddress: usdcAddr, + TokenChain: 2, + TargetAddress: eoaAddrVAA, + AmountRaw: big.NewInt(456), + Amount: big.NewInt(456), + }, + }, + }, + }, + expected: 1, + shouldError: false, + }, + "valid transfer: amount in is greater than amount out, deposit": { + transferReceipt: &TransferReceipt{ + Deposits: &[]*NativeDeposit{ + { + TokenAddress: nativeAddr, + TokenChain: vaa.ChainIDEthereum, + Receiver: tokenBridgeAddr, + Amount: big.NewInt(999), + }, + }, + Transfers: &[]*ERC20Transfer{}, + MessagePublicatons: &[]*LogMessagePublished{ + { + EventEmitter: coreBridgeAddr, + MsgSender: tokenBridgeAddr, + TransferDetails: &TransferDetails{ + PayloadType: TransferTokens, + OriginAddressRaw: nativeAddr.Bytes(), + TokenChain: 2, + OriginAddress: nativeAddr, + TargetAddress: eoaAddrVAA, + AmountRaw: big.NewInt(321), + Amount: big.NewInt(321), + }, + }, + }, + }, + expected: 1, + shouldError: false, + }, + "valid transfer: amount in is greater than amount out, transfer": { + transferReceipt: &TransferReceipt{ + Deposits: &[]*NativeDeposit{}, + Transfers: &[]*ERC20Transfer{ + { + TokenAddress: usdcAddr, + TokenChain: vaa.ChainIDEthereum, + From: eoaAddrGeth, + To: tokenBridgeAddr, + Amount: big.NewInt(999), + }, + }, + MessagePublicatons: &[]*LogMessagePublished{ + { + EventEmitter: coreBridgeAddr, + MsgSender: tokenBridgeAddr, + TransferDetails: &TransferDetails{ + PayloadType: TransferTokens, + OriginAddressRaw: usdcAddr.Bytes(), + OriginAddress: usdcAddr, + TargetAddress: eoaAddrVAA, + TokenChain: 2, + AmountRaw: big.NewInt(321), + Amount: big.NewInt(321), + }, + }, + }, + }, + expected: 1, + shouldError: false, + }, + "invalid transfer: amount in too low, deposit": { + transferReceipt: &TransferReceipt{ + Deposits: &[]*NativeDeposit{ + { + TokenAddress: nativeAddr, + TokenChain: NATIVE_CHAIN_ID, + Receiver: tokenBridgeAddr, + Amount: big.NewInt(10), + }, + }, + Transfers: &[]*ERC20Transfer{}, + MessagePublicatons: &[]*LogMessagePublished{ + { + EventEmitter: coreBridgeAddr, + MsgSender: tokenBridgeAddr, + TransferDetails: &TransferDetails{ + PayloadType: TransferTokens, + OriginAddressRaw: nativeAddr.Bytes(), + OriginAddress: nativeAddr, + TargetAddress: eoaAddrVAA, + TokenChain: vaa.ChainIDEthereum, + AmountRaw: big.NewInt(11), + Amount: big.NewInt(11), + }, + }, + }, + }, + expected: 1, + shouldError: true, + }, + "invalid transfer: amount in too low, transfer": { + transferReceipt: &TransferReceipt{ + Deposits: &[]*NativeDeposit{}, + Transfers: &[]*ERC20Transfer{ + { + TokenAddress: usdcAddr, + TokenChain: NATIVE_CHAIN_ID, + From: eoaAddrGeth, + To: tokenBridgeAddr, + Amount: big.NewInt(1), + }, + }, + MessagePublicatons: &[]*LogMessagePublished{ + { + EventEmitter: coreBridgeAddr, + MsgSender: tokenBridgeAddr, + TransferDetails: &TransferDetails{ + PayloadType: TransferTokens, + OriginAddressRaw: nativeAddr.Bytes(), + OriginAddress: nativeAddr, + TargetAddress: eoaAddrVAA, + TokenChain: 2, + AmountRaw: big.NewInt(2), + Amount: big.NewInt(2), + }, + }, + }, + }, + expected: 1, + shouldError: true, + }, + "invalid transfer: transfer out after transferring a different token": { + transferReceipt: &TransferReceipt{ + Deposits: &[]*NativeDeposit{}, + Transfers: &[]*ERC20Transfer{ + { + TokenAddress: usdcAddr, + TokenChain: vaa.ChainIDEthereum, + From: eoaAddrGeth, + To: tokenBridgeAddr, + Amount: big.NewInt(2), + }, + }, + MessagePublicatons: &[]*LogMessagePublished{ + { + EventEmitter: coreBridgeAddr, + MsgSender: tokenBridgeAddr, + TransferDetails: &TransferDetails{ + PayloadType: TransferTokens, + OriginAddressRaw: nativeAddr.Bytes(), + OriginAddress: nativeAddr, + TargetAddress: eoaAddrVAA, + TokenChain: 2, + AmountRaw: big.NewInt(2), + Amount: big.NewInt(2), + }, + }, + }, + }, + expected: 1, + shouldError: true, + }, + } + + for name, test := range tests { + t.Run(name, func(t *testing.T) { + + summary, err := mocks.transferVerifier.ProcessReceipt(test.transferReceipt) + + assert.Equal(t, test.expected, summary.logsProcessed, "number of processed receipts did not match") + + if err != nil { + assert.True(t, test.shouldError, "test should have returned an error") + _, ok := err.(*InvariantError) + assert.True(t, ok, "wrong error type. expected InvariantError, got: `%w`", err) + } else { + assert.False(t, test.shouldError, "test should not have returned an error but got: `%w`", err) + } + }) + } +} + +func receiptData(payloadAmount *big.Int) (data []byte) { + // non-payload part of the receipt and ABI metadata fields + seq := common.LeftPadBytes([]byte{0x11}, 32) + nonce := common.LeftPadBytes([]byte{0x22}, 32) + offset := common.LeftPadBytes([]byte{0x80}, 32) + consistencyLevel := common.LeftPadBytes([]byte{0x01}, 32) + payloadLength := common.LeftPadBytes([]byte{0x85}, 32) // 133 for transferTokens + + data = append(data, seq...) + data = append(data, nonce...) + data = append(data, offset...) + data = append(data, consistencyLevel...) + data = append(data, payloadLength...) + data = append(data, transferTokensPayload(payloadAmount)...) + + return data +} + +// Generate the Payload portion of a LogMessagePublished receipt for use in unit tests. +func transferTokensPayload(payloadAmount *big.Int) (data []byte) { + // tokenTransfer() payload format: + // transfer.payloadID, uint8, size: 1 + // amount, uint256, size: 32 + // tokenAddress, bytes32: size 32 + // tokenChain, uint16, size 2 + // to, bytes32: size 32 + // toChain, uint16, size: 2 + // fee, uint256 size: size 32 + // 1 + 32 + 32 + 2 + 32 + 2 + 32 = 133 + // See also: https://docs.soliditylang.org/en/latest/abi-spec.html + + payloadType := []byte{0x01} // transferTokens, not padded + amount := common.LeftPadBytes(payloadAmount.Bytes(), 32) + tokenAddress := common.LeftPadBytes(usdcAddr.Bytes(), 32) + tokenChain := common.LeftPadBytes([]byte{0x02}, 2) // Eth wormhole chain ID, uint16 + to := common.LeftPadBytes([]byte{0xbe, 0xef, 0xca, 0xfe}, 32) + toChain := common.LeftPadBytes([]byte{0x01}, 2) // Eth wormhole chain ID, uint16 + fee := common.LeftPadBytes([]byte{0x00}, 32) // Solana wormhole chain ID, uint16 + data = append(data, payloadType...) + data = append(data, amount...) + data = append(data, tokenAddress...) + data = append(data, tokenChain...) + data = append(data, to...) + data = append(data, toChain...) + data = append(data, fee...) + return data +} diff --git a/node/pkg/txverifier/evmtypes.go b/node/pkg/txverifier/evmtypes.go new file mode 100644 index 0000000000..90df97969f --- /dev/null +++ b/node/pkg/txverifier/evmtypes.go @@ -0,0 +1,1053 @@ +package txverifier + +// TODO +// Change constant naming convention to PascalCase (maybe goimports can do this automatically) +// Can the actual ethCalls be factored into their own function? + +import ( + "bytes" + "context" + "encoding/binary" + "encoding/hex" + "errors" + "fmt" + "strconv" + + "math/big" + "time" + + connectors "github.com/certusone/wormhole/node/pkg/watchers/evm/connectors" + "github.com/certusone/wormhole/node/pkg/watchers/evm/connectors/ethabi" + "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + ethClient "github.com/ethereum/go-ethereum/ethclient" + "github.com/ethereum/go-ethereum/event" + "github.com/wormhole-foundation/wormhole/sdk/vaa" + "go.uber.org/zap" +) + +// Event Signatures +const ( + // LogMessagePublished(address indexed sender, uint64 sequence, uint32 nonce, bytes payload, uint8 consistencyLevel); + EVENTHASH_WORMHOLE_LOG_MESSAGE_PUBLISHED = "0x6eb224fb001ed210e379b335e35efe88672a8ce935d981a6896b27ffdf52a3b2" + // Transfer(address,address,uint256) + EVENTHASH_ERC20_TRANSFER = "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef" + // Deposit(address,uint256) + EVENTHASH_WETH_DEPOSIT = "0xe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c" +) + +// Function signatures +var ( + // wrappedAsset(uint16 tokenChainId, bytes32 tokenAddress) => 0x1ff1e286 + TOKEN_BRIDGE_WRAPPED_ASSET_SIGNATURE = []byte("\x1f\xf1\xe2\x86") + // isWrappedAsset(address token) => 0x1a2be4da + TOKEN_BRIDGE_IS_WRAPPED_ASSET_SIGNATURE = []byte("\x1a\x2b\xe4\xda") + // decimals() => 0x313ce567 + ERC20_DECIMALS_SIGNATURE = []byte("\x31\x3c\xe5\x67") + // chainId() => 0x9a8a0592 + WRAPPED_ERC20_CHAIN_ID_SIGNATURE = []byte("\x9a\x8a\x05\x92") +) + +// Fixed addresses +var ( + // https://etherscan.io/token/0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2 + ZERO_ADDRESS = common.BytesToAddress([]byte{0x00}) + ZERO_ADDRESS_VAA = VAAAddrFrom(ZERO_ADDRESS) +) + +// EVM chain constants +const ( + // EVM uses 32 bytes for words. Note that vaa.Address is an alias for a slice of 32 bytes + EVM_WORD_LENGTH = 32 + // The expected total number of indexed topics for an ERC20 Transfer event + TOPICS_COUNT_TRANSFER = 3 + // The expected total number of indexed topics for a WETH Deposit event + TOPICS_COUNT_DEPOSIT = 2 +) + +const ( + RPC_TIMEOUT = 10 * time.Second +) + +// Important addresses for Transfer Verification. +type TVAddresses struct { + CoreBridgeAddr common.Address + // Address of the Wormhole token bridge contract for this chain + TokenBridgeAddr common.Address + // Wrapped version of the native asset, e.g. WETH for Ethereum + WrappedNativeAddr common.Address +} + +// Stores the EVM chain ID and corresponding Wormhole chain ID for the current chain being monitored by the connector. +type chainIds struct { + evmChainId uint64 + wormholeChainId vaa.ChainID +} + +// TransferVerifier contains configuration values for verifying transfers. +type TransferVerifier[E evmClient, C connector] struct { + Addresses *TVAddresses + // The chainId being monitored as reported by the client connector. + chainIds *chainIds + // Wormhole connector for wrapping contract-specific interactions + logger zap.Logger + // Corresponds to the connector interface for EVM chains + evmConnector C + // Corresponds to an ethClient from go-ethereum + client E + // Mapping to track the transactions that have been processed. Indexed by a log's txHash. + processedTransactions map[common.Hash]*types.Receipt + // The latest transaction block number, used to determine the size of historic receipts to keep in memory. + lastBlockNumber uint64 + // The block height difference between the latest block and the oldest block to keep in memory. + pruneHeightDelta uint64 + + // Holds previously-recorded decimals (uint8) for token addresses + // (common.Address) that have been observed. + decimalsCache map[common.Address]uint8 + + // Records whether an asset is wrapped but does not store the native data + isWrappedCache map[string]bool + + // Maps the 32-byte token addresses received via LogMessagePublished + // events to their unwrapped 20-byte addresses. This mapping is also + // used for non-wrapped token addresses. + wrappedCache map[string]common.Address + + // Native chain cache for wrapped assets. + nativeChainCache map[string]vaa.ChainID +} + +func NewTransferVerifier(connector connectors.Connector, tvAddrs *TVAddresses, pruneHeightDelta uint64, logger *zap.Logger) (*TransferVerifier[*ethClient.Client, connectors.Connector], error) { + // Retrieve the chainId from the connector. + chainIdFromClient, err := connector.Client().ChainID(context.Background()) + if err != nil { + return nil, fmt.Errorf("failed to get chain ID: %w", err) + } + + // Fetch EVM chain ID from the connector and attempt to convert it to a Wormhole chain ID. + evmChainId, parseErr := strconv.ParseUint(chainIdFromClient.String(), 10, 16) + if parseErr != nil { + return nil, fmt.Errorf("Failed to parse chainId from string returned by connector client: %w", parseErr) + } + + wormholeChainId, unregisteredErr := TryWormholeChainIdFromNative(evmChainId) + if unregisteredErr != nil { + return nil, fmt.Errorf("Could not get Wormhole chain ID from EVM chain ID: %w", unregisteredErr) + } + + return &TransferVerifier[*ethClient.Client, connectors.Connector]{ + Addresses: tvAddrs, + chainIds: &chainIds{ + evmChainId: evmChainId, + wormholeChainId: wormholeChainId, + }, + logger: *logger, + evmConnector: connector, + client: connector.Client(), + processedTransactions: make(map[common.Hash]*types.Receipt), + lastBlockNumber: 0, + pruneHeightDelta: pruneHeightDelta, + decimalsCache: make(map[common.Address]uint8), + isWrappedCache: make(map[string]bool), + wrappedCache: make(map[string]common.Address), + nativeChainCache: make(map[string]vaa.ChainID), + }, nil +} + +type connector interface { + ParseLogMessagePublished(log types.Log) (*ethabi.AbiLogMessagePublished, error) + TransactionReceipt(ctx context.Context, txHash common.Hash) (*types.Receipt, error) +} + +type evmClient interface { + // getDecimals() + CallContract(ctx context.Context, msg ethereum.CallMsg, blockNumber *big.Int) ([]byte, error) +} + +type Subscription struct { + // TODO make generic or use an interface + client *ethClient.Client + connector connectors.Connector + logC chan *ethabi.AbiLogMessagePublished + errC chan error + quit chan struct{} +} + +func NewSubscription(client *ethClient.Client, connector connectors.Connector) *Subscription { + return &Subscription{ + client: client, + connector: connector, + logC: make(chan *ethabi.AbiLogMessagePublished), + errC: make(chan error), + quit: make(chan struct{}), + } +} + +// Subscribe creates a subscription to WatchLogMessagePublished events and will +// attempt to reconnect when errors occur, such as Websocket connection +// problems. +func (s *Subscription) Subscribe(ctx context.Context) { + go func() { + for { + select { + case <-ctx.Done(): + return + case <-s.quit: + return + default: + subscription, err := s.connector.WatchLogMessagePublished( + ctx, + s.errC, + s.logC, + ) + + if err != nil { + s.errC <- fmt.Errorf("failed to subscribe to logs: %w", err) + time.Sleep(RECONNECT_DELAY) // Wait before retrying + continue + } + + // Handle subscription until error occurs + // TODO: This section of code should have a limit on the number of times it will retry + // and fail if it can't connect a certain number of times + err = s.handleSubscription(ctx, subscription) + + if err != nil { + s.errC <- err + time.Sleep(RECONNECT_DELAY) // Wait before retrying + } + } + } + }() +} + +func (s *Subscription) handleSubscription(ctx context.Context, subscription event.Subscription) error { + for { + select { + case <-ctx.Done(): + subscription.Unsubscribe() + return nil + case <-s.quit: + subscription.Unsubscribe() + return nil + case err := <-subscription.Err(): + subscription.Unsubscribe() + return fmt.Errorf("subscription error: %w", err) + } + } +} + +func (s *Subscription) Events() <-chan *ethabi.AbiLogMessagePublished { + return s.logC +} + +func (s *Subscription) Errors() <-chan error { + return s.errC +} + +func (s *Subscription) Close() { + close(s.quit) +} + +// Abstraction over the fields that are expected to be present for Transfer +// types encoded in receipt logs: Deposits, Transfers, and LogMessagePublished +// events. +type TransferLog interface { + // Amount after (de)normalization + TransferAmount() *big.Int + // The Transferror: EOA or contract that initiated the transfer. Not to be confused with msg.sender. + Sender() vaa.Address + // The Transferee. Ultimate recipient of funds. + Destination() vaa.Address + // Event emitter + Emitter() common.Address // Emitter will always be an Ethereum address + // Chain where the token was minted + OriginChain() vaa.ChainID + // Address that minted the token + OriginAddress() vaa.Address +} + +// Abstraction over a Deposit event for a wrapped native asset, e.g. WETH for Ethereum. +type NativeDeposit struct { + // The address of the token. + TokenAddress common.Address + // The native chain of the token (where it was minted) + TokenChain vaa.ChainID + Receiver common.Address + Amount *big.Int +} + +func (d *NativeDeposit) TransferAmount() *big.Int { + return d.Amount +} + +func (d *NativeDeposit) Destination() vaa.Address { + return VAAAddrFrom(d.Receiver) +} + +// Deposit does not actually have a sender but this is required to implement the interface +func (d *NativeDeposit) Sender() vaa.Address { + // Sender is not present in the Logs emitted for a Deposit + return ZERO_ADDRESS_VAA +} + +func (d *NativeDeposit) Emitter() common.Address { + // Event emitter of the Deposit should be equal to TokenAddress. + return d.TokenAddress +} + +func (d *NativeDeposit) OriginChain() vaa.ChainID { + return d.TokenChain +} + +func (d *NativeDeposit) OriginAddress() vaa.Address { + return VAAAddrFrom(d.TokenAddress) +} + +func (d *NativeDeposit) String() string { + return fmt.Sprintf( + "Deposit: {TokenAddress=%s TokenChain=%d Receiver=%s Amount=%s}", + d.TokenAddress.String(), + d.TokenChain, + d.Receiver.String(), + d.Amount.String(), + ) +} + +// DepositFromLog() creates a NativeDeposit struct given a log and Wormhole chain ID. +func DepositFromLog( + log *types.Log, + // This chain ID should correspond to the Wormhole chain ID, not the EVM chain ID. In this context it's + // important to track the transfer as Wormhole sees it, not as the EVM network itself sees it. + chainId vaa.ChainID, +) (deposit *NativeDeposit, err error) { + dest, amount := parseWNativeDepositEvent(log.Topics, log.Data) + + if amount == nil { + return deposit, errors.New("could not parse Deposit from log") + } + + deposit = &NativeDeposit{ + TokenAddress: log.Address, + TokenChain: chainId, + Receiver: dest, + Amount: amount, + } + return +} + +// parseWNativeDepositEvent parses an event for a deposit of a wrapped version of the chain's native asset, i.e. WETH for Ethereum. +func parseWNativeDepositEvent(logTopics []common.Hash, logData []byte) (destination common.Address, amount *big.Int) { + + // https://etherscan.io/token/0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2#code#L29 + // event Deposit(address indexed dst, uint wad); + if len(logData) != EVM_WORD_LENGTH || len(logTopics) != TOPICS_COUNT_DEPOSIT { + return common.Address{}, nil + } + + destination = common.BytesToAddress(logTopics[1][:]) + amount = new(big.Int).SetBytes(logData[:]) + + return destination, amount +} + +// Abstraction over an ERC20 Transfer event. +type ERC20Transfer struct { + // The address of the token. Also equivalent to the Emitter of the event. + TokenAddress common.Address + // The native chain of the token (where it was minted) + TokenChain vaa.ChainID + From common.Address + To common.Address + Amount *big.Int +} + +func (t *ERC20Transfer) TransferAmount() *big.Int { + return t.Amount +} + +func (t *ERC20Transfer) Sender() vaa.Address { + // Note that this value may return zero for receipt logs that are in + // fact Transfers emitted from e.g. UniswapV2 which have the same event + // signature as ERC20 Transfers. + return VAAAddrFrom(t.From) +} + +func (t *ERC20Transfer) Destination() vaa.Address { + // Note that this value may return zero when tokens are being burned. + return VAAAddrFrom(t.To) +} + +func (t *ERC20Transfer) Emitter() common.Address { + // The TokenAddress is equal to the Emitter for ERC20 Transfers + return t.TokenAddress +} + +func (t *ERC20Transfer) OriginChain() vaa.ChainID { + return t.TokenChain +} + +func (t *ERC20Transfer) OriginAddress() vaa.Address { + return VAAAddrFrom(t.TokenAddress) +} + +func (t *ERC20Transfer) String() string { + return fmt.Sprintf( + "ERC20Transfer: {TokenAddress=%s TokenChain=%d From=%s To=%s Amount=%s}", + t.TokenAddress.String(), + t.TokenChain, + t.From.String(), + t.To.String(), + t.Amount.String(), + ) +} + +// ERC20TransferFromLog() creates an ERC20Transfer struct given a log and Wormhole chain ID. +func ERC20TransferFromLog( + log *types.Log, + // This chain ID should correspond to the Wormhole chain ID, not the EVM chain ID. In this context it's + // important to track the transfer as Wormhole sees it, not as the EVM network itself sees it. + chainId vaa.ChainID, +) (transfer *ERC20Transfer, err error) { + from, to, amount := parseERC20TransferEvent(log.Topics, log.Data) + + // Ensure From address is not empty. The To address is allowed to be empty when funds are being burned. + if cmp(from, ZERO_ADDRESS) == 0 { + return transfer, errors.New("could not parse ERC20 Transfer from log: address From is empty") + } + + if amount == nil { + return transfer, errors.New("could not parse ERC20 Transfer from log: nil Amount") + } + + transfer = &ERC20Transfer{ + TokenAddress: log.Address, + // Initially, set Token's chain to the chain being monitored. This will be updated by making an RPC call later. + TokenChain: chainId, + From: from, + To: to, + Amount: amount, + } + return +} + +// This function parses an ERC20 transfer event from a log topic and data. +// It verifies the input lengths, extracts the 'from', 'to' and amount fields from the log data, +// and returns these values as common.Address and big.Int types. +// - Error handling: The function checks if the log data and topic lengths are correct before attempting to parse them. +// - Input validation: The function verifies that the input lengths match expected values, preventing potential attacks or errors. +func parseERC20TransferEvent(logTopics []common.Hash, logData []byte) (from common.Address, to common.Address, amount *big.Int) { + + // https://github.com/OpenZeppelin/openzeppelin-contracts/blob/6e224307b44bc4bd0cb60d408844e028cfa3e485/contracts/token/ERC20/IERC20.sol#L16 + // event Transfer(address indexed from, address indexed to, uint256 value) + if len(logData) != EVM_WORD_LENGTH || len(logTopics) != TOPICS_COUNT_TRANSFER { + return common.Address{}, common.Address{}, nil + } + + from = common.BytesToAddress(logTopics[1][:]) + to = common.BytesToAddress(logTopics[2][:]) + amount = new(big.Int).SetBytes(logData[:]) + + return +} + +// Abstraction over a LogMessagePublished event emitted by the core bridge. +// TODO add String() method +type LogMessagePublished struct { + // Which contract emitted the event. + EventEmitter common.Address + // Which address sent the transaction that triggered the message publication. + MsgSender common.Address + // Abstraction over fields encoded in the event's Data field which in turn contains the transfer's payload. + TransferDetails *TransferDetails + // Note: these fields are non-exhaustive. Data not needed for Transfer Verification is not encoded here. +} + +func (l *LogMessagePublished) String() string { + return fmt.Sprintf("LogMessagePublished: {emitter=%s sender=%s transferDetails=%s}", + l.EventEmitter, + l.MsgSender, + l.TransferDetails, + ) +} + +func (l *LogMessagePublished) Destination() (destination vaa.Address) { + if l.TransferDetails != nil { + destination = l.TransferDetails.TargetAddress + } + return +} + +func (l *LogMessagePublished) Emitter() common.Address { + return l.EventEmitter +} + +func (l *LogMessagePublished) Sender() vaa.Address { + return VAAAddrFrom(l.MsgSender) +} + +func (l *LogMessagePublished) TransferAmount() (amount *big.Int) { + if l.TransferDetails != nil { + return l.TransferDetails.Amount + } + return +} + +func (l *LogMessagePublished) OriginAddress() (origin vaa.Address) { + if l.TransferDetails != nil { + origin = VAAAddrFrom(l.TransferDetails.OriginAddress) + } + return +} + +func (l *LogMessagePublished) OriginChain() (chainID vaa.ChainID) { + if l.TransferDetails != nil { + chainID = l.TransferDetails.TokenChain + } + return +} + +// TransferReceipt is an abstraction over an EVM transaction receipt for a +// Token Bridge transfer. It represents Deposit, Transfer, and +// LogMessagePublished events that can appear in a Receipt logs. Other event +// types are not represented by this program because they are not relevant for +// checking the invariants on transfers sent from the token bridge. +type TransferReceipt struct { + Deposits *[]*NativeDeposit + Transfers *[]*ERC20Transfer + // There must be at least one LogMessagePublished for a valid receipt. + MessagePublicatons *[]*LogMessagePublished +} + +func (r *TransferReceipt) String() string { + dStr := "" + if r.Deposits != nil { + for _, d := range *r.Deposits { + if d != nil { + dStr += d.String() + } + } + } + + tStr := "" + if r.Transfers != nil { + for _, t := range *r.Transfers { + if t != nil { + tStr += t.String() + } + } + } + + mStr := "" + if r.MessagePublicatons != nil { + for _, m := range *r.MessagePublicatons { + if m != nil { + mStr += m.String() + } + } + } + + return fmt.Sprintf( + "receipt: {deposits=%s transfers=%s messages=%s}", + dStr, + tStr, + mStr, + ) +} + +// Summary of a processed TransferReceipt. Contains information about relevant +// transfers requested in and out of the bridge. +type ReceiptSummary struct { + // Number of LogMessagePublished events in the receipt + logsProcessed int + // The sum of tokens transferred into the Token Bridge contract. + in map[string]*big.Int + // The sum of tokens parsed from the core bridge's LogMessagePublished payload. + out map[string]*big.Int +} + +func NewReceiptSummary() *ReceiptSummary { + return &ReceiptSummary{ + logsProcessed: 0, + // The sum of tokens transferred into the Token Bridge contract. + in: make(map[string]*big.Int), + // The sum of tokens parsed from the core bridge's LogMessagePublished payload. + out: make(map[string]*big.Int), + } +} + +func (s *ReceiptSummary) String() (outStr string) { + + ins := "" + + for key, amountIn := range s.in { + ins += fmt.Sprintf("%s=%s", key, amountIn.String()) + } + + outs := "" + for key, amountOut := range s.out { + outs += fmt.Sprintf("%s=%s ", key, amountOut.String()) + } + + outStr = fmt.Sprintf( + "receipt summary: logsProcessed=%d requestedIn={%s} requestedOut={%s}", + s.logsProcessed, + ins, + outs, + ) + return outStr +} + +// https://wormhole.com/docs/learn/infrastructure/vaas/#payload-types +type VAAPayloadType uint8 + +const ( + TransferTokens VAAPayloadType = 1 + TransferTokensWithPayload VAAPayloadType = 3 +) + +// Abstraction of a Token Bridge transfer payload encoded in the Data field of a LogMessagePublished event. +// It is meant to correspond to the API for Token Transfer messages as described in the Token Bridge whitepaper: +// https://github.com/wormhole-foundation/wormhole/blob/main/whitepapers/0003_token_bridge.md#api--database-schema +type TransferDetails struct { + PayloadType VAAPayloadType + // Denormalized amount, accounting for decimal differences between contracts and chains + Amount *big.Int + // Amount as sent in the raw payload + AmountRaw *big.Int + // Original wormhole chain ID where the token was minted. + TokenChain vaa.ChainID + // Original address of the token when minted natively. Corresponds to the "unwrapped" address in the token bridge. + OriginAddress common.Address + // Raw token address parsed from the payload. May be wrapped. + OriginAddressRaw []byte + // Not necessarily an EVM address, so vaa.Address is used instead + TargetAddress vaa.Address +} + +func (td *TransferDetails) String() string { + return fmt.Sprintf( + "PayloadType: %d OriginAddressRaw(hex-encoded): %s TokenChain: %d OriginAddress: %s TargetAddress: %s AmountRaw: %s Amount: %s", + td.PayloadType, + fmt.Sprintf("%x", td.OriginAddressRaw), + td.TokenChain, + td.OriginAddress.String(), + td.TargetAddress.String(), + td.AmountRaw.String(), + td.Amount.String(), + ) +} + +// unwrapIfWrapped returns the "unwrapped" address for a token a.k.a. the OriginAddress +// of the token's original minting contract. +func (tv *TransferVerifier[ethClient, connector]) unwrapIfWrapped( + tokenAddress []byte, + tokenChain vaa.ChainID, +) (unwrappedTokenAddress common.Address, err error) { + ctx, cancel := context.WithTimeout(context.Background(), RPC_TIMEOUT) + defer cancel() + + tokenAddressAsKey := hex.EncodeToString(tokenAddress) + + // If the token address already exists in the wrappedCache mapping the + // cached value can be returned. + if addr, exists := tv.wrappedCache[tokenAddressAsKey]; exists { + tv.logger.Debug("wrapped asset found in cache, returning") + return addr, nil + } + + // prepare eth_call data, 4-byte signature + 2x 32 byte arguments + calldata := make([]byte, 4+EVM_WORD_LENGTH+EVM_WORD_LENGTH) + + copy(calldata, TOKEN_BRIDGE_WRAPPED_ASSET_SIGNATURE) + // Add the uint16 tokenChain as the last two bytes in the first argument + binary.BigEndian.PutUint16(calldata[4+30:], uint16(tokenChain)) + copy(calldata[4+EVM_WORD_LENGTH:], common.LeftPadBytes(tokenAddress, EVM_WORD_LENGTH)) + + ethCallMsg := ethereum.CallMsg{ + To: &tv.Addresses.TokenBridgeAddr, + Data: calldata, + } + tv.logger.Debug("calling wrappedAsset", + zap.Uint16("tokenChain", uint16(tokenChain)), + zap.String("tokenChainString", tokenChain.String()), + zap.String("tokenAddress", fmt.Sprintf("%x", tokenAddress)), + zap.String("callData", fmt.Sprintf("%x", calldata))) + + result, err := tv.client.CallContract(ctx, ethCallMsg, nil) + if err != nil { + // This strictly handles the error case. The contract call will + // return the zero address for assets not in its map. + return common.Address{}, fmt.Errorf("failed to get mapping for token %s", tokenAddressAsKey) + } + + tokenAddressNative := common.BytesToAddress(result) + tv.wrappedCache[tokenAddressAsKey] = tokenAddressNative + + tv.logger.Debug("got wrappedAsset result", + zap.String("tokenAddressNative", fmt.Sprintf("%x", tokenAddressNative))) + + if cmp(tokenAddressNative, ZERO_ADDRESS) == 0 { + tv.logger.Info("got zero address for wrappedAsset result. this asset is probably not registered correctly", + zap.String("queried tokenAddress", fmt.Sprintf("%x", tokenAddress)), + zap.Uint16("queried tokenChain", uint16(tokenChain)), + zap.String("tokenChain name", tokenChain.String()), + ) + } + + return tokenAddressNative, nil +} + +// chainId() calls the chainId() function on the contract at the supplied address. To get the chain ID being monitored +// by the Transfer Verifier, use the field TransferVerifier.chain. +func (tv *TransferVerifier[ethClient, Connector]) chainId( + addr common.Address, +) (vaa.ChainID, error) { + + if cmp(addr, ZERO_ADDRESS) == 0 { + return 0, errors.New("got zero address as parameter for chainId() call") + } + ctx, cancel := context.WithTimeout(context.Background(), RPC_TIMEOUT) + defer cancel() + + tokenAddressAsKey := addr.Hex() + + // If the token address already exists in the wrappedCache mapping the + // cached value can be returned. + if chainId, exists := tv.nativeChainCache[tokenAddressAsKey]; exists { + tv.logger.Debug("wrapped asset found in native chain cache, returning") + return chainId, nil + } + + // prepare eth_call data, 4-byte signature + calldata := make([]byte, 4) + + copy(calldata, WRAPPED_ERC20_CHAIN_ID_SIGNATURE) + + ethCallMsg := ethereum.CallMsg{ + To: &addr, + Data: calldata, + } + + tv.logger.Debug("calling chainId()", zap.String("tokenAddress", addr.String())) + + result, err := tv.client.CallContract(ctx, ethCallMsg, nil) + + if err != nil { + // TODO add more checks here + return 0, err + } + if len(result) < EVM_WORD_LENGTH { + tv.logger.Warn("result for chainId has insufficient length", + zap.Int("length", len(result)), + zap.String("result", fmt.Sprintf("%x", result))) + return 0, errors.New("result for chainId has insufficient length") + } + + chainID := vaa.ChainID(binary.BigEndian.Uint16(result)) + + tv.nativeChainCache[tokenAddressAsKey] = chainID + + return chainID, nil +} + +func (tv *TransferVerifier[ethClient, Connector]) isWrappedAsset( + addr common.Address, + // chainID common.Address, +) (bool, error) { + ctx, cancel := context.WithTimeout(context.Background(), RPC_TIMEOUT) + defer cancel() + + tokenAddressAsKey := addr.Hex() + + // If the token address already exists in the isWrappedCache mapping the + // cached value can be returned. + if wrapped, exists := tv.isWrappedCache[tokenAddressAsKey]; exists { + tv.logger.Debug("asset found in isWrapped cache, returning") + return wrapped, nil + } + + // Prepare eth_call data: 4-byte signature + 32 byte address + calldata := make([]byte, 4+EVM_WORD_LENGTH) + copy(calldata, TOKEN_BRIDGE_IS_WRAPPED_ASSET_SIGNATURE) + copy(calldata[4:], common.LeftPadBytes(addr.Bytes(), EVM_WORD_LENGTH)) + + evmCallMsg := ethereum.CallMsg{ + To: &tv.Addresses.TokenBridgeAddr, + Data: calldata, + } + + tv.logger.Debug("calling isWrappedAsset()", zap.String("tokenAddress", addr.String())) + + result, err := tv.client.CallContract(ctx, evmCallMsg, nil) + + if err != nil { + // TODO add more info here + tv.logger.Warn("isWrappedAsset() call error", zap.Error(err)) + return false, err + } + if len(result) < EVM_WORD_LENGTH { + tv.logger.Warn("isWrappedAsset() result length is too small", zap.String("result", fmt.Sprintf("%x", result))) + return false, err + } + tv.logger.Debug("isWrappedAsset result", zap.String("result", fmt.Sprintf("%x", result))) + + // The boolean result will be returned as a byte string with length + // equal to EVM_WORD_LENGTH. Grab the last byte. + wrapped := result[EVM_WORD_LENGTH-1] == 1 + + tv.isWrappedCache[tokenAddressAsKey] = wrapped + + return wrapped, nil +} + +// Determine whether a log is relevant for the addresses passed into TVAddresses. Returns a string of the form "address-chain" for relevant entries. +func relevant[L TransferLog](tLog TransferLog, tv *TVAddresses) (key string, relevant bool) { + + switch log := tLog.(type) { + case *NativeDeposit: + // Skip native deposit events emitted by contracts other than the configured wrapped native address. + if cmp(log.Emitter(), tv.WrappedNativeAddr) != 0 { + return + } + + // We only care about deposits into the token bridge. + if cmp(log.Destination(), tv.TokenBridgeAddr) != 0 { + return + } + + case *ERC20Transfer: + // We only care about transfers sent to the token bridge. + if cmp(log.Destination(), tv.TokenBridgeAddr) != 0 { + return + } + + case *LogMessagePublished: + // This check is already done elsewhere but it's important. + if cmp(log.Emitter(), tv.CoreBridgeAddr) != 0 { + return + } + + // Only consider LogMessagePublished events with msg.sender equal to the Token Bridge + if cmp(log.Sender(), tv.TokenBridgeAddr) != 0 { + return + } + + // The following values are not exposed by the interface, so check them directly here. + if log.TransferDetails.PayloadType != TransferTokens && log.TransferDetails.PayloadType != TransferTokensWithPayload { + return + } + + } + return fmt.Sprintf(KEY_FORMAT, tLog.OriginAddress(), tLog.OriginChain()), true +} + +// Custom error type indicating an issue in issue in a type that implements the +// TransferLog interface. Used to ensure that a TransferLog is well-formed. +// Typically indicates a bug in the code. +type InvalidLogError struct { + Msg string +} + +func (i InvalidLogError) Error() string { + return fmt.Sprintf("invalid log: %s", i.Msg) +} + +// validate() ensures a TransferLog is well-formed. This means that its fields +// are not nil and in most cases are not equal to the zero-value for the +// field's type. +func validate[L TransferLog](tLog TransferLog) error { + + // Generic validation for all TransferLogs + if cmp(tLog.Emitter(), ZERO_ADDRESS) == 0 { + return &InvalidLogError{Msg: "emitter is the zero address"} + } + + if tLog.OriginChain() == 0 { + return &InvalidLogError{Msg: "originChain is zero"} + } + + if tLog.TransferAmount() == nil { + return &InvalidLogError{Msg: "transfer amount is nil"} + } + + if tLog.TransferAmount().Sign() == -1 { + return &InvalidLogError{Msg: "transfer amount is negative"} + } + + switch log := tLog.(type) { + case *NativeDeposit: + // Deposit does not actually have a sender, so it should always be equal to the zero address. + if cmp(log.Sender(), ZERO_ADDRESS_VAA) != 0 { + return &InvalidLogError{Msg: "sender address for Deposit must be 0"} + } + if cmp(log.Emitter(), log.TokenAddress) != 0 { + return &InvalidLogError{Msg: "deposit emitter is not equal to its token address"} + } + if cmp(log.Destination(), ZERO_ADDRESS_VAA) == 0 { + return &InvalidLogError{Msg: "destination is not set"} + } + if cmp(log.OriginAddress(), ZERO_ADDRESS_VAA) == 0 { + return &InvalidLogError{Msg: "originAddress is the zero address"} + } + case *ERC20Transfer: + // Note: The token bridge transfers to the zero address in + // order to burn tokens for some kinds of transfers. For this + // reason, there is no validation here to check if Destination + // is the zero address. + + // Sender must not be checked to be non-zero here. The event + // hash for Transfer also shows up in other popular contracts + // (e.g. UniswapV2) and may have a valid reason to set this + // field to zero. + + // TODO ensure that, if the Token is wrapped, that its tokenchain is not equal to NATIVE_CHAIN_ID. + // at this point, this should've been updated + + if cmp(log.Emitter(), log.TokenAddress) != 0 { + return &InvalidLogError{Msg: "transfer emitter is not equal to its token address"} + } + if cmp(log.OriginAddress(), ZERO_ADDRESS_VAA) == 0 { + return &InvalidLogError{Msg: "originAddress is the zero address"} + } + case *LogMessagePublished: + // LogMessagePublished cannot have a sender with a 0 address + if cmp(log.Sender(), ZERO_ADDRESS_VAA) == 0 { + return &InvalidLogError{Msg: "sender cannot be zero"} + } + if cmp(log.Destination(), ZERO_ADDRESS_VAA) == 0 { + return &InvalidLogError{Msg: "destination is not set"} + } + + // TODO is this valid for assets that return the zero address from unwrap? + // if cmp(log.OriginAddress(), ZERO_ADDRESS_VAA) == 0 { + // return errors.New("origin cannot be zero") + // } + + // The following values are not exposed by the interface, so check them directly here. + if log.TransferDetails == nil { + return &InvalidLogError{Msg: "TransferDetails cannot be nil"} + } + if cmp(log.TransferDetails.TargetAddress, ZERO_ADDRESS_VAA) == 0 { + return &InvalidLogError{Msg: "target address cannot be zero"} + } + + if len(log.TransferDetails.OriginAddressRaw) == 0 { + return &InvalidLogError{Msg: "origin address raw cannot be empty"} + } + + // if bytes.Compare(log.TransferDetails.OriginAddressRaw, ZERO_ADDRESS_VAA.Bytes()) == 0 { + // return &InvalidLogError{Msg: "origin address raw cannot be zero"} + // } + + if log.TransferDetails.AmountRaw == nil { + return &InvalidLogError{Msg: "amountRaw cannot be nil"} + } + if log.TransferDetails.AmountRaw.Sign() == -1 { + return &InvalidLogError{Msg: "amountRaw cannot be negative"} + } + if log.TransferDetails.PayloadType != TransferTokens && log.TransferDetails.PayloadType != TransferTokensWithPayload { + return &InvalidLogError{Msg: "payload type is not a transfer type"} + } + default: + return &InvalidLogError{Msg: "invalid transfer log type: unknown"} + } + + return nil +} + +// getDecimals() is equivalent to calling decimals() on a contract that follows the ERC20 standard. +func (tv *TransferVerifier[evmClient, connector]) getDecimals( + tokenAddress common.Address, +) (decimals uint8, err error) { + ctx, cancel := context.WithTimeout(context.Background(), RPC_TIMEOUT) + defer cancel() + + // First check if this token's decimals is stored in cache + if _, exists := tv.decimalsCache[tokenAddress]; exists { + tv.logger.Debug("asset decimals found in cache, returning") + return tv.decimalsCache[tokenAddress], nil + } + + // If the decimals aren't cached, perform an eth_call lookup for the decimals + // This RPC call should only be made once per token, until the guardian is restarted + evmCallMsg := ethereum.CallMsg{ + To: &tokenAddress, + Data: ERC20_DECIMALS_SIGNATURE, + } + + result, err := tv.client.CallContract(ctx, evmCallMsg, nil) + if err != nil { + tv.logger.Warn("error from getDecimals() for token", + zap.String("tokenAddress", tokenAddress.String()), + zap.ByteString("result", result), + zap.Error(err)) + return 0, err + } + + if len(result) < EVM_WORD_LENGTH { + tv.logger.Warn("failed to get decimals for token: result has insufficient length", + zap.String("tokenAddress", tokenAddress.String()), + zap.ByteString("result", result)) + return 0, err + } + + // An ERC20 token's decimals should fit in a single byte. A call to `decimals()` + // returns a uint8 value encoded in string with 32-bytes. To get the decimals, + // we grab the last byte, expecting all the preceding bytes to be equal to 0. + decimals = result[EVM_WORD_LENGTH-1] + + // Add the decimal value to the cache + tv.decimalsCache[tokenAddress] = decimals + tv.logger.Debug("adding new token's decimals to cache", + zap.String("tokenAddress", tokenAddress.String()), + zap.Uint8("tokenDecimals", decimals)) + + return decimals, nil +} + +// Yields the registered Wormhole chain ID corresponding to an EVM chain ID. +func TryWormholeChainIdFromNative(evmChainId uint64) (wormholeChainID vaa.ChainID, err error) { + wormholeChainID = vaa.ChainIDUnset + // Add additional cases below to support more EVM chains. + // Note: it might be better for this function to be moved into the SDK in case other codebases need similar functionality. + switch evmChainId { + // Special carve out for anvil-based testing. This chain ID 1337 anvil's default. + // In this case, report the native chain ID as the mainnet chain ID for the purposes of testing. + case 1, 1337: + wormholeChainID = vaa.ChainIDEthereum + case 11155111: + wormholeChainID = vaa.ChainIDSepolia + default: + err = fmt.Errorf( + "Transfer Verifier does not have a registered mapping from EVM chain ID %d to a Wormhole chain ID", + evmChainId, + ) + } + return +} + +// Gives the representation of a geth address in vaa.Address +func VAAAddrFrom(gethAddr common.Address) (vaaAddr vaa.Address) { + // Geth uses 20 bytes to represent an address. A VAA address is equivalent if it has the same + // final 20 bytes. The leading bytes are expected to be zero for both types. + vaaAddr = vaa.Address(common.LeftPadBytes(gethAddr[:], EVM_WORD_LENGTH)) + return +} + +// Interface useful for comparing vaa.Address and common.Address +type Bytes interface { + Bytes() []byte +} + +// Utility method for comparing common.Address and vaa.Address at the byte level. +func cmp[some Bytes, other Bytes](a some, b other) int { + + // Compare bytes, prepending 0s to ensure that both values are of EVM_WORD_LENGTH. + return bytes.Compare( + common.LeftPadBytes(a.Bytes(), EVM_WORD_LENGTH), + common.LeftPadBytes(b.Bytes(), EVM_WORD_LENGTH), + ) +} diff --git a/node/pkg/txverifier/evmtypes_test.go b/node/pkg/txverifier/evmtypes_test.go new file mode 100644 index 0000000000..6952ec9f12 --- /dev/null +++ b/node/pkg/txverifier/evmtypes_test.go @@ -0,0 +1,860 @@ +package txverifier + +import ( + "bytes" + "math/big" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/wormhole-foundation/wormhole/sdk/vaa" +) + +var ( + // Mainnet values + WETH_ADDRESS = common.HexToAddress("c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2") + NATIVE_CHAIN_ID vaa.ChainID = 2 +) + +func TestRelevantDeposit(t *testing.T) { + t.Parallel() + + // The expected return values for relevant() + type result struct { + key string + relevant bool + } + + mocks := setup() + + deposits := map[string]struct { + input NativeDeposit + expected result + }{ + "relevant, deposit": { + input: NativeDeposit{ + TokenAddress: nativeAddr, + TokenChain: NATIVE_CHAIN_ID, + Receiver: tokenBridgeAddr, + Amount: big.NewInt(500), + }, + expected: result{"000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2-2", true}, + }, + "irrelevant, deposit from non-native contract": { + input: NativeDeposit{ + TokenAddress: usdcAddr, // not Native + TokenChain: NATIVE_CHAIN_ID, + Receiver: tokenBridgeAddr, + Amount: big.NewInt(500), + }, + expected: result{"", false}, + }, + "irrelevant, deposit not sent to token bridge": { + input: NativeDeposit{ + TokenAddress: nativeAddr, + TokenChain: NATIVE_CHAIN_ID, + Receiver: eoaAddrGeth, // not token bridge + Amount: big.NewInt(500), + }, + expected: result{"", false}, + }, + "irrelevant, sanity check for zero-address deposits": { + input: NativeDeposit{ + TokenAddress: ZERO_ADDRESS, // zero address + TokenChain: NATIVE_CHAIN_ID, + Receiver: tokenBridgeAddr, + Amount: big.NewInt(500), + }, + expected: result{"", false}, + }, + } + + transfers := map[string]struct { + input ERC20Transfer + expected result + }{ + "relevant, transfer": { + input: ERC20Transfer{ + TokenAddress: nativeAddr, + TokenChain: NATIVE_CHAIN_ID, + From: eoaAddrGeth, + To: tokenBridgeAddr, + Amount: big.NewInt(500), + }, + expected: result{"000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2-2", true}, + }, + "irrelevant, transfer destination is not token bridge": { + input: ERC20Transfer{ + TokenAddress: nativeAddr, + TokenChain: NATIVE_CHAIN_ID, + From: eoaAddrGeth, + To: eoaAddrGeth, + Amount: big.NewInt(500), + }, + expected: result{"", false}, + }, + } + + messages := map[string]struct { + input LogMessagePublished + expected result + }{ + "relevant, LogMessagePublished": { + input: LogMessagePublished{ + EventEmitter: coreBridgeAddr, + MsgSender: tokenBridgeAddr, + TransferDetails: &TransferDetails{ + PayloadType: TransferTokens, + OriginAddressRaw: usdcAddr.Bytes(), + TokenChain: NATIVE_CHAIN_ID, + OriginAddress: nativeAddr, + TargetAddress: eoaAddrVAA, + AmountRaw: big.NewInt(7), + Amount: big.NewInt(7), + }, + }, + expected: result{"000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2-2", true}, + }, + "irrelevant, LogMessagePublished has a sender not equal to token bridge": { + input: LogMessagePublished{ + EventEmitter: coreBridgeAddr, + MsgSender: eoaAddrGeth, + TransferDetails: &TransferDetails{ + PayloadType: TransferTokens, + OriginAddressRaw: usdcAddr.Bytes(), + TokenChain: NATIVE_CHAIN_ID, + OriginAddress: nativeAddr, + TargetAddress: eoaAddrVAA, + AmountRaw: big.NewInt(7), + Amount: big.NewInt(7), + }, + }, + expected: result{"", false}, + }, + "irrelevant, LogMessagePublished not emitted by core bridge": { + input: LogMessagePublished{ + EventEmitter: tokenBridgeAddr, + MsgSender: tokenBridgeAddr, + TransferDetails: &TransferDetails{ + PayloadType: TransferTokens, + OriginAddressRaw: usdcAddr.Bytes(), + TokenChain: NATIVE_CHAIN_ID, + OriginAddress: nativeAddr, + TargetAddress: eoaAddrVAA, + AmountRaw: big.NewInt(7), + Amount: big.NewInt(7), + }, + }, + expected: result{"", false}, + }, + "irrelevant, LogMessagePublished does not have a PayloadType corresponding to a Transfer": { + input: LogMessagePublished{ + EventEmitter: coreBridgeAddr, + MsgSender: tokenBridgeAddr, + TransferDetails: &TransferDetails{ + PayloadType: 2, + OriginAddressRaw: usdcAddr.Bytes(), + TokenChain: NATIVE_CHAIN_ID, + OriginAddress: nativeAddr, + TargetAddress: eoaAddrVAA, + AmountRaw: big.NewInt(7), + Amount: big.NewInt(7), + }, + }, + expected: result{"", false}, + }, + } + + for name, test := range deposits { + test := test // NOTE: uncomment for Go < 1.22, see /doc/faq#closures_and_goroutines + t.Run(name, func(t *testing.T) { + t.Parallel() // marks each test case as capable of running in parallel with each other + + key, relevant := relevant[*NativeDeposit](&test.input, mocks.transferVerifier.Addresses) + assert.Equal(t, test.expected.key, key) + assert.Equal(t, test.expected.relevant, relevant) + + if key == "" { + assert.False(t, relevant, "key must be empty for irrelevant transfers, but got ", key) + } else { + assert.True(t, relevant, "relevant must be true for non-empty keys") + } + }) + } + + for name, test := range transfers { + test := test // NOTE: uncomment for Go < 1.22, see /doc/faq#closures_and_goroutines + t.Run(name, func(t *testing.T) { + t.Parallel() // marks each test case as capable of running in parallel with each other + + key, relevant := relevant[*ERC20Transfer](&test.input, mocks.transferVerifier.Addresses) + assert.Equal(t, test.expected.key, key) + assert.Equal(t, test.expected.relevant, relevant) + + if key == "" { + assert.False(t, relevant, "key must be empty for irrelevant transfers, but got ", key) + } else { + assert.True(t, relevant, "relevant must be true for non-empty keys") + } + }) + } + + for name, test := range messages { + test := test // NOTE: uncomment for Go < 1.22, see /doc/faq#closures_and_goroutines + t.Run(name, func(t *testing.T) { + t.Parallel() // marks each test case as capable of running in parallel with each other + + key, relevant := relevant[*LogMessagePublished](&test.input, mocks.transferVerifier.Addresses) + assert.Equal(t, test.expected.key, key) + assert.Equal(t, test.expected.relevant, relevant) + + if key == "" { + assert.False(t, relevant, "key must be empty for irrelevant transfers, but got ", key) + } else { + assert.True(t, relevant, "relevant must be true for non-empty keys") + } + }) + } +} + +func TestValidateDeposit(t *testing.T) { + t.Parallel() + + invalidDeposits := map[string]struct { + deposit NativeDeposit + }{ + "invalid: zero-value for TokenAddress": { + deposit: NativeDeposit{ + // TokenAddress: + TokenChain: NATIVE_CHAIN_ID, + Receiver: tokenBridgeAddr, + Amount: big.NewInt(1), + }, + }, + "invalid: zero-value for TokenChain": { + deposit: NativeDeposit{ + TokenAddress: usdcAddr, + // TokenChain: + Receiver: tokenBridgeAddr, + Amount: big.NewInt(1), + }, + }, + "invalid: zero-value for Receiver": { + deposit: NativeDeposit{ + TokenAddress: usdcAddr, + TokenChain: NATIVE_CHAIN_ID, + // Receiver: + Amount: big.NewInt(1), + }, + }, + "invalid: nil Amount": { + deposit: NativeDeposit{ + TokenAddress: usdcAddr, + TokenChain: NATIVE_CHAIN_ID, + Receiver: tokenBridgeAddr, + Amount: nil, + }, + }, + "invalid: negative Amount": { + deposit: NativeDeposit{ + TokenAddress: usdcAddr, + TokenChain: NATIVE_CHAIN_ID, + Receiver: tokenBridgeAddr, + Amount: big.NewInt(-1), + }, + }, + } + + for name, test := range invalidDeposits { + test := test // NOTE: uncomment for Go < 1.22, see /doc/faq#closures_and_goroutines + t.Run(name, func(t *testing.T) { + t.Parallel() // marks each test case as capable of running in parallel with each other + + err := validate[*NativeDeposit](&test.deposit) + require.Error(t, err) + }) + } + + validDeposits := map[string]struct { + deposit NativeDeposit + }{ + "valid": { + deposit: NativeDeposit{ + TokenAddress: nativeAddr, + TokenChain: NATIVE_CHAIN_ID, + Receiver: tokenBridgeAddr, + Amount: big.NewInt(500), + }, + }, + } + + for name, test := range validDeposits { + test := test // NOTE: uncomment for Go < 1.22, see /doc/faq#closures_and_goroutines + t.Run(name, func(t *testing.T) { + t.Parallel() // marks each test case as capable of running in parallel with each other + + err := validate[*NativeDeposit](&test.deposit) + require.NoError(t, err) + + // Test the interface + // The Sender() field for a Deposit must always be + // 'zero'. It only exists to satisfy the TransferLog interface. + assert.Equal(t, ZERO_ADDRESS_VAA.Bytes(), test.deposit.Sender().Bytes()) + assert.Equal(t, test.deposit.TokenAddress, test.deposit.Emitter()) + assert.NotEqual(t, ZERO_ADDRESS, test.deposit.OriginAddress()) + }) + } +} + +func TestValidateERC20Transfer(t *testing.T) { + t.Parallel() + + invalidTransfers := map[string]struct { + input ERC20Transfer + }{ + "invalid: zero-value for TokenAddress": { + input: ERC20Transfer{ + // TokenAddress: + TokenChain: NATIVE_CHAIN_ID, + To: tokenBridgeAddr, + From: eoaAddrGeth, + Amount: big.NewInt(1), + }, + }, + "invalid: zero-value for TokenChain": { + input: ERC20Transfer{ + TokenAddress: usdcAddr, + // TokenChain: + To: tokenBridgeAddr, + From: eoaAddrGeth, + Amount: big.NewInt(1), + }, + }, + // Note: transfer's To and From values are allowed to be the zero address. + "invalid: nil Amount": { + input: ERC20Transfer{ + TokenAddress: usdcAddr, + TokenChain: NATIVE_CHAIN_ID, + From: eoaAddrGeth, + To: tokenBridgeAddr, + Amount: nil, + }, + }, + "invalid: negative Amount": { + input: ERC20Transfer{ + TokenAddress: usdcAddr, + TokenChain: NATIVE_CHAIN_ID, + From: eoaAddrGeth, + To: tokenBridgeAddr, + Amount: big.NewInt(-1), + }, + }, + } + + for name, test := range invalidTransfers { + test := test // NOTE: uncomment for Go < 1.22, see /doc/faq#closures_and_goroutines + t.Run(name, func(t *testing.T) { + t.Parallel() // marks each test case as capable of running in parallel with each other + + err := validate[*ERC20Transfer](&test.input) + require.Error(t, err) + assert.ErrorContains(t, err, "invalid log") + }) + } + + validTransfers := map[string]struct { + transfer ERC20Transfer + }{ + "valid": { + transfer: ERC20Transfer{ + TokenAddress: usdcAddr, + TokenChain: NATIVE_CHAIN_ID, + To: tokenBridgeAddr, + From: eoaAddrGeth, + Amount: big.NewInt(100), + }, + }, + "valid: zero-value for From (possible Transfer event from non-ERC20 contract)": { + transfer: ERC20Transfer{ + TokenAddress: usdcAddr, + TokenChain: NATIVE_CHAIN_ID, + From: ZERO_ADDRESS, + To: tokenBridgeAddr, + Amount: big.NewInt(1), + }, + }, + "valid: zero-value for To (burning funds)": { + transfer: ERC20Transfer{ + TokenAddress: usdcAddr, + TokenChain: NATIVE_CHAIN_ID, + From: tokenBridgeAddr, + To: ZERO_ADDRESS, + Amount: big.NewInt(1), + }, + }, + } + + for name, test := range validTransfers { + test := test // NOTE: uncomment for Go < 1.22, see /doc/faq#closures_and_goroutines + t.Run(name, func(t *testing.T) { + t.Parallel() // marks each test case as capable of running in parallel with each other + + err := validate[*ERC20Transfer](&test.transfer) + require.NoError(t, err) + + // Test interface + assert.Equal(t, test.transfer.TokenAddress, test.transfer.Emitter()) + assert.NotEqual(t, ZERO_ADDRESS, test.transfer.OriginAddress()) + }) + } +} + +func TestValidateLogMessagePublished(t *testing.T) { + t.Parallel() + + invalidMessages := map[string]struct { + logMessagePublished LogMessagePublished + }{ + "invalid: zero-value for EventEmitter": { + logMessagePublished: LogMessagePublished{ + // EventEmitter: coreBridgeAddr, + MsgSender: tokenBridgeAddr, + TransferDetails: &TransferDetails{ + PayloadType: TransferTokens, + OriginAddressRaw: usdcAddr.Bytes(), + TokenChain: NATIVE_CHAIN_ID, + OriginAddress: usdcAddr, + TargetAddress: eoaAddrVAA, + AmountRaw: big.NewInt(7), + Amount: big.NewInt(7), + }, + }, + }, + "invalid: zero-value for MsgSender": { + logMessagePublished: LogMessagePublished{ + EventEmitter: coreBridgeAddr, + // MsgSender: tokenBridgeAddr, + TransferDetails: &TransferDetails{ + PayloadType: TransferTokens, + OriginAddressRaw: usdcAddr.Bytes(), + TokenChain: NATIVE_CHAIN_ID, + OriginAddress: usdcAddr, + TargetAddress: eoaAddrVAA, + AmountRaw: big.NewInt(7), + Amount: big.NewInt(7), + }, + }, + }, + "invalid: zero-value for TransferDetails": { + logMessagePublished: LogMessagePublished{ + EventEmitter: coreBridgeAddr, + MsgSender: tokenBridgeAddr, + // TransferDetails: &TransferDetails{ + // PayloadType: TransferTokens, + // OriginAddressRaw: usdcAddr, + // TokenChain: NATIVE_CHAIN_ID, + // OriginAddress: eoaAddrGeth, + // TargetAddress: eoaAddrVAA, + // AmountRaw: big.NewInt(7), + // Amount: big.NewInt(7), + // }, + }, + }, + "invalid: zero-value for PayloadType": { + logMessagePublished: LogMessagePublished{ + EventEmitter: coreBridgeAddr, + MsgSender: tokenBridgeAddr, + TransferDetails: &TransferDetails{ + // PayloadType: TransferTokens, + OriginAddressRaw: usdcAddr.Bytes(), + TokenChain: NATIVE_CHAIN_ID, + OriginAddress: usdcAddr, + TargetAddress: eoaAddrVAA, + AmountRaw: big.NewInt(7), + Amount: big.NewInt(7), + }, + }, + }, + "invalid: zero-value for OriginAddressRaw": { + logMessagePublished: LogMessagePublished{ + EventEmitter: coreBridgeAddr, + MsgSender: tokenBridgeAddr, + TransferDetails: &TransferDetails{ + PayloadType: TransferTokens, + // OriginAddressRaw: erc20Addr, + TokenChain: NATIVE_CHAIN_ID, + OriginAddress: usdcAddr, + TargetAddress: eoaAddrVAA, + AmountRaw: big.NewInt(7), + Amount: big.NewInt(7), + }, + }, + }, + "invalid: zero-value for TokenChain": { + logMessagePublished: LogMessagePublished{ + EventEmitter: coreBridgeAddr, + MsgSender: tokenBridgeAddr, + TransferDetails: &TransferDetails{ + PayloadType: TransferTokens, + OriginAddressRaw: usdcAddr.Bytes(), + // TokenChain: NATIVE_CHAIN_ID, + OriginAddress: usdcAddr, + TargetAddress: eoaAddrVAA, + AmountRaw: big.NewInt(7), + Amount: big.NewInt(7), + }, + }, + }, + // OriginAddress may be zero for unwrapped assets without a wrapped entry? + // "invalid: zero-value for OriginAddress": { + // input: LogMessagePublished{ + // EventEmitter: coreBridgeAddr, + // MsgSender: tokenBridgeAddr, + // TransferDetails: &TransferDetails{ + // PayloadType: TransferTokens, + // OriginAddressRaw: usdcAddr, + // TokenChain: NATIVE_CHAIN_ID, + // // OriginAddress: usdcAddr, + // TargetAddress: eoaAddrVAA, + // AmountRaw: big.NewInt(7), + // Amount: big.NewInt(7), + // }, + // }, + // }, + "invalid: zero-value for TargetAddress": { + logMessagePublished: LogMessagePublished{ + EventEmitter: coreBridgeAddr, + MsgSender: tokenBridgeAddr, + TransferDetails: &TransferDetails{ + PayloadType: TransferTokens, + OriginAddressRaw: usdcAddr.Bytes(), + TokenChain: NATIVE_CHAIN_ID, + OriginAddress: usdcAddr, + // TargetAddress: eoaAddrVAA, + AmountRaw: big.NewInt(7), + Amount: big.NewInt(7), + }, + }, + }, + "invalid: nil AmountRaw": { + logMessagePublished: LogMessagePublished{ + EventEmitter: coreBridgeAddr, + MsgSender: tokenBridgeAddr, + TransferDetails: &TransferDetails{ + PayloadType: TransferTokens, + OriginAddressRaw: usdcAddr.Bytes(), + TokenChain: NATIVE_CHAIN_ID, + OriginAddress: usdcAddr, + TargetAddress: eoaAddrVAA, + // AmountRaw: big.NewInt(7), + Amount: big.NewInt(7), + }, + }, + }, + "invalid: negative AmountRaw": { + logMessagePublished: LogMessagePublished{ + EventEmitter: coreBridgeAddr, + MsgSender: tokenBridgeAddr, + TransferDetails: &TransferDetails{ + PayloadType: TransferTokens, + OriginAddressRaw: usdcAddr.Bytes(), + TokenChain: NATIVE_CHAIN_ID, + OriginAddress: usdcAddr, + TargetAddress: eoaAddrVAA, + AmountRaw: big.NewInt(-1), + Amount: big.NewInt(7), + }, + }, + }, + "invalid: nil Amount": { + logMessagePublished: LogMessagePublished{ + EventEmitter: coreBridgeAddr, + MsgSender: tokenBridgeAddr, + TransferDetails: &TransferDetails{ + PayloadType: TransferTokens, + OriginAddressRaw: usdcAddr.Bytes(), + TokenChain: NATIVE_CHAIN_ID, + OriginAddress: usdcAddr, + TargetAddress: eoaAddrVAA, + AmountRaw: big.NewInt(7), + // Amount: big.NewInt(7), + }, + }, + }, + "invalid: negative Amount": { + logMessagePublished: LogMessagePublished{ + EventEmitter: coreBridgeAddr, + MsgSender: tokenBridgeAddr, + TransferDetails: &TransferDetails{ + PayloadType: TransferTokens, + OriginAddressRaw: usdcAddr.Bytes(), + TokenChain: NATIVE_CHAIN_ID, + OriginAddress: usdcAddr, + TargetAddress: eoaAddrVAA, + AmountRaw: big.NewInt(7), + Amount: big.NewInt(-1), + }, + }, + }, + } + + for name, test := range invalidMessages { + test := test // NOTE: uncomment for Go < 1.22, see /doc/faq#closures_and_goroutines + t.Run(name, func(t *testing.T) { + t.Parallel() // marks each test case as capable of running in parallel with each other + + err := validate[*LogMessagePublished](&test.logMessagePublished) + require.Error(t, err) + _, ok := err.(*InvalidLogError) + assert.True(t, ok, "wrong error type: ", err.Error()) + }) + } + + validTransfers := map[string]struct { + input LogMessagePublished + }{ + "valid and relevant": { + input: LogMessagePublished{ + EventEmitter: coreBridgeAddr, + MsgSender: tokenBridgeAddr, + TransferDetails: &TransferDetails{ + PayloadType: TransferTokens, + OriginAddressRaw: usdcAddr.Bytes(), + TokenChain: NATIVE_CHAIN_ID, + OriginAddress: eoaAddrGeth, + TargetAddress: eoaAddrVAA, + AmountRaw: big.NewInt(7), + Amount: big.NewInt(7), + }, + }, + }, + "valid and irrelevant": { + input: LogMessagePublished{ + EventEmitter: usdcAddr, + MsgSender: eoaAddrGeth, + TransferDetails: &TransferDetails{ + PayloadType: TransferTokensWithPayload, + OriginAddressRaw: usdcAddr.Bytes(), + TokenChain: NATIVE_CHAIN_ID, + OriginAddress: eoaAddrGeth, + TargetAddress: eoaAddrVAA, + AmountRaw: big.NewInt(7), + Amount: big.NewInt(7), + }, + }, + }, + } + + for name, test := range validTransfers { + test := test // NOTE: uncomment for Go < 1.22, see /doc/faq#closures_and_goroutines + t.Run(name, func(t *testing.T) { + t.Parallel() // marks each test case as capable of running in parallel with each other + + err := validate[*LogMessagePublished](&test.input) + require.NoError(t, err) + }) + } +} + +func TestCmp(t *testing.T) { + + t.Parallel() + + // Table-driven tests were not used here because the function takes generic types which are awkward to declare + // in that format. + + // Test identity + assert.Zero(t, cmp(ZERO_ADDRESS, ZERO_ADDRESS)) + assert.Zero(t, cmp(ZERO_ADDRESS_VAA, ZERO_ADDRESS)) + + // Test mixed types + assert.Zero(t, cmp(ZERO_ADDRESS, ZERO_ADDRESS_VAA)) + assert.Zero(t, cmp(ZERO_ADDRESS_VAA, ZERO_ADDRESS_VAA)) + + vaaAddr, err := vaa.BytesToAddress([]byte{0x01}) + require.NoError(t, err) + assert.Zero(t, cmp(vaaAddr, common.BytesToAddress([]byte{0x01}))) + + vaaAddr, err = vaa.BytesToAddress([]byte{0xff, 0x02}) + require.NoError(t, err) + assert.Zero(t, cmp(common.BytesToAddress([]byte{0xff, 0x02}), vaaAddr)) +} + +func TestVAAFromAddr(t *testing.T) { + + t.Parallel() + + // Test values. Declared here in order to silence error values from the vaa functions. + vaa1, _ := vaa.BytesToAddress([]byte{0xff, 0x02}) + vaa2, _ := vaa.StringToAddress("0000000000000000000000002260fac5e5542a773aa44fbcfedf7c193bc2c599") + + tests := map[string]struct { + input common.Address + expected vaa.Address + }{ + "valid, arbitrary": { + input: common.BytesToAddress([]byte{0xff, 0x02}), + expected: vaa1, + }, + "valid, zero values": { + input: ZERO_ADDRESS, + expected: ZERO_ADDRESS_VAA, + }, + "valid, string-based": { + input: common.HexToAddress("0x2260fac5e5542a773aa44fbcfedf7c193bc2c599"), + expected: vaa2, + }, + } + + for name, test := range tests { + test := test // NOTE: uncomment for Go < 1.22, see /doc/faq#closures_and_goroutines + t.Run(name, func(t *testing.T) { + t.Parallel() // marks each test case as capable of running in parallel with each other + + res := VAAAddrFrom(test.input) + assert.Equal(t, test.expected, res) + assert.Zero(t, bytes.Compare(res[:], common.LeftPadBytes(test.input.Bytes(), EVM_WORD_LENGTH))) + }) + } + +} + +func TestDepositFrom(t *testing.T) { + + t.Parallel() + + tests := map[string]struct { + log types.Log + expected *NativeDeposit + }{ + "valid deposit": { + log: types.Log{ + Address: WETH_ADDRESS, + Topics: []common.Hash{ + common.HexToHash(EVENTHASH_WETH_DEPOSIT), + // Receiver + common.HexToHash(tokenBridgeAddr.String()), + }, + TxHash: common.BytesToHash([]byte{0x01}), + Data: common.LeftPadBytes(big.NewInt(100).Bytes(), EVM_WORD_LENGTH), + }, + expected: &NativeDeposit{ + Receiver: tokenBridgeAddr, + TokenAddress: WETH_ADDRESS, + // Default token chain for a transfer. + TokenChain: NATIVE_CHAIN_ID, + Amount: big.NewInt(100), + }, + }, + } + + for name, test := range tests { + t.Run(name, func(t *testing.T) { + t.Parallel() // marks each test case as capable of running in parallel with each other + + deposit, err := DepositFromLog(&test.log, NATIVE_CHAIN_ID) + assert.Equal(t, test.expected, deposit) + require.NoError(t, err) + }) + } + +} + +func TestParseERC20TransferFrom(t *testing.T) { + + t.Parallel() + + tests := map[string]struct { + log types.Log + expected *ERC20Transfer + }{ + "valid transfer": { + log: types.Log{ + Address: usdcAddr, + Topics: []common.Hash{ + common.HexToHash(EVENTHASH_ERC20_TRANSFER), + // From + common.HexToHash(eoaAddrGeth.String()), + // To + common.HexToHash(tokenBridgeAddr.String()), + }, + TxHash: common.BytesToHash([]byte{0x01}), + Data: common.LeftPadBytes(big.NewInt(100).Bytes(), EVM_WORD_LENGTH), + }, + expected: &ERC20Transfer{ + TokenAddress: usdcAddr, + // Default token chain for a transfer. + TokenChain: NATIVE_CHAIN_ID, + From: eoaAddrGeth, + To: tokenBridgeAddr, + Amount: big.NewInt(100), + }, + }, + "valid transfer: burn action": { + log: types.Log{ + Address: usdcAddr, + Topics: []common.Hash{ + common.HexToHash(EVENTHASH_ERC20_TRANSFER), + // From + common.HexToHash(eoaAddrGeth.String()), + // To is equal to the zero-address for burn transfers + common.HexToHash(ZERO_ADDRESS.String()), + }, + TxHash: common.BytesToHash([]byte{0x01}), + Data: common.LeftPadBytes(big.NewInt(100).Bytes(), EVM_WORD_LENGTH), + }, + expected: &ERC20Transfer{ + TokenAddress: usdcAddr, + // Default token chain for a transfer. + TokenChain: NATIVE_CHAIN_ID, + From: eoaAddrGeth, + To: ZERO_ADDRESS, + Amount: big.NewInt(100), + }, + }, + } + + for name, test := range tests { + test := test // NOTE: uncomment for Go < 1.22, see /doc/faq#closures_and_goroutines + t.Run(name, func(t *testing.T) { + t.Parallel() // marks each test case as capable of running in parallel with each other + + transfer, err := ERC20TransferFromLog(&test.log, NATIVE_CHAIN_ID) + assert.Equal(t, test.expected, transfer) + require.NoError(t, err) + }) + } + + invalidTests := map[string]struct { + log types.Log + }{ + "invalid transfer: From is zero address": { + log: types.Log{ + Address: usdcAddr, + Topics: []common.Hash{ + common.HexToHash(EVENTHASH_ERC20_TRANSFER), + // From + common.HexToHash(ZERO_ADDRESS.String()), + // To + common.HexToHash(tokenBridgeAddr.String()), + }, + TxHash: common.BytesToHash([]byte{0x01}), + Data: common.LeftPadBytes(big.NewInt(100).Bytes(), EVM_WORD_LENGTH), + }, + }, + } + + for name, invalidTest := range invalidTests { + test := invalidTest // NOTE: uncomment for Go < 1.22, see /doc/faq#closures_and_goroutines + t.Run(name, func(t *testing.T) { + t.Parallel() // marks each test case as capable of running in parallel with each other + + transfer, err := ERC20TransferFromLog(&test.log, NATIVE_CHAIN_ID) + require.Error(t, err) + assert.Nil(t, transfer) + }) + } + +} diff --git a/node/pkg/txverifier/sui.go b/node/pkg/txverifier/sui.go new file mode 100644 index 0000000000..2df122b472 --- /dev/null +++ b/node/pkg/txverifier/sui.go @@ -0,0 +1,301 @@ +package txverifier + +// TODOs: +// * balances on Sui are stored as u64's. Consider using uint64 instead of big.Int + +import ( + "encoding/json" + "errors" + "fmt" + "io" + "math/big" + "net/http" + "strings" + + "github.com/wormhole-foundation/wormhole/sdk/vaa" + "go.uber.org/zap" +) + +// Global variables +var ( + suiModule = "publish_message" + suiEventName = "WormholeMessage" +) + +type SuiTransferVerifier struct { + suiCoreContract string + suiTokenBridgeEmitter string + suiTokenBridgeContract string + suiEventType string +} + +func NewSuiTransferVerifier(suiCoreContract, suiTokenBridgeEmitter, suiTokenBridgeContract string) *SuiTransferVerifier { + return &SuiTransferVerifier{ + suiCoreContract: suiCoreContract, + suiTokenBridgeEmitter: suiTokenBridgeEmitter, + suiTokenBridgeContract: suiTokenBridgeContract, + suiEventType: fmt.Sprintf("%s::%s::%s", suiCoreContract, suiModule, suiEventName), + } +} + +// func (s *SuiTransferVerifier) GetSuiEventType() string { +// return s.suiEventType +// } + +// Filter to be used for querying events +// The `MoveEventType` filter doesn't seem to be available in the documentation. However, there is an example +// showing the inclusion of `type` in the `MoveModule` filter. +// Reference: https://docs.sui.io/guides/developer/sui-101/using-events#query-events-with-rpc +func (s *SuiTransferVerifier) GetEventFilter() string { + return fmt.Sprintf(` + { + "MoveModule":{ + "package":"%s", + "module":"%s", + "type":"%s" + } + }`, s.suiCoreContract, suiModule, s.suiEventType) +} + +// processEvents takes a list of events and processes them to determine the amount requested out of the bridge. It returns a mapping +// that maps the token address and chain ID to the amount requested out of the bridge. It does not return an error, because any faulty +// events can be skipped, since they would likely fail being processed by the guardian as well. Debug level logging can be used to +// reveal any potential locations where errors are occurring. +func (s *SuiTransferVerifier) processEvents(events []SuiEvent, logger *zap.Logger) (requestedOutOfBridge map[string]*big.Int, numEventsProcessed uint) { + // Initialize the map to store the amount requested out of the bridge + requestedOutOfBridge = make(map[string]*big.Int) + + // Filter events that have the sui token bridge emitter as the sender in the message. The events indicate + // how much is going to leave the network. + for _, event := range events { + + // If any of these event parameters are nil, skip the event + if event.Message == nil || event.Message.Sender == nil || event.Type == nil { + continue + } + + // Only process the event if it is a WormholeMessage event from the token bridge emitter + if *event.Type == s.suiEventType && *event.Message.Sender == s.suiTokenBridgeEmitter { + + // Parse the wormhole message. vaa.IsTransfer can be omitted, since this is done + // inside `DecodeTransferPayloadHdr` already. + hdr, err := vaa.DecodeTransferPayloadHdr(event.Message.Payload) + + // If there is an error decoding the payload, skip the event + if err != nil { + logger.Debug("Error decoding payload", zap.Error(err)) + continue + } + + // Add the key if it does not exist yet + key := fmt.Sprintf(KEY_FORMAT, hdr.OriginAddress.String(), hdr.OriginChain) + if _, exists := requestedOutOfBridge[key]; !exists { + requestedOutOfBridge[key] = big.NewInt(0) + } + + // Add the amount requested out of the bridge + requestedOutOfBridge[key] = new(big.Int).Add(requestedOutOfBridge[key], hdr.Amount) + + numEventsProcessed++ + } else { + logger.Debug("Event does not match the criteria", zap.String("event type", *event.Type), zap.String("event sender", *event.Message.Sender)) + } + } + + return requestedOutOfBridge, numEventsProcessed +} + +func (s *SuiTransferVerifier) processObjectUpdates(objectChanges []ObjectChange, suiApiConnection SuiApiInterface, logger *zap.Logger) (transferredIntoBridge map[string]*big.Int, numChangesProcessed uint) { + transferredIntoBridge = make(map[string]*big.Int) + + for _, objectChange := range objectChanges { + // Check that the type information is correct. + if !objectChange.ValidateTypeInformation(s.suiTokenBridgeContract) { + continue + } + + // Get the past objects + resp, err := suiApiConnection.TryMultiGetPastObjects(objectChange.ObjectId, objectChange.Version, objectChange.PreviousVersion) + + if err != nil { + logger.Error("Error in getting past objects", zap.Error(err)) + continue + } + + decimals, err := resp.GetDecimals() + if err != nil { + logger.Error("Error in getting decimals", zap.Error(err)) + continue + } + + address, err := resp.GetTokenAddress() + if err != nil { + logger.Error("Error in getting token address", zap.Error(err)) + continue + } + + chain, err := resp.GetTokenChain() + if err != nil { + logger.Error("Error in getting token chain", zap.Error(err)) + continue + } + + // Get the balance difference + balanceDiff, err := resp.GetBalanceDiff() + if err != nil { + logger.Error("Error in getting balance difference", zap.Error(err)) + continue + } + + normalized := normalize(balanceDiff, decimals) + + // Add the key if it does not exist yet + key := fmt.Sprintf(KEY_FORMAT, address, chain) + + // Add the normalized amount to the transferredIntoBridge map + // Intentionally use 'Set' instead of 'Add' because there should only be a single objectChange per token + var amount big.Int + transferredIntoBridge[key] = amount.Set(normalized) + + // Increment the number of changes processed + numChangesProcessed++ + } + + return transferredIntoBridge, numChangesProcessed +} + +func (s *SuiTransferVerifier) ProcessDigest(digest string, suiApiConnection SuiApiInterface, logger *zap.Logger) (uint, error) { + // Get the transaction block + txBlock, err := suiApiConnection.GetTransactionBlock(digest) + + if err != nil { + logger.Fatal("Error in getting transaction block", zap.Error(err)) + } + + // process all events, indicating funds that are leaving the chain + requestedOutOfBridge, numEventsProcessed := s.processEvents(txBlock.Result.Events, logger) + + // process all object changes, indicating funds that are entering the chain + transferredIntoBridge, numChangesProcessed := s.processObjectUpdates(txBlock.Result.ObjectChanges, suiApiConnection, logger) + + // TODO: Using `Warn` for testing purposes. Update to Fatal? when ready to go into PR. + // TODO: Revisit error handling here. + for key, amountOut := range requestedOutOfBridge { + + if _, exists := transferredIntoBridge[key]; !exists { + logger.Warn("transfer-out request for tokens that were never deposited", + zap.String("tokenAddress", key)) + // TODO: Is it better to return or continue here? + return 0, errors.New("transfer-out request for tokens that were never deposited") + // continue + } + + amountIn := transferredIntoBridge[key] + + if amountOut.Cmp(amountIn) > 0 { + logger.Warn("requested amount out is larger than amount in") + return 0, errors.New("requested amount out is larger than amount in") + } + + keyParts := strings.Split(key, "-") + logger.Info("bridge request processed", + zap.String("tokenAddress", keyParts[0]), + zap.String("chain", keyParts[1]), + zap.String("amountOut", amountOut.String()), + zap.String("amountIn", amountIn.String())) + } + + //nolint:gosec + logger.Info("Digest processed", zap.String("txDigest", digest), zap.Uint("numEventsProcessed", numEventsProcessed), zap.Uint("numChangesProcessed", numChangesProcessed)) + + return numEventsProcessed, nil +} + +type SuiApiResponse interface { + GetError() error +} + +func suiApiRequest[T SuiApiResponse](rpc string, method string, params string) (T, error) { + var defaultT T + + // Create the request + requestBody := fmt.Sprintf(`{"jsonrpc":"2.0", "id": 1, "method": "%s", "params": %s}`, method, params) + + //nolint:noctx + req, err := http.NewRequest("POST", rpc, strings.NewReader(requestBody)) + if err != nil { + return defaultT, fmt.Errorf("cannot create request: %w", err) + } + + // Add headers + req.Header.Set("Content-Type", "application/json") + + // Send the request + client := &http.Client{} + resp, err := client.Do(req) + if err != nil { + return defaultT, fmt.Errorf("cannot send request: %w", err) + } + defer resp.Body.Close() + + // Read the response + body, err := io.ReadAll(resp.Body) + if err != nil { + return defaultT, fmt.Errorf("cannot read response: %w", err) + } + + // Parse the response + var res T + err = json.Unmarshal(body, &res) + if err != nil { + return defaultT, fmt.Errorf("cannot parse response: %w", err) + } + + // Check if an error message exists + if res.GetError() != nil { + return defaultT, fmt.Errorf("error from Sui RPC: %w", res.GetError()) + } + + return res, nil +} + +type SuiApiConnection struct { + rpc string +} + +func NewSuiApiConnection(rpc string) SuiApiInterface { + return &SuiApiConnection{rpc: rpc} +} + +func (s *SuiApiConnection) GetTransactionBlock(txDigest string) (SuiGetTransactionBlockResponse, error) { + method := "sui_getTransactionBlock" + params := fmt.Sprintf(`[ + "%s", + { + "showObjectChanges":true, + "showEvents": true + } + ]`, txDigest) + + return suiApiRequest[SuiGetTransactionBlockResponse](s.rpc, method, params) +} + +func (s *SuiApiConnection) QueryEvents(filter string, cursor string, limit int, descending bool) (SuiQueryEventsResponse, error) { + method := "suix_queryEvents" + params := fmt.Sprintf(`[%s, %s, %d, %t]`, filter, cursor, limit, descending) + + return suiApiRequest[SuiQueryEventsResponse](s.rpc, method, params) +} + +func (s *SuiApiConnection) TryMultiGetPastObjects(objectId string, version string, previousVersion string) (SuiTryMultiGetPastObjectsResponse, error) { + method := "sui_tryMultiGetPastObjects" + params := fmt.Sprintf(`[ + [ + {"objectId" : "%s", "version" : "%s"}, + {"objectId" : "%s", "version" : "%s"} + ], + {"showContent": true} + ]`, objectId, version, objectId, previousVersion) + + return suiApiRequest[SuiTryMultiGetPastObjectsResponse](s.rpc, method, params) +} diff --git a/node/pkg/txverifier/sui_test.go b/node/pkg/txverifier/sui_test.go new file mode 100644 index 0000000000..37be7d6423 --- /dev/null +++ b/node/pkg/txverifier/sui_test.go @@ -0,0 +1,1155 @@ +package txverifier + +import ( + "encoding/hex" + "encoding/json" + "fmt" + "math/big" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/wormhole-foundation/wormhole/sdk/vaa" + "go.uber.org/zap" +) + +// Tokens +const ( + EthereumUsdcAddress = "000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48" + SuiUsdcAddress = "5d4b302506645c37ff133b98c4b50a5ae14841659738d6d733d59d0d217a93bf" +) + +// func initGlobals() { +// suiEventType = fmt.Sprintf("%s::%s::%s", *suiCoreContract, suiModule, suiEventName) +// } + +func newTestSuiTransferVerifier() *SuiTransferVerifier { + suiCoreContract := "0x5306f64e312b581766351c07af79c72fcb1cd25147157fdc2f8ad76de9a3fb6a" + suiTokenBridgeContract := "0x26efee2b51c911237888e5dc6702868abca3c7ac12c53f76ef8eba0697695e3d" + suiTokenBridgeEmitter := "0xccceeb29348f71bdd22ffef43a2a19c1f5b5e17c5cca5411529120182672ade5" + + return NewSuiTransferVerifier(suiCoreContract, suiTokenBridgeEmitter, suiTokenBridgeContract) +} + +type MockSuiApiConnection struct { + // The events to be returned by QueryEvents + Events []SuiEvent + ObjectsResponses []SuiTryMultiGetPastObjectsResponse +} + +type ResultTestCase struct { + decimals uint8 + tokenChain string + tokenAddress string + wrapped bool + newBalance string + oldBalance string + drop bool +} + +func NewMockSuiApiConnection(events []SuiEvent) *MockSuiApiConnection { + return &MockSuiApiConnection{ + Events: events, + ObjectsResponses: nil, + } +} + +func (mock *MockSuiApiConnection) SetEvents(events []SuiEvent) { + mock.Events = events +} + +func (mock *MockSuiApiConnection) SetObjectsResponse(ObjectResponse SuiTryMultiGetPastObjectsResponse) { + mock.ObjectsResponses = append(mock.ObjectsResponses, ObjectResponse) +} + +func (mock *MockSuiApiConnection) QueryEvents(filter string, cursor string, limit int, descending bool) (SuiQueryEventsResponse, error) { + return SuiQueryEventsResponse{}, nil +} + +func (mock *MockSuiApiConnection) GetTransactionBlock(txDigest string) (SuiGetTransactionBlockResponse, error) { + + objectChanges := []ObjectChange{} + + // Create new nested object that unwraps some of it + for _, objectResponse := range mock.ObjectsResponses { + objectType, _ := objectResponse.GetObjectType() + objectId, _ := objectResponse.GetObjectId() + version, _ := objectResponse.GetVersion() + previousVersion, _ := objectResponse.GetPreviousVersion() + + obj := ObjectChange{ + ObjectType: objectType, + ObjectId: objectId, + Version: version, + PreviousVersion: previousVersion, + } + objectChanges = append(objectChanges, obj) + } + + return SuiGetTransactionBlockResponse{Result: SuiGetTransactionBlockResult{Events: mock.Events, ObjectChanges: objectChanges}}, nil +} +func (mock *MockSuiApiConnection) TryMultiGetPastObjects(objectId string, version string, previousVersion string) (SuiTryMultiGetPastObjectsResponse, error) { + + for _, response := range mock.ObjectsResponses { + keyIn := fmt.Sprintf("%s-%s-%s", objectId, version, previousVersion) + objectId, err0 := response.GetObjectId() + version, err1 := response.GetVersion() + previousVersion, err2 := response.GetPreviousVersion() + if err0 != nil || err1 != nil || err2 != nil { + return SuiTryMultiGetPastObjectsResponse{}, fmt.Errorf("Error processing version data") + } + + keyCur := fmt.Sprintf("%s-%s-%s", objectId, version, previousVersion) + if keyIn == keyCur { + return response, nil + } + } + + return SuiTryMultiGetPastObjectsResponse{}, fmt.Errorf("Can't find entry") +} + +func TestNewSuiApiConnection(t *testing.T) { + sampleUrl := "http://localhost:8080" + + api := NewSuiApiConnection(sampleUrl) + if rpc, ok := api.(*SuiApiConnection); ok { + assert.Equal(t, sampleUrl, rpc.rpc) + } else { + t.Errorf("Unable to get RPC from SuiApiConnection") + } +} + +func TestProcessEvents(t *testing.T) { + suiTxVerifier := newTestSuiTransferVerifier() + + arbitraryEventType := "arbitrary::EventType" + arbitraryEmitter := "0x3117" + + logger := zap.NewNop() + + // Constants used throughout the tests + suiEventType := suiTxVerifier.suiEventType + suiTokenBridgeEmitter := suiTxVerifier.suiTokenBridgeEmitter + + // Define test cases + tests := []struct { + name string + events []SuiEvent + expectedResult map[string]*big.Int + expectedCount uint + }{ + { + name: "TestNoEvents", + events: []SuiEvent{}, + expectedResult: map[string]*big.Int{}, + expectedCount: 0, + }, + { + name: "TestSingleEthereumUSDCEvent", + events: []SuiEvent{ + { + Type: &suiEventType, + Message: &WormholeMessage{ + Sender: &suiTokenBridgeEmitter, + Payload: generatePayload(1, big.NewInt(100), EthereumUsdcAddress, 2), + }, + }, + }, + expectedResult: map[string]*big.Int{ + fmt.Sprintf(KEY_FORMAT, EthereumUsdcAddress, vaa.ChainIDEthereum): big.NewInt(100), + }, + expectedCount: 1, + }, + { + name: "TestMultipleEthereumUSDCEvents", + events: []SuiEvent{ + { + Type: &suiEventType, + Message: &WormholeMessage{ + Sender: &suiTokenBridgeEmitter, + Payload: generatePayload(1, big.NewInt(100), EthereumUsdcAddress, uint16(vaa.ChainIDEthereum)), + }, + }, + { + Type: &suiEventType, + Message: &WormholeMessage{ + Sender: &suiTokenBridgeEmitter, + Payload: generatePayload(1, big.NewInt(100), EthereumUsdcAddress, uint16(vaa.ChainIDEthereum)), + }, + }, + }, + expectedResult: map[string]*big.Int{ + fmt.Sprintf(KEY_FORMAT, EthereumUsdcAddress, vaa.ChainIDEthereum): big.NewInt(200), + }, + expectedCount: 2, + }, + { + name: "TestMixedEthereumAndSuiUSDCEvents", + events: []SuiEvent{ + { + Type: &suiEventType, + Message: &WormholeMessage{ + Sender: &suiTokenBridgeEmitter, + Payload: generatePayload(1, big.NewInt(100), EthereumUsdcAddress, uint16(vaa.ChainIDEthereum)), + }, + }, + { + Type: &suiEventType, + Message: &WormholeMessage{ + Sender: &suiTokenBridgeEmitter, + Payload: generatePayload(1, big.NewInt(100), SuiUsdcAddress, uint16(vaa.ChainIDSui)), + }, + }, + }, + expectedResult: map[string]*big.Int{ + fmt.Sprintf(KEY_FORMAT, EthereumUsdcAddress, vaa.ChainIDEthereum): big.NewInt(100), + fmt.Sprintf(KEY_FORMAT, SuiUsdcAddress, vaa.ChainIDSui): big.NewInt(100), + }, + expectedCount: 2, + }, + { + name: "TestIncorrectSender", + events: []SuiEvent{ + { + Type: &suiEventType, + Message: &WormholeMessage{ + Sender: &arbitraryEmitter, + Payload: generatePayload(1, big.NewInt(100), EthereumUsdcAddress, uint16(vaa.ChainIDEthereum)), + }, + }, + }, + expectedResult: map[string]*big.Int{}, + expectedCount: 0, + }, + { + name: "TestSkipNonWormholeEvents", + events: []SuiEvent{ + { + Type: &suiEventType, + Message: &WormholeMessage{ + Sender: &suiTokenBridgeEmitter, + Payload: generatePayload(1, big.NewInt(100), EthereumUsdcAddress, uint16(vaa.ChainIDEthereum)), + }, + }, + { + Type: &arbitraryEventType, + Message: &WormholeMessage{ + Sender: &suiTokenBridgeEmitter, + Payload: generatePayload(1, big.NewInt(100), SuiUsdcAddress, uint16(vaa.ChainIDSui)), + }, + }, + }, + expectedResult: map[string]*big.Int{ + fmt.Sprintf(KEY_FORMAT, EthereumUsdcAddress, vaa.ChainIDEthereum): big.NewInt(100), + }, + expectedCount: 1, + }, + { + name: "TestInvalidWormholePayloads", + events: []SuiEvent{ + { // Invalid payload type + Type: &suiEventType, + Message: &WormholeMessage{ + Sender: &suiTokenBridgeEmitter, + Payload: generatePayload(0, big.NewInt(100), EthereumUsdcAddress, uint16(vaa.ChainIDEthereum)), + }, + }, + { // Empty payload + Type: &suiEventType, + Message: &WormholeMessage{ + Sender: &suiTokenBridgeEmitter, + Payload: []byte{}, + }, + }, + }, + expectedResult: map[string]*big.Int{}, + expectedCount: 0, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + + result, count := suiTxVerifier.processEvents(tt.events, logger) + + assert.Equal(t, tt.expectedResult, result) + assert.Equal(t, tt.expectedCount, count) + }) + } +} + +func TestProcessObjectUpdates(t *testing.T) { + suiTxVerifier := newTestSuiTransferVerifier() + + logger := zap.NewNop() // zap.Must(zap.NewDevelopment()) + + // Constants used throughout the tests + normalObjectNativeType := "0x2::dynamic_field::Field<0x26efee2b51c911237888e5dc6702868abca3c7ac12c53f76ef8eba0697695e3d::token_registry::Key<0x2::sui::SUI>, 0x26efee2b51c911237888e5dc6702868abca3c7ac12c53f76ef8eba0697695e3d::native_asset::NativeAsset<0x2::sui::SUI>>" + normalObjectForeignType := "0x2::dynamic_field::Field<0x26efee2b51c911237888e5dc6702868abca3c7ac12c53f76ef8eba0697695e3d::token_registry::Key<0x5d4b302506645c37ff133b98c4b50a5ae14841659738d6d733d59d0d217a93bf::coin::COIN>, 0x26efee2b51c911237888e5dc6702868abca3c7ac12c53f76ef8eba0697695e3d::wrapped_asset::WrappedAsset<0x5d4b302506645c37ff133b98c4b50a5ae14841659738d6d733d59d0d217a93bf::coin::COIN>>" + normalVersion := "6565" + normalPreviousVersion := "4040" + normalObjectNativeId := "0x831c45a8d512c9cf46e7a8a947f7cbbb5e0a59829aa72450ff26fb1873fd0e94" + normalObjectForeignId := "0xf8f80c0d569fb076adb5fdc3a717dcb9ac14f7fd7512dc17efbf0f80a8b7fa8a" + + normalTokenAddressForeign := "0,0,0,0,0,0,0,0,0,0,0,0,160,184,105,145,198,33,139,54,193,209,157,74,46,158,176,206,54,6,235,72" + normalTokenAddressNative := "146,88,24,31,92,234,200,219,255,183,3,8,144,36,60,174,214,154,149,153,210,136,109,149,122,156,183,101,106,243,189,179" + normalChainIdNative := "21" + normalChainIdForeign := "2" + + oneToken := new(big.Int) + oneToken.SetString("1000000000000000000", 10) + + // Decimals, token chain, token address, wrapped or not, balance/custody + tests := []struct { + name string + objectChanges []ObjectChange + resultList []ResultTestCase + expectedResult map[string]*big.Int + expectedCount uint + }{ + { + name: "TestProcessObjectNativeBase", + objectChanges: []ObjectChange{ + { + ObjectType: normalObjectNativeType, + Version: normalVersion, + PreviousVersion: normalPreviousVersion, + ObjectId: normalObjectNativeId, + }, + }, + resultList: []ResultTestCase{ + { + tokenChain: normalChainIdNative, + tokenAddress: normalTokenAddressNative, + wrapped: false, + newBalance: "1000", + oldBalance: "10", + decimals: 8, + }, + }, + expectedResult: map[string]*big.Int{"9258181f5ceac8dbffb7030890243caed69a9599d2886d957a9cb7656af3bdb3-21": big.NewInt(990)}, + expectedCount: 1, + }, + { + name: "TestProcessObjectForeignBase", + objectChanges: []ObjectChange{ + { + ObjectType: normalObjectForeignType, + Version: normalVersion, + PreviousVersion: normalPreviousVersion, + ObjectId: normalObjectForeignId, + }, + }, + resultList: []ResultTestCase{ + { + tokenChain: normalChainIdForeign, + tokenAddress: normalTokenAddressForeign, + wrapped: true, + newBalance: "10", + oldBalance: "1000", + decimals: 8, + }, + }, + expectedResult: map[string]*big.Int{"000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48-2": big.NewInt(990)}, + expectedCount: 1, + }, + { + name: "TestProcessObjectNativeNegative", + objectChanges: []ObjectChange{ + { + ObjectType: normalObjectNativeType, + Version: normalVersion, + PreviousVersion: normalPreviousVersion, + ObjectId: normalObjectNativeId, + }, + }, + resultList: []ResultTestCase{ + { + tokenChain: normalChainIdNative, + tokenAddress: normalTokenAddressNative, + wrapped: false, + newBalance: "10", + oldBalance: "1000", + decimals: 8, + }, + }, + expectedResult: map[string]*big.Int{"9258181f5ceac8dbffb7030890243caed69a9599d2886d957a9cb7656af3bdb3-21": big.NewInt(-990)}, + expectedCount: 1, + }, + { + name: "TestProcessObjectForeignNegative", // Unsure if this test case is possible from Sui API + objectChanges: []ObjectChange{ + { + ObjectType: normalObjectForeignType, + Version: normalVersion, + PreviousVersion: normalPreviousVersion, + ObjectId: normalObjectForeignId, + }, + }, + resultList: []ResultTestCase{ + { + tokenChain: normalChainIdForeign, + tokenAddress: normalTokenAddressForeign, + wrapped: true, + newBalance: "1000", + oldBalance: "10", + decimals: 8, + }, + }, + expectedResult: map[string]*big.Int{"000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48-2": big.NewInt(-990)}, + expectedCount: 1, + }, + { + name: "TestProcessObjectNativeMultiple", + objectChanges: []ObjectChange{ + { + ObjectType: normalObjectNativeType, + Version: normalVersion, + PreviousVersion: normalPreviousVersion, + ObjectId: normalObjectNativeId, + }, + { + ObjectType: "0x2::dynamic_field::Field<0x26efee2b51c911237888e5dc6702868abca3c7ac12c53f76ef8eba0697695e3d::token_registry::Key<0xb779486cfd6c19e9218cc7dc17c453014d2d9ba12d2ee4dbb0ec4e1e02ae1cca::spt::SPT>, 0x26efee2b51c911237888e5dc6702868abca3c7ac12c53f76ef8eba0697695e3d::native_asset::NativeAsset<0xb779486cfd6c19e9218cc7dc17c453014d2d9ba12d2ee4dbb0ec4e1e02ae1cca::spt::SPT>>", + Version: normalVersion, + PreviousVersion: normalPreviousVersion, + ObjectId: "0x0063d37cdce648a7c6f72f69a75a114fbcc81ef23300e4ace60c7941521163db", + }, + }, + resultList: []ResultTestCase{ + { + tokenChain: normalChainIdNative, + tokenAddress: normalTokenAddressNative, + wrapped: false, + newBalance: "1000", + oldBalance: "10", + decimals: 8, + }, + { + tokenChain: normalChainIdNative, + tokenAddress: "80,117,89,76,1,212,111,59,203,196,167,239,20,98,5,130,115,190,206,119,147,238,189,4,100,150,53,151,201,253,9,53", + wrapped: false, + newBalance: "5000", + oldBalance: "50", + decimals: 8, + }, + }, + expectedResult: map[string]*big.Int{"9258181f5ceac8dbffb7030890243caed69a9599d2886d957a9cb7656af3bdb3-21": big.NewInt(990), "5075594c01d46f3bcbc4a7ef1462058273bece7793eebd0464963597c9fd0935-21": big.NewInt(4950)}, + expectedCount: 2, + }, + { + name: "TestProcessObjectNativeAndForeign", + objectChanges: []ObjectChange{ + { + ObjectType: normalObjectNativeType, + Version: normalVersion, + PreviousVersion: normalPreviousVersion, + ObjectId: normalObjectNativeId, + }, + { + ObjectType: normalObjectForeignType, + Version: normalVersion, + PreviousVersion: normalPreviousVersion, + ObjectId: normalObjectForeignId, + }, + }, + resultList: []ResultTestCase{ + { + tokenChain: normalChainIdNative, + tokenAddress: normalTokenAddressNative, + wrapped: false, + newBalance: "1000", + oldBalance: "10", + decimals: 8, + }, + { + tokenChain: normalChainIdForeign, + tokenAddress: normalTokenAddressForeign, + wrapped: true, + newBalance: "50", + oldBalance: "5000", + decimals: 8, + }, + }, + expectedResult: map[string]*big.Int{"9258181f5ceac8dbffb7030890243caed69a9599d2886d957a9cb7656af3bdb3-21": big.NewInt(990), "000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48-2": big.NewInt(4950)}, + expectedCount: 2, + }, + { + name: "TestProcessObjectWrongPackageIdType", + objectChanges: []ObjectChange{ + { + ObjectType: "0x2::dynamic_field::Field<0xa340e3db1332c21f20f5c08bef0fa459e733575f9a7e2f5faca64f72cd5a54f2::token_registry::Key<0x2::sui::SUI>, 0xa340e3db1332c21f20f5c08bef0fa459e733575f9a7e2f5faca64f72cd5a54f2::native_asset::NativeAsset<0x2::sui::SUI>", + Version: normalVersion, + PreviousVersion: normalPreviousVersion, + ObjectId: normalObjectNativeId, + }, + }, + resultList: []ResultTestCase{ + { + tokenChain: normalChainIdNative, + tokenAddress: normalTokenAddressNative, + wrapped: false, + newBalance: "1000", + oldBalance: "10", + decimals: 8, + }, + }, + expectedResult: map[string]*big.Int{}, + expectedCount: 0, + }, + { + name: "TestProcessObjectNotDynamicField", + objectChanges: []ObjectChange{ + { + ObjectType: "0x11111111111111111111::dynamic_field::Field<0x26efee2b51c911237888e5dc6702868abca3c7ac12c53f76ef8eba0697695e3d::token_registry::Key<0x2::sui::SUI>, 0x26efee2b51c911237888e5dc6702868abca3c7ac12c53f76ef8eba0697695e3d::native_asset::NativeAsset<0x2::sui::SUI>", + Version: normalVersion, + PreviousVersion: normalPreviousVersion, + ObjectId: normalObjectNativeId, + }, + }, + resultList: []ResultTestCase{ + { + tokenChain: normalChainIdNative, + tokenAddress: normalTokenAddressNative, + wrapped: false, + newBalance: "1000", + oldBalance: "10", + decimals: 8, + }, + }, + expectedResult: map[string]*big.Int{}, + expectedCount: 0, + }, + { + name: "TestProcessObjectMismatchedCoinTypes", + objectChanges: []ObjectChange{ + { + ObjectType: "0x2::dynamic_field::Field<0x26efee2b51c911237888e5dc6702868abca3c7ac12c53f76ef8eba0697695e3d::token_registry::Key<0x2::sui::SUI>, 0x26efee2b51c911237888e5dc6702868abca3c7ac12c53f76ef8eba0697695e3d::native_asset::NativeAsset<0x11111111111111111111::sui::SUI>", + Version: normalVersion, + PreviousVersion: normalPreviousVersion, + ObjectId: normalObjectNativeId, + }, + }, + resultList: []ResultTestCase{ + { + tokenChain: normalChainIdNative, + tokenAddress: normalTokenAddressNative, + wrapped: false, + newBalance: "1000", + oldBalance: "10", + decimals: 8, + }, + }, + expectedResult: map[string]*big.Int{}, + expectedCount: 0, + }, + { + name: "TestProcessObjectNotAssetType", + objectChanges: []ObjectChange{ + { + ObjectType: "0x2::dynamic_field::Field<0x26efee2b51c911237888e5dc6702868abca3c7ac12c53f76ef8eba0697695e3d::token_registry::Key<0x2::sui::SUI>, 0x26efee2b51c911237888e5dc6702868abca3c7ac12c53f76ef8eba0697695e3d::not_native_asset::NativeAsset<0x2::sui::SUI>", + Version: normalVersion, + PreviousVersion: normalPreviousVersion, + ObjectId: normalObjectNativeId, + }, + }, + resultList: []ResultTestCase{ + { + tokenChain: normalChainIdNative, + tokenAddress: normalTokenAddressNative, + wrapped: false, + newBalance: "1000", + oldBalance: "10", + decimals: 8, + }, + }, + expectedResult: map[string]*big.Int{}, + expectedCount: 0, + }, + { + name: "TestProcessObjectOneGoodOneBad", + objectChanges: []ObjectChange{ + { + ObjectType: normalObjectForeignType, + Version: normalVersion, + PreviousVersion: normalPreviousVersion, + ObjectId: normalObjectForeignId, + }, + { + ObjectType: "0x2::dynamic_field::Field<0x26efee2b51c911237888e5dc6702868abca3c7ac12c53f76ef8eba0697695e3d::token_registry::Key<0x2::sui::SUI>, 0x26efee2b51c911237888e5dc6702868abca3c7ac12c53f76ef8eba0697695e3d::not_native_asset::NativeAsset<0x2::sui::SUI>", + Version: fmt.Sprintf("%s111", normalVersion), + PreviousVersion: normalPreviousVersion, + ObjectId: normalObjectNativeId, + }, + }, + resultList: []ResultTestCase{ + { + tokenChain: normalChainIdForeign, + tokenAddress: normalTokenAddressForeign, + wrapped: true, + newBalance: "10", + oldBalance: "1000", + decimals: 8, + }, + { + tokenChain: normalChainIdNative, + tokenAddress: normalTokenAddressNative, + wrapped: false, + newBalance: "1000", + oldBalance: "10", + decimals: 8, + }, + }, + expectedResult: map[string]*big.Int{"000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48-2": big.NewInt(990)}, + expectedCount: 1, + }, + { + name: "TestProcessObjectRealNumbers", + objectChanges: []ObjectChange{ + { + ObjectType: normalObjectNativeType, + Version: normalVersion, + PreviousVersion: normalPreviousVersion, + ObjectId: normalObjectNativeId, + }, + }, + resultList: []ResultTestCase{ + { + tokenChain: normalChainIdNative, + tokenAddress: normalTokenAddressNative, + wrapped: false, + newBalance: "1000000000000000", + oldBalance: "999999000000000", + decimals: 8, + }, + }, + expectedResult: map[string]*big.Int{"9258181f5ceac8dbffb7030890243caed69a9599d2886d957a9cb7656af3bdb3-21": big.NewInt(1000000000)}, + expectedCount: 1, + }, + { + name: "TestProcessObjectNormalize", + objectChanges: []ObjectChange{ + { + ObjectType: normalObjectNativeType, + Version: normalVersion, + PreviousVersion: normalPreviousVersion, + ObjectId: normalObjectNativeId, + }, + }, + resultList: []ResultTestCase{ + { + tokenChain: normalChainIdNative, + tokenAddress: normalTokenAddressNative, + wrapped: false, + newBalance: "101000000000000000000", + oldBalance: "100000000000000000000", + decimals: 18, + }, + }, + expectedResult: map[string]*big.Int{"9258181f5ceac8dbffb7030890243caed69a9599d2886d957a9cb7656af3bdb3-21": big.NewInt(100000000)}, + expectedCount: 1, + }, + { + name: "TestProcessObjectMissingVersion", + objectChanges: []ObjectChange{ + { + ObjectType: normalObjectNativeType, + Version: normalVersion, + PreviousVersion: normalPreviousVersion, + ObjectId: normalObjectNativeId, + }, + }, + resultList: []ResultTestCase{ + { + tokenChain: normalChainIdNative, + tokenAddress: normalTokenAddressNative, + wrapped: false, + newBalance: "1000", + oldBalance: "10", + decimals: 8, + drop: true, + }, + }, + expectedResult: map[string]*big.Int{}, + expectedCount: 0, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + connection := NewMockSuiApiConnection([]SuiEvent{}) + + assert.Equal(t, len(tt.objectChanges), len(tt.resultList)) + + // Add all changes to the mock Sui API for future lookups + for index := 0; index < len(tt.objectChanges); index++ { + change := tt.objectChanges[index] + queryResult := tt.resultList[index] + + if !queryResult.drop { + responseObject := generateResponsesObject(change.ObjectId, change.Version, change.ObjectType, change.PreviousVersion, queryResult.newBalance, queryResult.oldBalance, queryResult.tokenAddress, queryResult.tokenChain, queryResult.decimals, queryResult.wrapped) + connection.SetObjectsResponse(responseObject) + } + } + + // Run function and check results + transferredIntoBridge, numEventsProcessed := suiTxVerifier.processObjectUpdates(tt.objectChanges, connection, logger) + assert.Equal(t, tt.expectedResult, transferredIntoBridge) + assert.Equal(t, tt.expectedCount, numEventsProcessed) + }) + } +} + +// TODO +func TestProcessDigest(t *testing.T) { + suiTxVerifier := newTestSuiTransferVerifier() + + // Constants used throughout the tests + normalObjectNativeType := "0x2::dynamic_field::Field<0x26efee2b51c911237888e5dc6702868abca3c7ac12c53f76ef8eba0697695e3d::token_registry::Key<0x2::sui::SUI>, 0x26efee2b51c911237888e5dc6702868abca3c7ac12c53f76ef8eba0697695e3d::native_asset::NativeAsset<0x2::sui::SUI>>" + normalObjectForeignType := "0x2::dynamic_field::Field<0x26efee2b51c911237888e5dc6702868abca3c7ac12c53f76ef8eba0697695e3d::token_registry::Key<0x5d4b302506645c37ff133b98c4b50a5ae14841659738d6d733d59d0d217a93bf::coin::COIN>, 0x26efee2b51c911237888e5dc6702868abca3c7ac12c53f76ef8eba0697695e3d::wrapped_asset::WrappedAsset<0x5d4b302506645c37ff133b98c4b50a5ae14841659738d6d733d59d0d217a93bf::coin::COIN>>" + normalVersion := "6565" + normalPreviousVersion := "4040" + normalObjectNativeId := "0x831c45a8d512c9cf46e7a8a947f7cbbb5e0a59829aa72450ff26fb1873fd0e94" + normalObjectForeignId := "0xf8f80c0d569fb076adb5fdc3a717dcb9ac14f7fd7512dc17efbf0f80a8b7fa8a" + + normalTokenAddressForeign := "0,0,0,0,0,0,0,0,0,0,0,0,160,184,105,145,198,33,139,54,193,209,157,74,46,158,176,206,54,6,235,72" + normalTokenAddressNative := "93,75,48,37,6,100,92,55,255,19,59,152,196,181,10,90,225,72,65,101,151,56,214,215,51,213,157,13,33,122,147,191" + normalChainIdNative := "21" + normalChainIdForeign := "2" + + suiEventType := suiTxVerifier.suiEventType + suiTokenBridgeEmitter := suiTxVerifier.suiTokenBridgeEmitter + + logger := zap.Must(zap.NewDevelopment()) + + // func processDigest(digest string, suiApiConnection SuiApiInterface, logger *zap.Logger) error { + // Needs BOTH events and ObjectChange information to be updated + tests := []struct { + name string + objectChanges []ObjectChange + resultList []ResultTestCase + suiEvents []SuiEvent + expectedError string + expectedCount uint + }{ + { + name: "TestProcessDigestNativeBase", + objectChanges: []ObjectChange{ + { + ObjectType: normalObjectNativeType, + Version: normalVersion, + PreviousVersion: normalPreviousVersion, + ObjectId: normalObjectNativeId, + }, + }, + resultList: []ResultTestCase{ + { + tokenChain: normalChainIdNative, + tokenAddress: normalTokenAddressNative, + wrapped: false, + newBalance: "1000", + oldBalance: "10", + decimals: 8, + }, + }, + suiEvents: []SuiEvent{ + { + Type: &suiEventType, + Message: &WormholeMessage{ + Sender: &suiTokenBridgeEmitter, + Payload: generatePayload(1, big.NewInt(990), SuiUsdcAddress, uint16(vaa.ChainIDSui)), + }, + }, + }, + expectedError: "", + expectedCount: 1, + }, + { + name: "TestProcessDigestTakingMoreThanPuttingIn", + objectChanges: []ObjectChange{ + { + ObjectType: normalObjectNativeType, + Version: normalVersion, + PreviousVersion: normalPreviousVersion, + ObjectId: normalObjectNativeId, + }, + }, + resultList: []ResultTestCase{ + { + tokenChain: normalChainIdNative, + tokenAddress: normalTokenAddressNative, + wrapped: false, + newBalance: "100000", + oldBalance: "100000", + decimals: 8, + }, + }, + suiEvents: []SuiEvent{ + { + Type: &suiEventType, + Message: &WormholeMessage{ + Sender: &suiTokenBridgeEmitter, + Payload: generatePayload(1, big.NewInt(100000), SuiUsdcAddress, uint16(vaa.ChainIDSui)), + }, + }, + }, + expectedError: "requested amount out is larger than amount in", + expectedCount: 0, + }, + { + name: "TestProcessDigestNoEvents", + objectChanges: []ObjectChange{}, + resultList: []ResultTestCase{}, + suiEvents: []SuiEvent{ + { + Type: &suiEventType, + Message: &WormholeMessage{ + Sender: &suiTokenBridgeEmitter, + Payload: generatePayload(1, big.NewInt(100000), SuiUsdcAddress, uint16(vaa.ChainIDSui)), + }, + }, + }, + expectedError: "transfer-out request for tokens that were never deposited", + expectedCount: 0, + }, + { + name: "TestProcessDigestForeignBase", + objectChanges: []ObjectChange{ + { + ObjectType: normalObjectForeignType, + Version: normalVersion, + PreviousVersion: normalPreviousVersion, + ObjectId: normalObjectForeignId, + }, + }, + resultList: []ResultTestCase{ + { + tokenChain: normalChainIdForeign, + tokenAddress: normalTokenAddressForeign, + wrapped: true, + newBalance: "10", + oldBalance: "1000", + decimals: 8, + }, + }, + suiEvents: []SuiEvent{ + { + Type: &suiEventType, + Message: &WormholeMessage{ + Sender: &suiTokenBridgeEmitter, + Payload: generatePayload(1, big.NewInt(990), EthereumUsdcAddress, uint16(vaa.ChainIDEthereum)), + }, + }, + }, + expectedError: "", + expectedCount: 1, + }, + { + name: "TestProcessDigestNoEvents", + objectChanges: []ObjectChange{}, + resultList: []ResultTestCase{}, + suiEvents: []SuiEvent{ + { + Type: &suiEventType, + Message: &WormholeMessage{ + Sender: &suiTokenBridgeEmitter, + Payload: generatePayload(1, big.NewInt(100000), SuiUsdcAddress, uint16(vaa.ChainIDSui)), + }, + }, + }, + expectedError: "transfer-out request for tokens that were never deposited", + expectedCount: 0, + }, + { + name: "TestProcessDigestMultipleEvents", + objectChanges: []ObjectChange{ + { + ObjectType: normalObjectForeignType, + Version: normalVersion, + PreviousVersion: normalPreviousVersion, + ObjectId: normalObjectForeignId, + }, + }, + resultList: []ResultTestCase{ + { + tokenChain: normalChainIdForeign, + tokenAddress: normalTokenAddressForeign, + wrapped: true, + newBalance: "10", + oldBalance: "2000", + decimals: 8, + }, + }, + suiEvents: []SuiEvent{ + { + Type: &suiEventType, + Message: &WormholeMessage{ + Sender: &suiTokenBridgeEmitter, + Payload: generatePayload(1, big.NewInt(990), EthereumUsdcAddress, uint16(vaa.ChainIDEthereum)), + }, + }, + { + Type: &suiEventType, + Message: &WormholeMessage{ + Sender: &suiTokenBridgeEmitter, + Payload: generatePayload(1, big.NewInt(1000), EthereumUsdcAddress, uint16(vaa.ChainIDEthereum)), + }, + }, + }, + expectedError: "", + expectedCount: 2, + }, + { + name: "TestProcessDigestMultipleEventsOverWithdraw", + objectChanges: []ObjectChange{ + { + ObjectType: normalObjectForeignType, + Version: normalVersion, + PreviousVersion: normalPreviousVersion, + ObjectId: normalObjectForeignId, + }, + }, + resultList: []ResultTestCase{ + { + tokenChain: normalChainIdForeign, + tokenAddress: normalTokenAddressForeign, + wrapped: true, + newBalance: "10", + oldBalance: "2000", + decimals: 8, + }, + }, + suiEvents: []SuiEvent{ + { + Type: &suiEventType, + Message: &WormholeMessage{ + Sender: &suiTokenBridgeEmitter, + Payload: generatePayload(1, big.NewInt(990), EthereumUsdcAddress, uint16(vaa.ChainIDEthereum)), + }, + }, + { + Type: &suiEventType, + Message: &WormholeMessage{ + Sender: &suiTokenBridgeEmitter, + Payload: generatePayload(1, big.NewInt(1001), EthereumUsdcAddress, uint16(vaa.ChainIDEthereum)), + }, + }, + }, + expectedError: "requested amount out is larger than amount in", + expectedCount: 0, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + + assert.Equal(t, len(tt.objectChanges), len(tt.resultList)) + connection := NewMockSuiApiConnection(tt.suiEvents) // Set events for connection + + // Add Object Response data for Sui connections + for index := 0; index < len(tt.objectChanges); index++ { + change := tt.objectChanges[index] + queryResult := tt.resultList[index] + + responseObject := generateResponsesObject(change.ObjectId, change.Version, change.ObjectType, change.PreviousVersion, queryResult.newBalance, queryResult.oldBalance, queryResult.tokenAddress, queryResult.tokenChain, queryResult.decimals, queryResult.wrapped) + + connection.SetObjectsResponse(responseObject) + } + + numProcessed, err := suiTxVerifier.ProcessDigest("HASH", connection, logger) + + assert.Equal(t, true, tt.expectedError == "" && err == nil || err != nil && err.Error() == tt.expectedError) + assert.Equal(t, tt.expectedCount, numProcessed) + }) + } +} + +// Generate WormholeMessage payload. +// +// Payload type: payload[0] +// Amount: payload[1] for 32 +// Origin address: payload[33] for 32 +// Origin chain ID: payload[65] for 2 +func generatePayload(payloadType byte, amount *big.Int, originAddressHex string, originChainID uint16) []byte { + originAddress, _ := hex.DecodeString(originAddressHex) + + payload := make([]byte, 0, 101) + + // Append payload type + payload = append(payload, payloadType) + + // Append amount (32 bytes) + amountBytes := amount.FillBytes(make([]byte, 32)) + payload = append(payload, amountBytes...) + + // Append origin address (32 bytes) + payload = append(payload, originAddress...) + + // Append origin chain ID (2 bytes) + originChainIDBytes := []byte{byte(originChainID >> 8), byte(originChainID & 0xff)} + payload = append(payload, originChainIDBytes...) + + // Right-pad the payload to 101 bytes + padding := make([]byte, 101-len(payload)) + payload = append(payload, padding...) + + return payload +} + +/* +JSON data + +Decimals, token chain, token address, wrapped or not, balance/custody +*/ + +func generateResponsesObject(objectId string, version string, objectType string, previousVersion string, balanceAfter string, balanceBefore string, tokenAddress string, tokenChain string, decimals uint8, isWrapped bool) SuiTryMultiGetPastObjectsResponse { + + var newVersion string + var oldVersion string + + if isWrapped == false { + newVersion = generateResponseObjectNative(objectId, version, objectType, balanceAfter, tokenAddress, decimals) + oldVersion = generateResponseObjectNative(objectId, previousVersion, objectType, balanceBefore, tokenAddress, decimals) + } else { + newVersion = generateResponseObjectForeign(objectId, version, objectType, balanceAfter, tokenAddress, tokenChain, decimals) + oldVersion = generateResponseObjectForeign(objectId, previousVersion, objectType, balanceBefore, tokenAddress, tokenChain, decimals) + } + + // Complete the rest of the response data + responseString := fmt.Sprintf(`{"result": [{"details" : %s}, {"details" : %s}]}`, newVersion, oldVersion) + + data := SuiTryMultiGetPastObjectsResponse{} + err := json.Unmarshal([]byte(responseString), &data) + if err != nil { + fmt.Println("Error in JSON parsing...") + } + + return data +} + +func generateResponseObjectNative(objectId string, version string, objectType string, balance string, tokenAddress string, decimals uint8) string { + json_string_per_object := fmt.Sprintf(`{ + "objectId": "%s", + "version": "%s", + "digest": "4ne8fjG16hAXP8GxuXzoA5hBwuHz6C4D7cyf4TZza4Pa", + "type": "%s", + "owner": { + "ObjectOwner": "0x334881831bd89287554a6121087e498fa023ce52c037001b53a4563a00a281a5" + }, + "previousTransaction": "FRx1iHA3Wq2ybDe3hhMSkS5yqsKJ4wUDUWY3Xp8K6g18", + "storageRebate": "3146400", + "content": { + "type": "%s", + "fields": { + "id": { + "id": "0x831c45a8d512c9cf46e7a8a947f7cbbb5e0a59829aa72450ff26fb1873fd0e94" + }, + "name": { + "type": "0x26efee2b51c911237888e5dc6702868abca3c7ac12c53f76ef8eba0697695e3d::token_registry::Key<0x2::sui::SUI>", + "fields": { + "dummy_field": false + } + }, + "value": { + "type": "0x26efee2b51c911237888e5dc6702868abca3c7ac12c53f76ef8eba0697695e3d::native_asset::NativeAsset<0x2::sui::SUI>", + "fields": { + "custody": "%s", + "decimals": %d, + "token_address": { + "type": "0x5306f64e312b581766351c07af79c72fcb1cd25147157fdc2f8ad76de9a3fb6a::external_address::ExternalAddress", + "fields": { + "value": { + "type": "0x5306f64e312b581766351c07af79c72fcb1cd25147157fdc2f8ad76de9a3fb6a::bytes32::Bytes32", + "fields": { + "data": [ + %s + ] + } + } + } + } + } + } + }}}`, objectId, version, objectType, objectType, balance, decimals, tokenAddress) + + return json_string_per_object +} + +func generateResponseObjectForeign(objectId string, version string, objectType string, balance string, tokenAddress string, tokenChain string, decimals uint8) string { + json_string_per_object := fmt.Sprintf(`{ + "objectId": "%s", + "version": "%s", + "digest": "CWXv7KJrNawMqREtVYCRT9PVF2H8cogW1WCLMd5iQchr", + "type": "%s", + "owner": { + "ObjectOwner": "0x334881831bd89287554a6121087e498fa023ce52c037001b53a4563a00a281a5" + }, + "previousTransaction": "EaqLzHQTeiPq2FjYCRobDH5E91DAVZgKgZzwQUJ5FaNU", + "storageRebate": "4050800", + "content": { + "dataType": "moveObject", + "type": "%s", + "hasPublicTransfer": false, + "fields": { + "id": { + "id": "0xf8f80c0d569fb076adb5fdc3a717dcb9ac14f7fd7512dc17efbf0f80a8b7fa8a" + }, + "name": { + "type": "0x26efee2b51c911237888e5dc6702868abca3c7ac12c53f76ef8eba0697695e3d::token_registry::Key<0x5d4b302506645c37ff133b98c4b50a5ae14841659738d6d733d59d0d217a93bf::coin::COIN>", + "fields": { + "dummy_field": false + } + }, + "value": { + "type": "0x26efee2b51c911237888e5dc6702868abca3c7ac12c53f76ef8eba0697695e3d::wrapped_asset::WrappedAsset<0x5d4b302506645c37ff133b98c4b50a5ae14841659738d6d733d59d0d217a93bf::coin::COIN>", + "fields": { + "decimals": 6, + "info": { + "type": "0x26efee2b51c911237888e5dc6702868abca3c7ac12c53f76ef8eba0697695e3d::wrapped_asset::ForeignInfo<0x5d4b302506645c37ff133b98c4b50a5ae14841659738d6d733d59d0d217a93bf::coin::COIN>", + "fields": { + "native_decimals": %d, + "symbol": "USDC", + "token_address": { + "type": "0x5306f64e312b581766351c07af79c72fcb1cd25147157fdc2f8ad76de9a3fb6a::external_address::ExternalAddress", + "fields": { + "value": { + "type": "0x5306f64e312b581766351c07af79c72fcb1cd25147157fdc2f8ad76de9a3fb6a::bytes32::Bytes32", + "fields": {"data": [%s] + } + } + } + }, + "token_chain": %s + } + }, + "treasury_cap": { + "type": "0x2::coin::TreasuryCap<0x5d4b302506645c37ff133b98c4b50a5ae14841659738d6d733d59d0d217a93bf::coin::COIN>", + "fields": { + "id": { + "id": "0xa5085139fdeae133cf6ca58f1f1cee138f24ad6fc54d8e24a519dc24f3b2b974" + }, + "total_supply": { + "type": "0x2::balance::Supply<0x5d4b302506645c37ff133b98c4b50a5ae14841659738d6d733d59d0d217a93bf::coin::COIN>", + "fields": { + "value": "%s" + } + } + } + }, + "upgrade_cap": { + "type": "0x2::package::UpgradeCap", + "fields": { + "id": { + "id": "0x86ebd31cc715928671ac05e29e85b68ae1d96db02565b5413084fcb5afb695b1" + }, + "package": "0x5d4b302506645c37ff133b98c4b50a5ae14841659738d6d733d59d0d217a93bf", + "policy": 0, + "version": "1" + } + } + } + } + } + } + }`, objectId, version, objectType, objectType, decimals, tokenAddress, tokenChain, balance) + return json_string_per_object + +} diff --git a/node/pkg/txverifier/suitypes.go b/node/pkg/txverifier/suitypes.go new file mode 100644 index 0000000000..a88e380e53 --- /dev/null +++ b/node/pkg/txverifier/suitypes.go @@ -0,0 +1,436 @@ +package txverifier + +import ( + "encoding/hex" + "encoding/json" + "fmt" + "math/big" + "regexp" + "strings" +) + +const SUI_CHAIN_ID = 21 + +// The SuiApi interface defines the functions that are required to interact with the Sui RPC. +type SuiApiInterface interface { + QueryEvents(filter string, cursor string, limit int, descending bool) (SuiQueryEventsResponse, error) + GetTransactionBlock(txDigest string) (SuiGetTransactionBlockResponse, error) + TryMultiGetPastObjects(objectId string, version string, previousVersion string) (SuiTryMultiGetPastObjectsResponse, error) +} + +// This struct defines the standard properties that get returned from the RPC. +// It includes the ErrorMessage and Error fields as well, with a standard implementation +// of a `GetError()` function. `suiApiRequest` requires `GetError()` for standard +// API error handling. +type SuiApiStandardResponse struct { + Jsonrpc string `json:"jsonrpc"` + ID int `json:"id"` + // error_msg is typically populated when a non-api-related error occurs (like ratelimiting) + ErrorMessage *string `json:"error_msg"` + // error is typically populated when an api-related error occurs + Error *struct { + Code int `json:"code"` + Message string `json:"message"` + } `json:"error"` +} + +func (e SuiApiStandardResponse) GetError() error { + if e.ErrorMessage != nil { + return fmt.Errorf("error from Sui RPC: %s", *e.ErrorMessage) + } + + if e.Error != nil { + return fmt.Errorf("error from Sui RPC: %s", e.Error.Message) + } + + return nil +} + +// The response object for suix_queryEvents +type SuiQueryEventsResponse struct { + SuiApiStandardResponse + Result SuiQueryEventsResult `json:"result"` +} + +type SuiQueryEventsResult struct { + Data []SuiEvent `json:"data"` +} + +type SuiEvent struct { + ID struct { + TxDigest *string `json:"txDigest"` + EventSeq *string `json:"eventSeq"` + } `json:"id"` + PackageID *string `json:"packageId"` + TransactionModule *string `json:"transactionModule"` + Sender *string `json:"sender"` + Type *string `json:"type"` + // Bcs *string `json:"bcs"` + Timestamp *string `json:"timestampMs"` + Message *WormholeMessage `json:"parsedJson"` +} + +// The response object for sui_GetTransactionBlock +type SuiGetTransactionBlockResponse struct { + SuiApiStandardResponse + Result SuiGetTransactionBlockResult `json:"result"` +} + +type SuiGetTransactionBlockResult struct { + ObjectChanges []ObjectChange `json:"objectChanges"` + Events []SuiEvent `json:"events"` +} + +type ObjectChange struct { + ObjectType string `json:"objectType"` + ObjectId string `json:"objectId"` + Version string `json:"version"` + PreviousVersion string `json:"previousVersion"` +} + +// Validate the type information of the object change. The following checks are performed: +// - pass the object through a regex that extracts the package ID, coin type, and asset type +// - ensure that the asset type is wrapped or native +// - ensure that the package IDs match the expected package ID +// - ensure that the coin types match +func (o ObjectChange) ValidateTypeInformation(expectedPackageId string) (success bool) { + // AI generated regex + re := regexp.MustCompile(`^0x2::dynamic_field::Field<([^:]+)::token_registry::Key<([^>]+)>, ([^:]+)::([^<]+)<([^>]+)>>$`) + matches := re.FindStringSubmatch(o.ObjectType) + + if len(matches) == 6 { + scanPackage1 := matches[1] + scanCoinType1 := matches[2] + scanPackage2 := matches[3] + scanAssetType := matches[4] + scanCoinType2 := matches[5] + + // Ensure that the asset type is wrapped or native + if scanAssetType != "wrapped_asset::WrappedAsset" && scanAssetType != "native_asset::NativeAsset" { + return false + } + + // Ensure that the package IDs match the expected package ID + if scanPackage1 != expectedPackageId || scanPackage2 != expectedPackageId { + return false + } + + // Ensure that the coin types match + if scanCoinType1 != scanCoinType2 { + return false + } + + return true + } + + // No matches were found + return false +} + +// The response object for suix_tryMultiGetPastObjects +type SuiTryMultiGetPastObjectsResponse struct { + SuiApiStandardResponse + Result []SuiTryMultiGetPastObjectsResult `json:"result"` +} + +// Gets the balance difference of the two result objects. +func (r SuiTryMultiGetPastObjectsResponse) GetBalanceDiff() (*big.Int, error) { + + if len(r.Result) != 2 { + return big.NewInt(0), fmt.Errorf("incorrect number of results received") + } + + // Determine if the asset is wrapped or native + isWrapped, err := r.Result[0].IsWrapped() + if err != nil { + return big.NewInt(0), fmt.Errorf("error in checking if object is wrapped: %w", err) + } + + // TODO: Should we check that the other asset is also wrapped? + newBalance, err := r.Result[0].GetVersionBalance(isWrapped) + if err != nil { + return big.NewInt(0), fmt.Errorf("error in getting new balance: %w", err) + } + + oldBalance, err := r.Result[1].GetVersionBalance(isWrapped) + if err != nil { + return big.NewInt(0), fmt.Errorf("error in getting old balance: %w", err) + } + + difference := newBalance.Sub(newBalance, oldBalance) + // If the asset is wrapped, it means that the balance was burned, so the difference should be negative. + if isWrapped { + difference = difference.Mul(difference, big.NewInt(-1)) + } + + return difference, nil +} + +// Gets the decimals +func (r SuiTryMultiGetPastObjectsResponse) GetDecimals() (uint8, error) { + decimals0, err0 := r.Result[0].GetDecimals() + decimals1, err1 := r.Result[1].GetDecimals() + + if err0 != nil { + return 0, fmt.Errorf("error in getting decimals: %w", err0) + } else if err1 != nil { + return 0, fmt.Errorf("error in getting decimals: %w", err1) + } else if decimals0 != decimals1 { + return 0, fmt.Errorf("decimals do not match") + } + + return decimals0, nil +} + +func (r SuiTryMultiGetPastObjectsResponse) GetTokenAddress() (string, error) { + tokenAddress0, err0 := r.Result[0].GetTokenAddress() + tokenAddress1, err1 := r.Result[1].GetTokenAddress() + + if err0 != nil { + return "", fmt.Errorf("error in getting token address: %w", err0) + } else if err1 != nil { + return "", fmt.Errorf("error in getting token address: %w", err1) + } else if tokenAddress0 != tokenAddress1 { + return "", fmt.Errorf("token addresses do not match") + } + + return tokenAddress0, nil +} + +func (r SuiTryMultiGetPastObjectsResponse) GetTokenChain() (uint16, error) { + chain0, err0 := r.Result[0].GetTokenChain() + chain1, err1 := r.Result[1].GetTokenChain() + + if err0 != nil { + return 0, fmt.Errorf("error in getting token chain: %w", err0) + } else if err1 != nil { + return 0, fmt.Errorf("error in getting token chain: %w", err1) + } else if chain0 != chain1 { + return 0, fmt.Errorf("token chain ids do not match") + } + + return chain0, nil +} + +func (r SuiTryMultiGetPastObjectsResponse) GetObjectId() (string, error) { + objectId, err := r.Result[0].GetObjectId() + if err != nil { + return "", fmt.Errorf("could not get object id") + } + + return objectId, nil +} + +func (r SuiTryMultiGetPastObjectsResponse) GetVersion() (string, error) { + version, err := r.Result[0].GetVersion() + if err != nil { + return "", fmt.Errorf("could not get object id") + } + + return version, nil +} + +func (r SuiTryMultiGetPastObjectsResponse) GetPreviousVersion() (string, error) { + previousVersion, err := r.Result[1].GetVersion() + if err != nil { + return "", fmt.Errorf("could not get object id") + } + + return previousVersion, nil +} + +func (r SuiTryMultiGetPastObjectsResponse) GetObjectType() (string, error) { + type0, err0 := r.Result[0].GetObjectType() + type1, err1 := r.Result[1].GetObjectType() + + if err0 != nil { + return "", fmt.Errorf("error in getting token chain: %w", err0) + } else if err1 != nil { + return "", fmt.Errorf("error in getting token chain: %w", err1) + } else if type0 != type1 { + return "", fmt.Errorf("token chain ids do not match") + } + + return type0, nil +} + +// The result object for suix_tryMultiGetPastObjects. +type SuiTryMultiGetPastObjectsResult struct { + Status string `json:"status"` + Details *json.RawMessage `json:"details"` +} + +// Check if the result object is wrapped. +func (r SuiTryMultiGetPastObjectsResult) IsWrapped() (bool, error) { + path := "content.type" + objectType, err := extractFromJsonPath[string](*r.Details, path) + + if err != nil { + return false, fmt.Errorf("error in extracting object type: %w", err) + } + + return strings.Contains(objectType, "wrapped_asset::WrappedAsset"), nil +} + +// Get the balance of the result object. +func (r SuiTryMultiGetPastObjectsResult) GetVersionBalance(isWrapped bool) (*big.Int, error) { + + var path string + supplyInt := big.NewInt(0) + + // The path to use for a native asset + pathNative := "content.fields.value.fields.custody" + + // The path to use for a wrapped asset + pathWrapped := "content.fields.value.fields.treasury_cap.fields.total_supply.fields.value" + + if isWrapped { + path = pathWrapped + } else { + path = pathNative + } + + supply, err := extractFromJsonPath[string](*r.Details, path) + + if err != nil { + return supplyInt, fmt.Errorf("error in extracting wormhole balance: %w", err) + } + + supplyInt, success := supplyInt.SetString(supply, 10) + + if !success { + return supplyInt, fmt.Errorf("error converting supply to int: %w", err) + } + + return supplyInt, nil +} + +// Get the result object's decimals. +func (r SuiTryMultiGetPastObjectsResult) GetDecimals() (uint8, error) { + // token_bridge::wrapped_asset::decimals() and token_bridge::native_asset::decimals() + // both store the decimals used for truncation in the NativeAsset or WrappedAsset's `decimals()` field + path := "content.fields.value.fields.decimals" + + decimals, err := extractFromJsonPath[float64](*r.Details, path) + + if err != nil { + return 0, fmt.Errorf("error in extracting decimals: %w", err) + } + + return uint8(decimals), nil +} + +// Get the result object's token address. This will be the address of the token +// on it's chain of origin. +func (r SuiTryMultiGetPastObjectsResult) GetTokenAddress() (tokenAddress string, err error) { + var path string + + // The path to use for a native asset + pathNative := "content.fields.value.fields.token_address.fields.value.fields.data" + + // The path to use for a wrapped asset + pathWrapped := "content.fields.value.fields.info.fields.token_address.fields.value.fields.data" + + wrapped, err := r.IsWrapped() + + if err != nil { + return "", fmt.Errorf("error in checking if object is wrapped: %w", err) + } + + if wrapped { + path = pathWrapped + } else { + path = pathNative + } + + data, err := extractFromJsonPath[[]interface{}](*r.Details, path) + + if err != nil { + return "", fmt.Errorf("error in extracting token address: %w", err) + } + + // data is of type []interface{}, and each element is of type float64. + // We need to covnert each element to a byte, and then convert the []byte to a hex string. + addrBytes := make([]byte, len(data)) + + for i, v := range data { + if f, ok := v.(float64); ok { + addrBytes[i] = byte(f) + } else { + return "", fmt.Errorf("error in converting token data to float type") + } + } + + return hex.EncodeToString(addrBytes), nil +} + +// Get the token's chain ID. This will be the chain ID of the network the token +// originated from. +func (r SuiTryMultiGetPastObjectsResult) GetTokenChain() (uint16, error) { + + wrapped, err := r.IsWrapped() + + if err != nil { + return 0, fmt.Errorf("error in checking if object is wrapped: %w", err) + } + + if !wrapped { + return SUI_CHAIN_ID, nil + } + + path := "content.fields.value.fields.info.fields.token_chain" + + chain, err := extractFromJsonPath[float64](*r.Details, path) + + if err != nil { + return 0, fmt.Errorf("error in extracting chain: %w", err) + } + + return uint16(chain), nil +} + +func (r SuiTryMultiGetPastObjectsResult) GetObjectId() (string, error) { + path := "objectId" + + objectId, err := extractFromJsonPath[string](*r.Details, path) + + if err != nil { + return "", fmt.Errorf("error in extracting objectId: %w", err) + } + + return objectId, nil +} + +func (r SuiTryMultiGetPastObjectsResult) GetVersion() (string, error) { + path := "version" + + version, err := extractFromJsonPath[string](*r.Details, path) + + if err != nil { + return "", fmt.Errorf("error in extracting version: %w", err) + } + + return version, nil +} + +func (r SuiTryMultiGetPastObjectsResult) GetObjectType() (string, error) { + path := "type" + + version, err := extractFromJsonPath[string](*r.Details, path) + + if err != nil { + return "", fmt.Errorf("error in extracting version: %w", err) + } + + return version, nil +} + +// Definition of the WormholeMessage event +type WormholeMessage struct { + ConsistencyLevel *uint8 `json:"consistency_level"` + Nonce *uint64 `json:"nonce"` + Payload []byte `json:"payload"` + Sender *string `json:"sender"` + Sequence *string `json:"sequence"` + Timestamp *string `json:"timestamp"` +} diff --git a/node/pkg/txverifier/utils.go b/node/pkg/txverifier/utils.go new file mode 100644 index 0000000000..01aa87e195 --- /dev/null +++ b/node/pkg/txverifier/utils.go @@ -0,0 +1,98 @@ +package txverifier + +import ( + "encoding/json" + "fmt" + "math/big" + "strings" +) + +// Constants +const ( + MAX_DECIMALS = 8 + KEY_FORMAT = "%s-%d" +) + +// Extracts the value at the given path from the JSON object, and casts it to +// type T. If the path does not exist in the object, an error is returned. +func extractFromJsonPath[T any](data json.RawMessage, path string) (T, error) { + var defaultT T + + var obj map[string]interface{} + err := json.Unmarshal(data, &obj) + if err != nil { + return defaultT, err + } + + // Split the path and iterate over the keys, except for the final key. For + // each key, check if it exists in the object. If it does exist and is a map, + // update the object to the value of the key. + keys := strings.Split(path, ".") + for _, key := range keys[:len(keys)-1] { + if obj[key] == nil { + return defaultT, fmt.Errorf("key %s not found", key) + } + + if v, ok := obj[key].(map[string]interface{}); ok { + obj = v + } else { + return defaultT, fmt.Errorf("can't convert to key to map[string]interface{} type") + } + } + + // If the final key exists in the object, return the value as T. Otherwise, + // return an error. + if value, exists := obj[keys[len(keys)-1]]; exists { + if v, ok := value.(T); ok { + return v, nil + } else { + return defaultT, fmt.Errorf("can't convert to type T") + } + } else { + return defaultT, fmt.Errorf("key %s not found", keys[len(keys)-1]) + } +} + +// Normalize the amount to 8 decimals. If the amount has more than 8 decimals, +// the amount is divided by 10^(decimals-8). If the amount has less than 8 +// decimals, the amount is returned as is. +// https://wormhole.com/docs/build/start-building/supported-networks/evm/#addresses +func normalize(amount *big.Int, decimals uint8) (normalizedAmount *big.Int) { + if amount == nil { + return nil + } + if decimals > MAX_DECIMALS { + exponent := new(big.Int).SetInt64(int64(decimals - 8)) + multiplier := new(big.Int).Exp(new(big.Int).SetInt64(10), exponent, nil) + normalizedAmount = new(big.Int).Div(amount, multiplier) + } else { + return amount + } + + return normalizedAmount +} + +// denormalize() scales an amount to its native decimal representation by multiplying it by some power of 10. +// See also: +// - documentation: +// https://github.com/wormhole-foundation/wormhole/blob/main/whitepapers/0003_token_bridge.md#handling-of-token-amounts-and-decimals +// https://wormhole.com/docs/build/start-building/supported-networks/evm/#addresses +// - solidity implementation: +// https://github.com/wormhole-foundation/wormhole/blob/91ec4d1dc01f8b690f0492815407505fb4587520/ethereum/contracts/bridge/Bridge.sol#L295-L300 +func denormalize( + amount *big.Int, + decimals uint8, +) (denormalizedAmount *big.Int) { + if decimals > 8 { + // Scale from 8 decimals to `decimals` + exponent := new(big.Int).SetInt64(int64(decimals - 8)) + multiplier := new(big.Int).Exp(new(big.Int).SetInt64(10), exponent, nil) + denormalizedAmount = new(big.Int).Mul(amount, multiplier) + + } else { + // No scaling necessary + denormalizedAmount = new(big.Int).Set(amount) + } + + return denormalizedAmount +} diff --git a/node/pkg/txverifier/utils_test.go b/node/pkg/txverifier/utils_test.go new file mode 100644 index 0000000000..8b77e4b8df --- /dev/null +++ b/node/pkg/txverifier/utils_test.go @@ -0,0 +1,221 @@ +package txverifier + +import ( + "encoding/json" + "math/big" + "testing" +) + +func TestExtractFromJsonPath(t *testing.T) { + testcases := []struct { + name string + data json.RawMessage + path string + expected interface{} + wantErr bool + typ string + }{ + { + name: "ValidPathString", + data: json.RawMessage(`{"key1": {"key2": "value"}}`), + path: "key1.key2", + expected: "value", + wantErr: false, + typ: "string", + }, + { + name: "ValidPathFloat", + data: json.RawMessage(`{"key1": {"key2": 123.45}}`), + path: "key1.key2", + expected: 123.45, + wantErr: false, + typ: "float64", + }, + { + name: "InvalidPath", + data: json.RawMessage(`{"key1": {"key2": "value"}}`), + path: "key1.key3", + expected: nil, + wantErr: true, + typ: "string", + }, + { + name: "NestedPath", + data: json.RawMessage(`{"key1": {"key2": {"key3": "value"}}}`), + path: "key1.key2.key3", + expected: "value", + wantErr: false, + typ: "string", + }, + { + name: "EmptyPath", + data: json.RawMessage(`{"key1": {"key2": "value"}}`), + path: "", + expected: nil, + wantErr: true, + typ: "string", + }, + { + name: "NonExistentPath", + data: json.RawMessage(`{"key1": {"key2": "value"}}`), + path: "key3.key4", + expected: nil, + wantErr: true, + typ: "string", + }, + { + name: "MalformedJson", + data: json.RawMessage(`{"key1": {"key2": "value"`), + path: "key1.key2", + expected: nil, + wantErr: true, + typ: "string", + }, + } + + for _, tt := range testcases { + t.Run(tt.name, func(t *testing.T) { + var result interface{} + var err error + switch tt.typ { + case "string": + var res string + res, err = extractFromJsonPath[string](tt.data, tt.path) + result = res + case "float64": + var res float64 + res, err = extractFromJsonPath[float64](tt.data, tt.path) + result = res + default: + t.Fatalf("Unsupported type: %v", tt.typ) + } + + if (err != nil) != tt.wantErr { + t.Errorf("Expected error: %v, got: %v", tt.wantErr, err) + } + if !tt.wantErr && result != tt.expected { + t.Errorf("Expected %v, got %v", tt.expected, result) + } + }) + } +} + +func TestNormalize(t *testing.T) { + testcases := []struct { + name string + amount *big.Int + decimals uint8 + expected *big.Int + }{ + { + name: "AmountWithMoreThan8Decimals", + amount: big.NewInt(1000000000000000000), + decimals: 18, + expected: big.NewInt(100000000), + }, + { + name: "AmountWithExactly8Decimals", + amount: big.NewInt(12345678), + decimals: 8, + expected: big.NewInt(12345678), + }, + { + name: "AmountWithLessThan8Decimals", + amount: big.NewInt(12345), + decimals: 5, + expected: big.NewInt(12345), + }, + { + name: "AmountWithZeroDecimals", + amount: big.NewInt(12345678), + decimals: 0, + expected: big.NewInt(12345678), + }, + { + name: "AmountWith9Decimals", + amount: big.NewInt(123456789), + decimals: 9, + expected: big.NewInt(12345678), + }, + { + name: "AmountWith10Decimals", + amount: big.NewInt(1234567890), + decimals: 10, + expected: big.NewInt(12345678), + }, + { + name: "AmountEqualsNil", + amount: nil, + decimals: 18, + expected: nil, + }, + } + + for _, tt := range testcases { + t.Run(tt.name, func(t *testing.T) { + result := normalize(tt.amount, tt.decimals) + if result.Cmp(tt.expected) != 0 { + t.Errorf("Expected %v, got %v", tt.expected, result) + } + }) + } +} + +func TestDenormalize(t *testing.T) { + t.Parallel() // marks TLog as capable of running in parallel with other tests + tests := map[string]struct { + amount *big.Int + decimals uint8 + expected *big.Int + }{ + "noop: decimals less than 8": { + amount: big.NewInt(123000), + decimals: 1, + expected: big.NewInt(123000), + }, + "noop: decimals equal to 8": { + amount: big.NewInt(123000), + decimals: 8, + expected: big.NewInt(123000), + }, + "denormalize: decimals greater than 8": { + amount: big.NewInt(123000), + decimals: 12, + expected: big.NewInt(1230000000), + }, + // NOTE: some tokens on NEAR have as many as 24 decimals so this isn't a strict limit for Wormhole + // overall, but should be true for EVM chains. + "denormalize: decimals at maximum expected size": { + amount: big.NewInt(123_000_000), + decimals: 18, + expected: big.NewInt(1_230_000_000_000_000_000), + }, + // https://github.com/wormhole-foundation/wormhole/blob/main/whitepapers/0003_token_bridge.md#handling-of-token-amounts-and-decimals + "denormalize: whitepaper example 1": { + amount: big.NewInt(100000000), + decimals: 18, + expected: big.NewInt(1000000000000000000), + }, + "denormalize: whitepaper example 2": { + amount: big.NewInt(20000), + decimals: 4, + expected: big.NewInt(20000), + }, + } + for name, test := range tests { + test := test // NOTE: uncomment for Go < 1.22, see /doc/faq#closures_and_goroutines + t.Run(name, func(t *testing.T) { + t.Parallel() // marks each test case as capable of running in parallel with each other + + if got := denormalize(test.amount, test.decimals); got.Cmp(test.expected) != 0 { + t.Fatalf("denormalize(%s, %d) returned %s; expected %s", + test.amount.String(), + test.decimals, + got, + test.expected.String(), + ) + } + + }) + } +} diff --git a/node/pkg/watchers/algorand/watcher.go b/node/pkg/watchers/algorand/watcher.go index 5928bed401..e295e2e3ce 100644 --- a/node/pkg/watchers/algorand/watcher.go +++ b/node/pkg/watchers/algorand/watcher.go @@ -157,7 +157,7 @@ func lookAtTxn(e *Watcher, t types.SignedTxnInBlock, b types.Block, logger *zap. for _, obs := range observations { observation := &common.MessagePublication{ - TxHash: txHash, + TxID: txHash.Bytes(), Timestamp: time.Unix(b.TimeStamp, 0), Nonce: obs.nonce, Sequence: obs.sequence, diff --git a/node/pkg/watchers/aptos/config.go b/node/pkg/watchers/aptos/config.go index 632b8a46e3..98b7f95a5c 100644 --- a/node/pkg/watchers/aptos/config.go +++ b/node/pkg/watchers/aptos/config.go @@ -42,5 +42,5 @@ func (wc *WatcherConfig) Create( _ chan<- *common.GuardianSet, env common.Environment, ) (interfaces.L1Finalizer, supervisor.Runnable, error) { - return nil, NewWatcher(wc.Rpc, wc.Account, wc.Handle, msgC, obsvReqC).Run, nil + return nil, NewWatcher(wc.ChainID, wc.NetworkID, wc.Rpc, wc.Account, wc.Handle, msgC, obsvReqC).Run, nil } diff --git a/node/pkg/watchers/aptos/watcher.go b/node/pkg/watchers/aptos/watcher.go index 9ea36ac4bb..f3e5228e85 100644 --- a/node/pkg/watchers/aptos/watcher.go +++ b/node/pkg/watchers/aptos/watcher.go @@ -14,6 +14,7 @@ import ( gossipv1 "github.com/certusone/wormhole/node/pkg/proto/gossip/v1" "github.com/certusone/wormhole/node/pkg/readiness" "github.com/certusone/wormhole/node/pkg/supervisor" + "github.com/certusone/wormhole/node/pkg/watchers" eth_common "github.com/ethereum/go-ethereum/common" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promauto" @@ -25,6 +26,9 @@ import ( type ( // Watcher is responsible for looking over Aptos blockchain and reporting new transactions to the wormhole contract Watcher struct { + chainID vaa.ChainID + networkID string + aptosRPC string aptosAccount string aptosHandle string @@ -36,20 +40,22 @@ type ( ) var ( - aptosMessagesConfirmed = promauto.NewCounter( + aptosMessagesConfirmed = promauto.NewCounterVec( prometheus.CounterOpts{ Name: "wormhole_aptos_observations_confirmed_total", - Help: "Total number of verified Aptos observations found", - }) - currentAptosHeight = promauto.NewGauge( + Help: "Total number of verified observations found for the chain", + }, []string{"chain_name"}) + currentAptosHeight = promauto.NewGaugeVec( prometheus.GaugeOpts{ Name: "wormhole_aptos_current_height", - Help: "Current Aptos block height", - }) + Help: "Current block height for the chain", + }, []string{"chain_name"}) ) // NewWatcher creates a new Aptos appid watcher func NewWatcher( + chainID vaa.ChainID, + networkID watchers.NetworkID, aptosRPC string, aptosAccount string, aptosHandle string, @@ -57,36 +63,42 @@ func NewWatcher( obsvReqC <-chan *gossipv1.ObservationRequest, ) *Watcher { return &Watcher{ + chainID: chainID, + networkID: string(networkID), aptosRPC: aptosRPC, aptosAccount: aptosAccount, aptosHandle: aptosHandle, msgC: msgC, obsvReqC: obsvReqC, - readinessSync: common.MustConvertChainIdToReadinessSyncing(vaa.ChainIDAptos), + readinessSync: common.MustConvertChainIdToReadinessSyncing(chainID), } } func (e *Watcher) Run(ctx context.Context) error { - p2p.DefaultRegistry.SetNetworkStats(vaa.ChainIDAptos, &gossipv1.Heartbeat_Network{ + p2p.DefaultRegistry.SetNetworkStats(e.chainID, &gossipv1.Heartbeat_Network{ ContractAddress: e.aptosAccount, }) logger := supervisor.Logger(ctx) logger.Info("Starting watcher", - zap.String("watcher_name", "aptos"), - zap.String("aptosRPC", e.aptosRPC), - zap.String("aptosAccount", e.aptosAccount), - zap.String("aptosHandle", e.aptosHandle), + zap.String("watcher_name", e.networkID), + zap.String("rpc", e.aptosRPC), + zap.String("account", e.aptosAccount), + zap.String("handle", e.aptosHandle), ) - logger.Info("Aptos watcher connecting to RPC node ", zap.String("url", e.aptosRPC)) - // SECURITY: the API guarantees that we only get the events from the right // contract var eventsEndpoint = fmt.Sprintf(`%s/v1/accounts/%s/events/%s/event`, e.aptosRPC, e.aptosAccount, e.aptosHandle) var aptosHealth = fmt.Sprintf(`%s/v1`, e.aptosRPC) + logger.Info("watcher connecting to RPC node ", + zap.String("url", e.aptosRPC), + zap.String("eventsQuery", eventsEndpoint), + zap.String("healthQuery", aptosHealth), + ) + // the events have sequence numbers associated with them in the aptos API // (NOTE: this is not the same as the wormhole sequence id). The event // endpoint is paginated, so we use this variable to keep track of which @@ -103,7 +115,7 @@ func (e *Watcher) Run(ctx context.Context) error { case <-ctx.Done(): return ctx.Err() case r := <-e.obsvReqC: - if vaa.ChainID(r.ChainId) != vaa.ChainIDAptos { + if vaa.ChainID(r.ChainId) != e.chainID { panic("invalid chain ID") } @@ -117,13 +129,13 @@ func (e *Watcher) Run(ctx context.Context) error { body, err := e.retrievePayload(s) if err != nil { logger.Error("retrievePayload", zap.Error(err)) - p2p.DefaultRegistry.AddErrorCount(vaa.ChainIDAptos, 1) + p2p.DefaultRegistry.AddErrorCount(e.chainID, 1) continue } if !gjson.Valid(string(body)) { logger.Error("InvalidJson: " + string(body)) - p2p.DefaultRegistry.AddErrorCount(vaa.ChainIDAptos, 1) + p2p.DefaultRegistry.AddErrorCount(e.chainID, 1) break } @@ -165,7 +177,7 @@ func (e *Watcher) Run(ctx context.Context) error { eventsJson, err := e.retrievePayload(s) if err != nil { logger.Error("retrievePayload", zap.Error(err)) - p2p.DefaultRegistry.AddErrorCount(vaa.ChainIDAptos, 1) + p2p.DefaultRegistry.AddErrorCount(e.chainID, 1) continue } @@ -178,7 +190,7 @@ func (e *Watcher) Run(ctx context.Context) error { if !gjson.Valid(string(eventsJson)) { logger.Error("InvalidJson: " + string(eventsJson)) - p2p.DefaultRegistry.AddErrorCount(vaa.ChainIDAptos, 1) + p2p.DefaultRegistry.AddErrorCount(e.chainID, 1) continue } @@ -193,27 +205,34 @@ func (e *Watcher) Run(ctx context.Context) error { continue } + eventSeq := eventSequence.Uint() + if nextSequence == 0 && eventSeq != 0 { + // Avoid publishing an old observation on startup. This does not block the first message on a new chain (when eventSeq would be zero). + nextSequence = eventSeq + 1 + continue + } + // this is interesting in the last iteration, whereby we // find the next sequence that comes after the array - nextSequence = eventSequence.Uint() + 1 + nextSequence = eventSeq + 1 data := event.Get("data") if !data.Exists() { continue } - e.observeData(logger, data, eventSequence.Uint(), false) + e.observeData(logger, data, eventSeq, false) } health, err := e.retrievePayload(aptosHealth) if err != nil { logger.Error("health", zap.Error(err)) - p2p.DefaultRegistry.AddErrorCount(vaa.ChainIDAptos, 1) + p2p.DefaultRegistry.AddErrorCount(e.chainID, 1) continue } if !gjson.Valid(string(health)) { logger.Error("Invalid JSON in health response: " + string(health)) - p2p.DefaultRegistry.AddErrorCount(vaa.ChainIDAptos, 1) + p2p.DefaultRegistry.AddErrorCount(e.chainID, 1) continue } @@ -226,8 +245,8 @@ func (e *Watcher) Run(ctx context.Context) error { blockHeight := pHealth.Get("block_height") if blockHeight.Exists() { - currentAptosHeight.Set(float64(blockHeight.Uint())) - p2p.DefaultRegistry.SetNetworkStats(vaa.ChainIDAptos, &gossipv1.Heartbeat_Network{ + currentAptosHeight.WithLabelValues(e.networkID).Set(float64(blockHeight.Uint())) + p2p.DefaultRegistry.SetNetworkStats(e.chainID, &gossipv1.Heartbeat_Network{ Height: int64(blockHeight.Uint()), ContractAddress: e.aptosAccount, }) @@ -243,6 +262,7 @@ func (e *Watcher) retrievePayload(s string) ([]byte, error) { if err != nil { return nil, err } + defer res.Body.Close() body, err := io.ReadAll(res.Body) if err != nil { return nil, err @@ -305,21 +325,21 @@ func (e *Watcher) observeData(logger *zap.Logger, data gjson.Result, nativeSeq u } observation := &common.MessagePublication{ - TxHash: txHash, + TxID: txHash.Bytes(), Timestamp: time.Unix(int64(ts.Uint()), 0), Nonce: uint32(nonce.Uint()), // uint32 Sequence: sequence.Uint(), - EmitterChain: vaa.ChainIDAptos, + EmitterChain: e.chainID, EmitterAddress: a, Payload: pl, ConsistencyLevel: uint8(consistencyLevel.Uint()), IsReobservation: isReobservation, } - aptosMessagesConfirmed.Inc() + aptosMessagesConfirmed.WithLabelValues(e.networkID).Inc() logger.Info("message observed", - zap.Stringer("txHash", observation.TxHash), + zap.String("txHash", observation.TxIDString()), zap.Time("timestamp", observation.Timestamp), zap.Uint32("nonce", observation.Nonce), zap.Uint64("sequence", observation.Sequence), diff --git a/node/pkg/watchers/cosmwasm/watcher.go b/node/pkg/watchers/cosmwasm/watcher.go index 0cf856518b..0ec30b8b7b 100644 --- a/node/pkg/watchers/cosmwasm/watcher.go +++ b/node/pkg/watchers/cosmwasm/watcher.go @@ -511,7 +511,7 @@ func EventsToMessagePublications(contract string, txHash string, events []gjson. continue } messagePublication := &common.MessagePublication{ - TxHash: txHashValue, + TxID: txHashValue.Bytes(), Timestamp: time.Unix(blockTimeInt, 0), Nonce: uint32(nonceInt), Sequence: sequenceInt, diff --git a/node/pkg/watchers/evm/by_transaction.go b/node/pkg/watchers/evm/by_transaction.go index 61c0ec0d00..4a109864ee 100644 --- a/node/pkg/watchers/evm/by_transaction.go +++ b/node/pkg/watchers/evm/by_transaction.go @@ -16,7 +16,7 @@ var ( // SECURITY: Hardcoded ABI identifier for the LogMessagePublished topic. When using the watcher, we don't need this // since the node will only hand us pre-filtered events. In this case, we need to manually verify it // since ParseLogMessagePublished will only verify whether it parses. - logMessagePublishedTopic = eth_common.HexToHash("0x6eb224fb001ed210e379b335e35efe88672a8ce935d981a6896b27ffdf52a3b2") + LogMessagePublishedTopic = eth_common.HexToHash("0x6eb224fb001ed210e379b335e35efe88672a8ce935d981a6896b27ffdf52a3b2") ) // MessageEventsForTransaction returns the lockup events for a given transaction. @@ -65,7 +65,7 @@ func MessageEventsForTransaction( continue } - if l.Topics[0] != logMessagePublishedTopic { + if l.Topics[0] != LogMessagePublishedTopic { continue } @@ -75,7 +75,7 @@ func MessageEventsForTransaction( } message := &common.MessagePublication{ - TxHash: ev.Raw.TxHash, + TxID: ev.Raw.TxHash.Bytes(), Timestamp: time.Unix(int64(blockTime), 0), Nonce: ev.Nonce, Sequence: ev.Sequence, diff --git a/node/pkg/watchers/evm/config.go b/node/pkg/watchers/evm/config.go index 9fe8dfa8b7..92a751a47e 100644 --- a/node/pkg/watchers/evm/config.go +++ b/node/pkg/watchers/evm/config.go @@ -53,9 +53,7 @@ func (wc *WatcherConfig) Create( setWriteC = setC } - var devMode bool = (env == common.UnsafeDevNet) - - watcher := NewEthWatcher(wc.Rpc, eth_common.HexToAddress(wc.Contract), string(wc.NetworkID), wc.ChainID, msgC, setWriteC, obsvReqC, queryReqC, queryResponseC, devMode, wc.CcqBackfillCache) + watcher := NewEthWatcher(wc.Rpc, eth_common.HexToAddress(wc.Contract), string(wc.NetworkID), wc.ChainID, msgC, setWriteC, obsvReqC, queryReqC, queryResponseC, env, wc.CcqBackfillCache) watcher.SetL1Finalizer(wc.l1Finalizer) return watcher, watcher.Run, nil } diff --git a/node/pkg/watchers/evm/connectors/celo.go b/node/pkg/watchers/evm/connectors/celo.go deleted file mode 100644 index fcf5c1e96f..0000000000 --- a/node/pkg/watchers/evm/connectors/celo.go +++ /dev/null @@ -1,291 +0,0 @@ -package connectors - -import ( - "context" - "time" - - celoAbi "github.com/certusone/wormhole/node/pkg/watchers/evm/connectors/celoabi" - ethAbi "github.com/certusone/wormhole/node/pkg/watchers/evm/connectors/ethabi" - - celoBind "github.com/celo-org/celo-blockchain/accounts/abi/bind" - celoCommon "github.com/celo-org/celo-blockchain/common" - celoTypes "github.com/celo-org/celo-blockchain/core/types" - celoClient "github.com/celo-org/celo-blockchain/ethclient" - celoRpc "github.com/celo-org/celo-blockchain/rpc" - - ethereum "github.com/ethereum/go-ethereum" - ethCommon "github.com/ethereum/go-ethereum/common" - ethTypes "github.com/ethereum/go-ethereum/core/types" - ethClient "github.com/ethereum/go-ethereum/ethclient" - ethEvent "github.com/ethereum/go-ethereum/event" - ethRpc "github.com/ethereum/go-ethereum/rpc" - - "github.com/certusone/wormhole/node/pkg/common" - "go.uber.org/zap" -) - -// CeloConnector implements EVM network query capabilities for the Celo network. It's almost identical to -// EthereumConnector except it's using the Celo fork and provides shims between their respective types. -type CeloConnector struct { - networkName string - address ethCommon.Address - logger *zap.Logger - client *celoClient.Client - rawClient *celoRpc.Client - filterer *celoAbi.AbiFilterer - caller *celoAbi.AbiCaller -} - -func NewCeloConnector(ctx context.Context, networkName, rawUrl string, address ethCommon.Address, logger *zap.Logger) (*CeloConnector, error) { - rawClient, err := celoRpc.DialContext(ctx, rawUrl) - if err != nil { - return nil, err - } - client := celoClient.NewClient(rawClient) - - filterer, err := celoAbi.NewAbiFilterer(celoCommon.BytesToAddress(address.Bytes()), client) - if err != nil { - panic(err) - } - caller, err := celoAbi.NewAbiCaller(celoCommon.BytesToAddress(address.Bytes()), client) - if err != nil { - panic(err) - } - - return &CeloConnector{ - networkName: networkName, - address: address, - logger: logger, - client: client, - rawClient: rawClient, - filterer: filterer, - caller: caller, - }, nil -} - -func (c *CeloConnector) NetworkName() string { - return c.networkName -} - -func (c *CeloConnector) ContractAddress() ethCommon.Address { - return c.address -} - -func (c *CeloConnector) GetCurrentGuardianSetIndex(ctx context.Context) (uint32, error) { - opts := &celoBind.CallOpts{Context: ctx} - return c.caller.GetCurrentGuardianSetIndex(opts) -} - -func (c *CeloConnector) GetGuardianSet(ctx context.Context, index uint32) (ethAbi.StructsGuardianSet, error) { - opts := &celoBind.CallOpts{Context: ctx} - celoGs, err := c.caller.GetGuardianSet(opts, index) - if err != nil { - return ethAbi.StructsGuardianSet{}, err - } - - ethKeys := make([]ethCommon.Address, len(celoGs.Keys)) - for n, k := range celoGs.Keys { - ethKeys[n] = ethCommon.BytesToAddress(k.Bytes()) - } - - return ethAbi.StructsGuardianSet{ - Keys: ethKeys, - ExpirationTime: celoGs.ExpirationTime, - }, err -} - -func (c *CeloConnector) WatchLogMessagePublished(ctx context.Context, errC chan error, sink chan<- *ethAbi.AbiLogMessagePublished) (ethEvent.Subscription, error) { - timeout, cancel := context.WithTimeout(ctx, 15*time.Second) - defer cancel() - messageC := make(chan *celoAbi.AbiLogMessagePublished, 2) - messageSub, err := c.filterer.WatchLogMessagePublished(&celoBind.WatchOpts{Context: timeout}, messageC, nil) - if err != nil { - return messageSub, err - } - - // The purpose of this is to map events from the Celo log message channel to the Eth log message channel. - common.RunWithScissors(ctx, errC, "celo_connector_watch_log", func(ctx context.Context) error { - for { - select { - // This will return when the subscription is unsubscribed as the error channel gets closed - case <-messageSub.Err(): - return nil - case celoEvent := <-messageC: - sink <- convertCeloEventToEth(celoEvent) - } - } - }) - - return messageSub, err -} - -func (c *CeloConnector) TransactionReceipt(ctx context.Context, txHash ethCommon.Hash) (*ethTypes.Receipt, error) { - celoReceipt, err := c.client.TransactionReceipt(ctx, celoCommon.BytesToHash(txHash.Bytes())) - if err != nil { - return nil, err - } - - return convertCeloReceiptToEth(celoReceipt), err -} - -func (c *CeloConnector) TimeOfBlockByHash(ctx context.Context, hash ethCommon.Hash) (uint64, error) { - block, err := c.client.HeaderByHash(ctx, celoCommon.BytesToHash(hash.Bytes())) - if err != nil { - return 0, err - } - - return block.Time, err -} - -func (c *CeloConnector) ParseLogMessagePublished(ethLog ethTypes.Log) (*ethAbi.AbiLogMessagePublished, error) { - celoEvent, err := c.filterer.ParseLogMessagePublished(*convertCeloLogFromEth(ðLog)) - if err != nil { - return nil, err - } - - return convertCeloEventToEth(celoEvent), err -} - -func (c *CeloConnector) SubscribeForBlocks(ctx context.Context, errC chan error, sink chan<- *NewBlock) (ethereum.Subscription, error) { - headSink := make(chan *celoTypes.Header, 2) - headerSubscription, err := c.client.SubscribeNewHead(ctx, headSink) - if err != nil { - return headerSubscription, err - } - - // The purpose of this is to map events from the Celo event channel to the new block event channel. - common.RunWithScissors(ctx, errC, "celo_connector_subscribe_for_block", func(ctx context.Context) error { - for { - select { - case <-ctx.Done(): - return nil - case ev := <-headSink: - if ev == nil { - c.logger.Error("new header event is nil") - continue - } - if ev.Number == nil { - c.logger.Error("new header block number is nil") - continue - } - hash := ethCommon.BytesToHash(ev.Hash().Bytes()) - sink <- &NewBlock{ - Number: ev.Number, - Hash: hash, - Time: ev.Time, - Finality: Finalized, - } - sink <- &NewBlock{ - Number: ev.Number, - Hash: hash, - Time: ev.Time, - Finality: Safe, - } - sink <- &NewBlock{ - Number: ev.Number, - Hash: hash, - Time: ev.Time, - Finality: Latest, - } - } - } - }) - - return headerSubscription, err -} - -func (c *CeloConnector) RawCallContext(ctx context.Context, result interface{}, method string, args ...interface{}) error { - return c.rawClient.CallContext(ctx, result, method, args...) -} - -func (c *CeloConnector) RawBatchCallContext(ctx context.Context, b []ethRpc.BatchElem) error { - celoB := make([]celoRpc.BatchElem, len(b)) - for i, v := range b { - celoB[i] = celoRpc.BatchElem{ - Method: v.Method, - Args: v.Args, - Result: v.Result, - Error: v.Error, - } - } - return c.rawClient.BatchCallContext(ctx, celoB) -} - -func (c *CeloConnector) Client() *ethClient.Client { - panic("unimplemented") -} - -func (c *CeloConnector) SubscribeNewHead(ctx context.Context, ch chan<- *ethTypes.Header) (ethereum.Subscription, error) { - panic("unimplemented") -} - -func convertCeloEventToEth(ev *celoAbi.AbiLogMessagePublished) *ethAbi.AbiLogMessagePublished { - return ðAbi.AbiLogMessagePublished{ - Sender: ethCommon.BytesToAddress(ev.Sender.Bytes()), - Sequence: ev.Sequence, - Nonce: ev.Nonce, - Payload: ev.Payload, - ConsistencyLevel: ev.ConsistencyLevel, - Raw: *convertCeloLogToEth(&ev.Raw), - } -} - -func convertCeloLogToEth(l *celoTypes.Log) *ethTypes.Log { - topics := make([]ethCommon.Hash, len(l.Topics)) - for n, t := range l.Topics { - topics[n] = ethCommon.BytesToHash(t.Bytes()) - } - - return ðTypes.Log{ - Address: ethCommon.BytesToAddress(l.Address.Bytes()), - Topics: topics, - Data: l.Data, - BlockNumber: l.BlockNumber, - TxHash: ethCommon.BytesToHash(l.TxHash.Bytes()), - TxIndex: l.TxIndex, - BlockHash: ethCommon.BytesToHash(l.BlockHash.Bytes()), - Index: l.Index, - Removed: l.Removed, - } -} - -func convertCeloReceiptToEth(celoReceipt *celoTypes.Receipt) *ethTypes.Receipt { - ethLogs := make([]*ethTypes.Log, len(celoReceipt.Logs)) - for n, l := range celoReceipt.Logs { - ethLogs[n] = convertCeloLogToEth(l) - } - - return ðTypes.Receipt{ - Type: celoReceipt.Type, - PostState: celoReceipt.PostState, - Status: celoReceipt.Status, - CumulativeGasUsed: celoReceipt.CumulativeGasUsed, - Bloom: ethTypes.BytesToBloom(celoReceipt.Bloom.Bytes()), - Logs: ethLogs, - TxHash: ethCommon.BytesToHash(celoReceipt.TxHash.Bytes()), - ContractAddress: ethCommon.BytesToAddress(celoReceipt.ContractAddress.Bytes()), - GasUsed: celoReceipt.GasUsed, - BlockHash: ethCommon.BytesToHash(celoReceipt.BlockHash.Bytes()), - BlockNumber: celoReceipt.BlockNumber, - TransactionIndex: celoReceipt.TransactionIndex, - } -} - -func convertCeloLogFromEth(l *ethTypes.Log) *celoTypes.Log { - topics := make([]celoCommon.Hash, len(l.Topics)) - for n, t := range l.Topics { - topics[n] = celoCommon.BytesToHash(t.Bytes()) - } - - return &celoTypes.Log{ - Address: celoCommon.BytesToAddress(l.Address.Bytes()), - Topics: topics, - Data: l.Data, - BlockNumber: l.BlockNumber, - TxHash: celoCommon.BytesToHash(l.TxHash.Bytes()), - TxIndex: l.TxIndex, - BlockHash: celoCommon.BytesToHash(l.BlockHash.Bytes()), - Index: l.Index, - Removed: l.Removed, - } -} diff --git a/node/pkg/watchers/evm/connectors/celoabi/abi.go b/node/pkg/watchers/evm/connectors/celoabi/abi.go deleted file mode 100644 index 7e0a186a35..0000000000 --- a/node/pkg/watchers/evm/connectors/celoabi/abi.go +++ /dev/null @@ -1,1900 +0,0 @@ -// Code generated - DO NOT EDIT. -// This file is a generated binding and any manual changes will be lost. - -package celoabi - -import ( - "errors" - "math/big" - "strings" - - ethereum "github.com/celo-org/celo-blockchain" - "github.com/celo-org/celo-blockchain/accounts/abi" - "github.com/celo-org/celo-blockchain/accounts/abi/bind" - "github.com/celo-org/celo-blockchain/common" - "github.com/celo-org/celo-blockchain/core/types" - "github.com/celo-org/celo-blockchain/event" -) - -// Reference imports to suppress errors if they are not otherwise used. -var ( - _ = errors.New - _ = big.NewInt - _ = strings.NewReader - _ = ethereum.NotFound - _ = bind.Bind - _ = common.Big1 - _ = types.BloomLookup - _ = event.NewSubscription -) - -// GovernanceStructsContractUpgrade is an auto generated low-level Go binding around an user-defined struct. -type GovernanceStructsContractUpgrade struct { - Module [32]byte - Action uint8 - Chain uint16 - NewContract common.Address -} - -// GovernanceStructsGuardianSetUpgrade is an auto generated low-level Go binding around an user-defined struct. -type GovernanceStructsGuardianSetUpgrade struct { - Module [32]byte - Action uint8 - Chain uint16 - NewGuardianSet StructsGuardianSet - NewGuardianSetIndex uint32 -} - -// GovernanceStructsSetMessageFee is an auto generated low-level Go binding around an user-defined struct. -type GovernanceStructsSetMessageFee struct { - Module [32]byte - Action uint8 - Chain uint16 - MessageFee *big.Int -} - -// GovernanceStructsTransferFees is an auto generated low-level Go binding around an user-defined struct. -type GovernanceStructsTransferFees struct { - Module [32]byte - Action uint8 - Chain uint16 - Amount *big.Int - Recipient [32]byte -} - -// StructsGuardianSet is an auto generated low-level Go binding around an user-defined struct. -type StructsGuardianSet struct { - Keys []common.Address - ExpirationTime uint32 -} - -// StructsSignature is an auto generated low-level Go binding around an user-defined struct. -type StructsSignature struct { - R [32]byte - S [32]byte - V uint8 - GuardianIndex uint8 -} - -// StructsVM is an auto generated low-level Go binding around an user-defined struct. -type StructsVM struct { - Version uint8 - Timestamp uint32 - Nonce uint32 - EmitterChainId uint16 - EmitterAddress [32]byte - Sequence uint64 - ConsistencyLevel uint8 - Payload []byte - GuardianSetIndex uint32 - Signatures []StructsSignature - Hash [32]byte -} - -// AbiMetaData contains all meta data concerning the Abi contract. -var AbiMetaData = &bind.MetaData{ - ABI: "[{\"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\":\"beacon\",\"type\":\"address\"}],\"name\":\"BeaconUpgraded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"oldContract\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newContract\",\"type\":\"address\"}],\"name\":\"ContractUpgraded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"index\",\"type\":\"uint32\"}],\"name\":\"GuardianSetAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sequence\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"nonce\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"payload\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"consistencyLevel\",\"type\":\"uint8\"}],\"name\":\"LogMessagePublished\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\",\"payable\":true},{\"inputs\":[],\"name\":\"chainId\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\",\"constant\":true},{\"inputs\":[],\"name\":\"getCurrentGuardianSetIndex\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\",\"constant\":true},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"index\",\"type\":\"uint32\"}],\"name\":\"getGuardianSet\",\"outputs\":[{\"components\":[{\"internalType\":\"address[]\",\"name\":\"keys\",\"type\":\"address[]\"},{\"internalType\":\"uint32\",\"name\":\"expirationTime\",\"type\":\"uint32\"}],\"internalType\":\"structStructs.GuardianSet\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\",\"constant\":true},{\"inputs\":[],\"name\":\"getGuardianSetExpiry\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\",\"constant\":true},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"hash\",\"type\":\"bytes32\"}],\"name\":\"governanceActionIsConsumed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\",\"constant\":true},{\"inputs\":[],\"name\":\"governanceChainId\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\",\"constant\":true},{\"inputs\":[],\"name\":\"governanceContract\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\",\"constant\":true},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"impl\",\"type\":\"address\"}],\"name\":\"isInitialized\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\",\"constant\":true},{\"inputs\":[],\"name\":\"messageFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\",\"constant\":true},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"emitter\",\"type\":\"address\"}],\"name\":\"nextSequence\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\",\"constant\":true},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"encodedVM\",\"type\":\"bytes\"}],\"name\":\"parseAndVerifyVM\",\"outputs\":[{\"components\":[{\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"},{\"internalType\":\"uint32\",\"name\":\"timestamp\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"nonce\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"emitterChainId\",\"type\":\"uint16\"},{\"internalType\":\"bytes32\",\"name\":\"emitterAddress\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sequence\",\"type\":\"uint64\"},{\"internalType\":\"uint8\",\"name\":\"consistencyLevel\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"payload\",\"type\":\"bytes\"},{\"internalType\":\"uint32\",\"name\":\"guardianSetIndex\",\"type\":\"uint32\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"},{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"guardianIndex\",\"type\":\"uint8\"}],\"internalType\":\"structStructs.Signature[]\",\"name\":\"signatures\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes32\",\"name\":\"hash\",\"type\":\"bytes32\"}],\"internalType\":\"structStructs.VM\",\"name\":\"vm\",\"type\":\"tuple\"},{\"internalType\":\"bool\",\"name\":\"valid\",\"type\":\"bool\"},{\"internalType\":\"string\",\"name\":\"reason\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\",\"constant\":true},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"encodedUpgrade\",\"type\":\"bytes\"}],\"name\":\"parseContractUpgrade\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"module\",\"type\":\"bytes32\"},{\"internalType\":\"uint8\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"uint16\",\"name\":\"chain\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"newContract\",\"type\":\"address\"}],\"internalType\":\"structGovernanceStructs.ContractUpgrade\",\"name\":\"cu\",\"type\":\"tuple\"}],\"stateMutability\":\"pure\",\"type\":\"function\",\"constant\":true},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"encodedUpgrade\",\"type\":\"bytes\"}],\"name\":\"parseGuardianSetUpgrade\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"module\",\"type\":\"bytes32\"},{\"internalType\":\"uint8\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"uint16\",\"name\":\"chain\",\"type\":\"uint16\"},{\"components\":[{\"internalType\":\"address[]\",\"name\":\"keys\",\"type\":\"address[]\"},{\"internalType\":\"uint32\",\"name\":\"expirationTime\",\"type\":\"uint32\"}],\"internalType\":\"structStructs.GuardianSet\",\"name\":\"newGuardianSet\",\"type\":\"tuple\"},{\"internalType\":\"uint32\",\"name\":\"newGuardianSetIndex\",\"type\":\"uint32\"}],\"internalType\":\"structGovernanceStructs.GuardianSetUpgrade\",\"name\":\"gsu\",\"type\":\"tuple\"}],\"stateMutability\":\"pure\",\"type\":\"function\",\"constant\":true},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"encodedSetMessageFee\",\"type\":\"bytes\"}],\"name\":\"parseSetMessageFee\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"module\",\"type\":\"bytes32\"},{\"internalType\":\"uint8\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"uint16\",\"name\":\"chain\",\"type\":\"uint16\"},{\"internalType\":\"uint256\",\"name\":\"messageFee\",\"type\":\"uint256\"}],\"internalType\":\"structGovernanceStructs.SetMessageFee\",\"name\":\"smf\",\"type\":\"tuple\"}],\"stateMutability\":\"pure\",\"type\":\"function\",\"constant\":true},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"encodedTransferFees\",\"type\":\"bytes\"}],\"name\":\"parseTransferFees\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"module\",\"type\":\"bytes32\"},{\"internalType\":\"uint8\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"uint16\",\"name\":\"chain\",\"type\":\"uint16\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"recipient\",\"type\":\"bytes32\"}],\"internalType\":\"structGovernanceStructs.TransferFees\",\"name\":\"tf\",\"type\":\"tuple\"}],\"stateMutability\":\"pure\",\"type\":\"function\",\"constant\":true},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"encodedVM\",\"type\":\"bytes\"}],\"name\":\"parseVM\",\"outputs\":[{\"components\":[{\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"},{\"internalType\":\"uint32\",\"name\":\"timestamp\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"nonce\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"emitterChainId\",\"type\":\"uint16\"},{\"internalType\":\"bytes32\",\"name\":\"emitterAddress\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sequence\",\"type\":\"uint64\"},{\"internalType\":\"uint8\",\"name\":\"consistencyLevel\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"payload\",\"type\":\"bytes\"},{\"internalType\":\"uint32\",\"name\":\"guardianSetIndex\",\"type\":\"uint32\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"},{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"guardianIndex\",\"type\":\"uint8\"}],\"internalType\":\"structStructs.Signature[]\",\"name\":\"signatures\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes32\",\"name\":\"hash\",\"type\":\"bytes32\"}],\"internalType\":\"structStructs.VM\",\"name\":\"vm\",\"type\":\"tuple\"}],\"stateMutability\":\"pure\",\"type\":\"function\",\"constant\":true},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_vm\",\"type\":\"bytes\"}],\"name\":\"submitContractUpgrade\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_vm\",\"type\":\"bytes\"}],\"name\":\"submitNewGuardianSet\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_vm\",\"type\":\"bytes\"}],\"name\":\"submitSetMessageFee\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_vm\",\"type\":\"bytes\"}],\"name\":\"submitTransferFees\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"hash\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"},{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"guardianIndex\",\"type\":\"uint8\"}],\"internalType\":\"structStructs.Signature[]\",\"name\":\"signatures\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"address[]\",\"name\":\"keys\",\"type\":\"address[]\"},{\"internalType\":\"uint32\",\"name\":\"expirationTime\",\"type\":\"uint32\"}],\"internalType\":\"structStructs.GuardianSet\",\"name\":\"guardianSet\",\"type\":\"tuple\"}],\"name\":\"verifySignatures\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"valid\",\"type\":\"bool\"},{\"internalType\":\"string\",\"name\":\"reason\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\",\"constant\":true},{\"inputs\":[{\"components\":[{\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"},{\"internalType\":\"uint32\",\"name\":\"timestamp\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"nonce\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"emitterChainId\",\"type\":\"uint16\"},{\"internalType\":\"bytes32\",\"name\":\"emitterAddress\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sequence\",\"type\":\"uint64\"},{\"internalType\":\"uint8\",\"name\":\"consistencyLevel\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"payload\",\"type\":\"bytes\"},{\"internalType\":\"uint32\",\"name\":\"guardianSetIndex\",\"type\":\"uint32\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"},{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"guardianIndex\",\"type\":\"uint8\"}],\"internalType\":\"structStructs.Signature[]\",\"name\":\"signatures\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes32\",\"name\":\"hash\",\"type\":\"bytes32\"}],\"internalType\":\"structStructs.VM\",\"name\":\"vm\",\"type\":\"tuple\"}],\"name\":\"verifyVM\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"valid\",\"type\":\"bool\"},{\"internalType\":\"string\",\"name\":\"reason\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\",\"constant\":true},{\"stateMutability\":\"payable\",\"type\":\"receive\",\"payable\":true},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"nonce\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"payload\",\"type\":\"bytes\"},{\"internalType\":\"uint8\",\"name\":\"consistencyLevel\",\"type\":\"uint8\"}],\"name\":\"publishMessage\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"sequence\",\"type\":\"uint64\"}],\"stateMutability\":\"payable\",\"type\":\"function\",\"payable\":true}]", -} - -// AbiABI is the input ABI used to generate the binding from. -// Deprecated: Use AbiMetaData.ABI instead. -var AbiABI = AbiMetaData.ABI - -// Abi is an auto generated Go binding around an Ethereum contract. -type Abi struct { - AbiCaller // Read-only binding to the contract - AbiTransactor // Write-only binding to the contract - AbiFilterer // Log filterer for contract events -} - -// AbiCaller is an auto generated read-only Go binding around an Ethereum contract. -type AbiCaller struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// AbiTransactor is an auto generated write-only Go binding around an Ethereum contract. -type AbiTransactor struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// AbiFilterer is an auto generated log filtering Go binding around an Ethereum contract events. -type AbiFilterer struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// AbiSession is an auto generated Go binding around an Ethereum contract, -// with pre-set call and transact options. -type AbiSession struct { - Contract *Abi // 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 -} - -// AbiCallerSession is an auto generated read-only Go binding around an Ethereum contract, -// with pre-set call options. -type AbiCallerSession struct { - Contract *AbiCaller // Generic contract caller binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session -} - -// AbiTransactorSession is an auto generated write-only Go binding around an Ethereum contract, -// with pre-set transact options. -type AbiTransactorSession struct { - Contract *AbiTransactor // Generic contract transactor binding to set the session for - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session -} - -// AbiRaw is an auto generated low-level Go binding around an Ethereum contract. -type AbiRaw struct { - Contract *Abi // Generic contract binding to access the raw methods on -} - -// AbiCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. -type AbiCallerRaw struct { - Contract *AbiCaller // Generic read-only contract binding to access the raw methods on -} - -// AbiTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. -type AbiTransactorRaw struct { - Contract *AbiTransactor // Generic write-only contract binding to access the raw methods on -} - -// NewAbi creates a new instance of Abi, bound to a specific deployed contract. -func NewAbi(address common.Address, backend bind.ContractBackend) (*Abi, error) { - contract, err := bindAbi(address, backend, backend, backend) - if err != nil { - return nil, err - } - return &Abi{AbiCaller: AbiCaller{contract: contract}, AbiTransactor: AbiTransactor{contract: contract}, AbiFilterer: AbiFilterer{contract: contract}}, nil -} - -// NewAbiCaller creates a new read-only instance of Abi, bound to a specific deployed contract. -func NewAbiCaller(address common.Address, caller bind.ContractCaller) (*AbiCaller, error) { - contract, err := bindAbi(address, caller, nil, nil) - if err != nil { - return nil, err - } - return &AbiCaller{contract: contract}, nil -} - -// NewAbiTransactor creates a new write-only instance of Abi, bound to a specific deployed contract. -func NewAbiTransactor(address common.Address, transactor bind.ContractTransactor) (*AbiTransactor, error) { - contract, err := bindAbi(address, nil, transactor, nil) - if err != nil { - return nil, err - } - return &AbiTransactor{contract: contract}, nil -} - -// NewAbiFilterer creates a new log filterer instance of Abi, bound to a specific deployed contract. -func NewAbiFilterer(address common.Address, filterer bind.ContractFilterer) (*AbiFilterer, error) { - contract, err := bindAbi(address, nil, nil, filterer) - if err != nil { - return nil, err - } - return &AbiFilterer{contract: contract}, nil -} - -// bindAbi binds a generic wrapper to an already deployed contract. -func bindAbi(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(AbiABI)) - if err != nil { - return nil, err - } - return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil -} - -// ParseAbiABI parses the ABI -func ParseAbiABI() (*abi.ABI, error) { - parsed, err := abi.JSON(strings.NewReader(AbiABI)) - if err != nil { - return nil, err - } - return &parsed, 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 (_Abi *AbiRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _Abi.Contract.AbiCaller.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 (_Abi *AbiRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _Abi.Contract.AbiTransactor.contract.Transfer(opts) -} - -// Transact invokes the (paid) contract method with params as input values. -func (_Abi *AbiRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _Abi.Contract.AbiTransactor.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 (_Abi *AbiCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _Abi.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 (_Abi *AbiTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _Abi.Contract.contract.Transfer(opts) -} - -// Transact invokes the (paid) contract method with params as input values. -func (_Abi *AbiTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _Abi.Contract.contract.Transact(opts, method, params...) -} - -// ChainId is a free data retrieval call binding the contract method 0x9a8a0592. -// -// Solidity: function chainId() view returns(uint16) -func (_Abi *AbiCaller) ChainId(opts *bind.CallOpts) (uint16, error) { - var out []interface{} - err := _Abi.contract.Call(opts, &out, "chainId") - - if err != nil { - return *new(uint16), err - } - - out0 := *abi.ConvertType(out[0], new(uint16)).(*uint16) - - return out0, err - -} - -// ChainId is a free data retrieval call binding the contract method 0x9a8a0592. -// -// Solidity: function chainId() view returns(uint16) -func (_Abi *AbiSession) ChainId() (uint16, error) { - return _Abi.Contract.ChainId(&_Abi.CallOpts) -} - -// ChainId is a free data retrieval call binding the contract method 0x9a8a0592. -// -// Solidity: function chainId() view returns(uint16) -func (_Abi *AbiCallerSession) ChainId() (uint16, error) { - return _Abi.Contract.ChainId(&_Abi.CallOpts) -} - -// GetCurrentGuardianSetIndex is a free data retrieval call binding the contract method 0x1cfe7951. -// -// Solidity: function getCurrentGuardianSetIndex() view returns(uint32) -func (_Abi *AbiCaller) GetCurrentGuardianSetIndex(opts *bind.CallOpts) (uint32, error) { - var out []interface{} - err := _Abi.contract.Call(opts, &out, "getCurrentGuardianSetIndex") - - if err != nil { - return *new(uint32), err - } - - out0 := *abi.ConvertType(out[0], new(uint32)).(*uint32) - - return out0, err - -} - -// GetCurrentGuardianSetIndex is a free data retrieval call binding the contract method 0x1cfe7951. -// -// Solidity: function getCurrentGuardianSetIndex() view returns(uint32) -func (_Abi *AbiSession) GetCurrentGuardianSetIndex() (uint32, error) { - return _Abi.Contract.GetCurrentGuardianSetIndex(&_Abi.CallOpts) -} - -// GetCurrentGuardianSetIndex is a free data retrieval call binding the contract method 0x1cfe7951. -// -// Solidity: function getCurrentGuardianSetIndex() view returns(uint32) -func (_Abi *AbiCallerSession) GetCurrentGuardianSetIndex() (uint32, error) { - return _Abi.Contract.GetCurrentGuardianSetIndex(&_Abi.CallOpts) -} - -// GetGuardianSet is a free data retrieval call binding the contract method 0xf951975a. -// -// Solidity: function getGuardianSet(uint32 index) view returns((address[],uint32)) -func (_Abi *AbiCaller) GetGuardianSet(opts *bind.CallOpts, index uint32) (StructsGuardianSet, error) { - var out []interface{} - err := _Abi.contract.Call(opts, &out, "getGuardianSet", index) - - if err != nil { - return *new(StructsGuardianSet), err - } - - out0 := *abi.ConvertType(out[0], new(StructsGuardianSet)).(*StructsGuardianSet) - - return out0, err - -} - -// GetGuardianSet is a free data retrieval call binding the contract method 0xf951975a. -// -// Solidity: function getGuardianSet(uint32 index) view returns((address[],uint32)) -func (_Abi *AbiSession) GetGuardianSet(index uint32) (StructsGuardianSet, error) { - return _Abi.Contract.GetGuardianSet(&_Abi.CallOpts, index) -} - -// GetGuardianSet is a free data retrieval call binding the contract method 0xf951975a. -// -// Solidity: function getGuardianSet(uint32 index) view returns((address[],uint32)) -func (_Abi *AbiCallerSession) GetGuardianSet(index uint32) (StructsGuardianSet, error) { - return _Abi.Contract.GetGuardianSet(&_Abi.CallOpts, index) -} - -// GetGuardianSetExpiry is a free data retrieval call binding the contract method 0xeb8d3f12. -// -// Solidity: function getGuardianSetExpiry() view returns(uint32) -func (_Abi *AbiCaller) GetGuardianSetExpiry(opts *bind.CallOpts) (uint32, error) { - var out []interface{} - err := _Abi.contract.Call(opts, &out, "getGuardianSetExpiry") - - if err != nil { - return *new(uint32), err - } - - out0 := *abi.ConvertType(out[0], new(uint32)).(*uint32) - - return out0, err - -} - -// GetGuardianSetExpiry is a free data retrieval call binding the contract method 0xeb8d3f12. -// -// Solidity: function getGuardianSetExpiry() view returns(uint32) -func (_Abi *AbiSession) GetGuardianSetExpiry() (uint32, error) { - return _Abi.Contract.GetGuardianSetExpiry(&_Abi.CallOpts) -} - -// GetGuardianSetExpiry is a free data retrieval call binding the contract method 0xeb8d3f12. -// -// Solidity: function getGuardianSetExpiry() view returns(uint32) -func (_Abi *AbiCallerSession) GetGuardianSetExpiry() (uint32, error) { - return _Abi.Contract.GetGuardianSetExpiry(&_Abi.CallOpts) -} - -// GovernanceActionIsConsumed is a free data retrieval call binding the contract method 0x2c3c02a4. -// -// Solidity: function governanceActionIsConsumed(bytes32 hash) view returns(bool) -func (_Abi *AbiCaller) GovernanceActionIsConsumed(opts *bind.CallOpts, hash [32]byte) (bool, error) { - var out []interface{} - err := _Abi.contract.Call(opts, &out, "governanceActionIsConsumed", hash) - - if err != nil { - return *new(bool), err - } - - out0 := *abi.ConvertType(out[0], new(bool)).(*bool) - - return out0, err - -} - -// GovernanceActionIsConsumed is a free data retrieval call binding the contract method 0x2c3c02a4. -// -// Solidity: function governanceActionIsConsumed(bytes32 hash) view returns(bool) -func (_Abi *AbiSession) GovernanceActionIsConsumed(hash [32]byte) (bool, error) { - return _Abi.Contract.GovernanceActionIsConsumed(&_Abi.CallOpts, hash) -} - -// GovernanceActionIsConsumed is a free data retrieval call binding the contract method 0x2c3c02a4. -// -// Solidity: function governanceActionIsConsumed(bytes32 hash) view returns(bool) -func (_Abi *AbiCallerSession) GovernanceActionIsConsumed(hash [32]byte) (bool, error) { - return _Abi.Contract.GovernanceActionIsConsumed(&_Abi.CallOpts, hash) -} - -// GovernanceChainId is a free data retrieval call binding the contract method 0xfbe3c2cd. -// -// Solidity: function governanceChainId() view returns(uint16) -func (_Abi *AbiCaller) GovernanceChainId(opts *bind.CallOpts) (uint16, error) { - var out []interface{} - err := _Abi.contract.Call(opts, &out, "governanceChainId") - - if err != nil { - return *new(uint16), err - } - - out0 := *abi.ConvertType(out[0], new(uint16)).(*uint16) - - return out0, err - -} - -// GovernanceChainId is a free data retrieval call binding the contract method 0xfbe3c2cd. -// -// Solidity: function governanceChainId() view returns(uint16) -func (_Abi *AbiSession) GovernanceChainId() (uint16, error) { - return _Abi.Contract.GovernanceChainId(&_Abi.CallOpts) -} - -// GovernanceChainId is a free data retrieval call binding the contract method 0xfbe3c2cd. -// -// Solidity: function governanceChainId() view returns(uint16) -func (_Abi *AbiCallerSession) GovernanceChainId() (uint16, error) { - return _Abi.Contract.GovernanceChainId(&_Abi.CallOpts) -} - -// GovernanceContract is a free data retrieval call binding the contract method 0xb172b222. -// -// Solidity: function governanceContract() view returns(bytes32) -func (_Abi *AbiCaller) GovernanceContract(opts *bind.CallOpts) ([32]byte, error) { - var out []interface{} - err := _Abi.contract.Call(opts, &out, "governanceContract") - - if err != nil { - return *new([32]byte), err - } - - out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) - - return out0, err - -} - -// GovernanceContract is a free data retrieval call binding the contract method 0xb172b222. -// -// Solidity: function governanceContract() view returns(bytes32) -func (_Abi *AbiSession) GovernanceContract() ([32]byte, error) { - return _Abi.Contract.GovernanceContract(&_Abi.CallOpts) -} - -// GovernanceContract is a free data retrieval call binding the contract method 0xb172b222. -// -// Solidity: function governanceContract() view returns(bytes32) -func (_Abi *AbiCallerSession) GovernanceContract() ([32]byte, error) { - return _Abi.Contract.GovernanceContract(&_Abi.CallOpts) -} - -// IsInitialized is a free data retrieval call binding the contract method 0xd60b347f. -// -// Solidity: function isInitialized(address impl) view returns(bool) -func (_Abi *AbiCaller) IsInitialized(opts *bind.CallOpts, impl common.Address) (bool, error) { - var out []interface{} - err := _Abi.contract.Call(opts, &out, "isInitialized", impl) - - if err != nil { - return *new(bool), err - } - - out0 := *abi.ConvertType(out[0], new(bool)).(*bool) - - return out0, err - -} - -// IsInitialized is a free data retrieval call binding the contract method 0xd60b347f. -// -// Solidity: function isInitialized(address impl) view returns(bool) -func (_Abi *AbiSession) IsInitialized(impl common.Address) (bool, error) { - return _Abi.Contract.IsInitialized(&_Abi.CallOpts, impl) -} - -// IsInitialized is a free data retrieval call binding the contract method 0xd60b347f. -// -// Solidity: function isInitialized(address impl) view returns(bool) -func (_Abi *AbiCallerSession) IsInitialized(impl common.Address) (bool, error) { - return _Abi.Contract.IsInitialized(&_Abi.CallOpts, impl) -} - -// MessageFee is a free data retrieval call binding the contract method 0x1a90a219. -// -// Solidity: function messageFee() view returns(uint256) -func (_Abi *AbiCaller) MessageFee(opts *bind.CallOpts) (*big.Int, error) { - var out []interface{} - err := _Abi.contract.Call(opts, &out, "messageFee") - - if err != nil { - return *new(*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - - return out0, err - -} - -// MessageFee is a free data retrieval call binding the contract method 0x1a90a219. -// -// Solidity: function messageFee() view returns(uint256) -func (_Abi *AbiSession) MessageFee() (*big.Int, error) { - return _Abi.Contract.MessageFee(&_Abi.CallOpts) -} - -// MessageFee is a free data retrieval call binding the contract method 0x1a90a219. -// -// Solidity: function messageFee() view returns(uint256) -func (_Abi *AbiCallerSession) MessageFee() (*big.Int, error) { - return _Abi.Contract.MessageFee(&_Abi.CallOpts) -} - -// NextSequence is a free data retrieval call binding the contract method 0x4cf842b5. -// -// Solidity: function nextSequence(address emitter) view returns(uint64) -func (_Abi *AbiCaller) NextSequence(opts *bind.CallOpts, emitter common.Address) (uint64, error) { - var out []interface{} - err := _Abi.contract.Call(opts, &out, "nextSequence", emitter) - - if err != nil { - return *new(uint64), err - } - - out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) - - return out0, err - -} - -// NextSequence is a free data retrieval call binding the contract method 0x4cf842b5. -// -// Solidity: function nextSequence(address emitter) view returns(uint64) -func (_Abi *AbiSession) NextSequence(emitter common.Address) (uint64, error) { - return _Abi.Contract.NextSequence(&_Abi.CallOpts, emitter) -} - -// NextSequence is a free data retrieval call binding the contract method 0x4cf842b5. -// -// Solidity: function nextSequence(address emitter) view returns(uint64) -func (_Abi *AbiCallerSession) NextSequence(emitter common.Address) (uint64, error) { - return _Abi.Contract.NextSequence(&_Abi.CallOpts, emitter) -} - -// ParseAndVerifyVM is a free data retrieval call binding the contract method 0xc0fd8bde. -// -// Solidity: function parseAndVerifyVM(bytes encodedVM) view returns((uint8,uint32,uint32,uint16,bytes32,uint64,uint8,bytes,uint32,(bytes32,bytes32,uint8,uint8)[],bytes32) vm, bool valid, string reason) -func (_Abi *AbiCaller) ParseAndVerifyVM(opts *bind.CallOpts, encodedVM []byte) (struct { - Vm StructsVM - Valid bool - Reason string -}, error) { - var out []interface{} - err := _Abi.contract.Call(opts, &out, "parseAndVerifyVM", encodedVM) - - outstruct := new(struct { - Vm StructsVM - Valid bool - Reason string - }) - if err != nil { - return *outstruct, err - } - - outstruct.Vm = *abi.ConvertType(out[0], new(StructsVM)).(*StructsVM) - outstruct.Valid = *abi.ConvertType(out[1], new(bool)).(*bool) - outstruct.Reason = *abi.ConvertType(out[2], new(string)).(*string) - - return *outstruct, err - -} - -// ParseAndVerifyVM is a free data retrieval call binding the contract method 0xc0fd8bde. -// -// Solidity: function parseAndVerifyVM(bytes encodedVM) view returns((uint8,uint32,uint32,uint16,bytes32,uint64,uint8,bytes,uint32,(bytes32,bytes32,uint8,uint8)[],bytes32) vm, bool valid, string reason) -func (_Abi *AbiSession) ParseAndVerifyVM(encodedVM []byte) (struct { - Vm StructsVM - Valid bool - Reason string -}, error) { - return _Abi.Contract.ParseAndVerifyVM(&_Abi.CallOpts, encodedVM) -} - -// ParseAndVerifyVM is a free data retrieval call binding the contract method 0xc0fd8bde. -// -// Solidity: function parseAndVerifyVM(bytes encodedVM) view returns((uint8,uint32,uint32,uint16,bytes32,uint64,uint8,bytes,uint32,(bytes32,bytes32,uint8,uint8)[],bytes32) vm, bool valid, string reason) -func (_Abi *AbiCallerSession) ParseAndVerifyVM(encodedVM []byte) (struct { - Vm StructsVM - Valid bool - Reason string -}, error) { - return _Abi.Contract.ParseAndVerifyVM(&_Abi.CallOpts, encodedVM) -} - -// ParseContractUpgrade is a free data retrieval call binding the contract method 0x4fdc60fa. -// -// Solidity: function parseContractUpgrade(bytes encodedUpgrade) pure returns((bytes32,uint8,uint16,address) cu) -func (_Abi *AbiCaller) ParseContractUpgrade(opts *bind.CallOpts, encodedUpgrade []byte) (GovernanceStructsContractUpgrade, error) { - var out []interface{} - err := _Abi.contract.Call(opts, &out, "parseContractUpgrade", encodedUpgrade) - - if err != nil { - return *new(GovernanceStructsContractUpgrade), err - } - - out0 := *abi.ConvertType(out[0], new(GovernanceStructsContractUpgrade)).(*GovernanceStructsContractUpgrade) - - return out0, err - -} - -// ParseContractUpgrade is a free data retrieval call binding the contract method 0x4fdc60fa. -// -// Solidity: function parseContractUpgrade(bytes encodedUpgrade) pure returns((bytes32,uint8,uint16,address) cu) -func (_Abi *AbiSession) ParseContractUpgrade(encodedUpgrade []byte) (GovernanceStructsContractUpgrade, error) { - return _Abi.Contract.ParseContractUpgrade(&_Abi.CallOpts, encodedUpgrade) -} - -// ParseContractUpgrade is a free data retrieval call binding the contract method 0x4fdc60fa. -// -// Solidity: function parseContractUpgrade(bytes encodedUpgrade) pure returns((bytes32,uint8,uint16,address) cu) -func (_Abi *AbiCallerSession) ParseContractUpgrade(encodedUpgrade []byte) (GovernanceStructsContractUpgrade, error) { - return _Abi.Contract.ParseContractUpgrade(&_Abi.CallOpts, encodedUpgrade) -} - -// ParseGuardianSetUpgrade is a free data retrieval call binding the contract method 0x04ca84cf. -// -// Solidity: function parseGuardianSetUpgrade(bytes encodedUpgrade) pure returns((bytes32,uint8,uint16,(address[],uint32),uint32) gsu) -func (_Abi *AbiCaller) ParseGuardianSetUpgrade(opts *bind.CallOpts, encodedUpgrade []byte) (GovernanceStructsGuardianSetUpgrade, error) { - var out []interface{} - err := _Abi.contract.Call(opts, &out, "parseGuardianSetUpgrade", encodedUpgrade) - - if err != nil { - return *new(GovernanceStructsGuardianSetUpgrade), err - } - - out0 := *abi.ConvertType(out[0], new(GovernanceStructsGuardianSetUpgrade)).(*GovernanceStructsGuardianSetUpgrade) - - return out0, err - -} - -// ParseGuardianSetUpgrade is a free data retrieval call binding the contract method 0x04ca84cf. -// -// Solidity: function parseGuardianSetUpgrade(bytes encodedUpgrade) pure returns((bytes32,uint8,uint16,(address[],uint32),uint32) gsu) -func (_Abi *AbiSession) ParseGuardianSetUpgrade(encodedUpgrade []byte) (GovernanceStructsGuardianSetUpgrade, error) { - return _Abi.Contract.ParseGuardianSetUpgrade(&_Abi.CallOpts, encodedUpgrade) -} - -// ParseGuardianSetUpgrade is a free data retrieval call binding the contract method 0x04ca84cf. -// -// Solidity: function parseGuardianSetUpgrade(bytes encodedUpgrade) pure returns((bytes32,uint8,uint16,(address[],uint32),uint32) gsu) -func (_Abi *AbiCallerSession) ParseGuardianSetUpgrade(encodedUpgrade []byte) (GovernanceStructsGuardianSetUpgrade, error) { - return _Abi.Contract.ParseGuardianSetUpgrade(&_Abi.CallOpts, encodedUpgrade) -} - -// ParseSetMessageFee is a free data retrieval call binding the contract method 0x515f3247. -// -// Solidity: function parseSetMessageFee(bytes encodedSetMessageFee) pure returns((bytes32,uint8,uint16,uint256) smf) -func (_Abi *AbiCaller) ParseSetMessageFee(opts *bind.CallOpts, encodedSetMessageFee []byte) (GovernanceStructsSetMessageFee, error) { - var out []interface{} - err := _Abi.contract.Call(opts, &out, "parseSetMessageFee", encodedSetMessageFee) - - if err != nil { - return *new(GovernanceStructsSetMessageFee), err - } - - out0 := *abi.ConvertType(out[0], new(GovernanceStructsSetMessageFee)).(*GovernanceStructsSetMessageFee) - - return out0, err - -} - -// ParseSetMessageFee is a free data retrieval call binding the contract method 0x515f3247. -// -// Solidity: function parseSetMessageFee(bytes encodedSetMessageFee) pure returns((bytes32,uint8,uint16,uint256) smf) -func (_Abi *AbiSession) ParseSetMessageFee(encodedSetMessageFee []byte) (GovernanceStructsSetMessageFee, error) { - return _Abi.Contract.ParseSetMessageFee(&_Abi.CallOpts, encodedSetMessageFee) -} - -// ParseSetMessageFee is a free data retrieval call binding the contract method 0x515f3247. -// -// Solidity: function parseSetMessageFee(bytes encodedSetMessageFee) pure returns((bytes32,uint8,uint16,uint256) smf) -func (_Abi *AbiCallerSession) ParseSetMessageFee(encodedSetMessageFee []byte) (GovernanceStructsSetMessageFee, error) { - return _Abi.Contract.ParseSetMessageFee(&_Abi.CallOpts, encodedSetMessageFee) -} - -// ParseTransferFees is a free data retrieval call binding the contract method 0x0319e59c. -// -// Solidity: function parseTransferFees(bytes encodedTransferFees) pure returns((bytes32,uint8,uint16,uint256,bytes32) tf) -func (_Abi *AbiCaller) ParseTransferFees(opts *bind.CallOpts, encodedTransferFees []byte) (GovernanceStructsTransferFees, error) { - var out []interface{} - err := _Abi.contract.Call(opts, &out, "parseTransferFees", encodedTransferFees) - - if err != nil { - return *new(GovernanceStructsTransferFees), err - } - - out0 := *abi.ConvertType(out[0], new(GovernanceStructsTransferFees)).(*GovernanceStructsTransferFees) - - return out0, err - -} - -// ParseTransferFees is a free data retrieval call binding the contract method 0x0319e59c. -// -// Solidity: function parseTransferFees(bytes encodedTransferFees) pure returns((bytes32,uint8,uint16,uint256,bytes32) tf) -func (_Abi *AbiSession) ParseTransferFees(encodedTransferFees []byte) (GovernanceStructsTransferFees, error) { - return _Abi.Contract.ParseTransferFees(&_Abi.CallOpts, encodedTransferFees) -} - -// ParseTransferFees is a free data retrieval call binding the contract method 0x0319e59c. -// -// Solidity: function parseTransferFees(bytes encodedTransferFees) pure returns((bytes32,uint8,uint16,uint256,bytes32) tf) -func (_Abi *AbiCallerSession) ParseTransferFees(encodedTransferFees []byte) (GovernanceStructsTransferFees, error) { - return _Abi.Contract.ParseTransferFees(&_Abi.CallOpts, encodedTransferFees) -} - -// ParseVM is a free data retrieval call binding the contract method 0xa9e11893. -// -// Solidity: function parseVM(bytes encodedVM) pure returns((uint8,uint32,uint32,uint16,bytes32,uint64,uint8,bytes,uint32,(bytes32,bytes32,uint8,uint8)[],bytes32) vm) -func (_Abi *AbiCaller) ParseVM(opts *bind.CallOpts, encodedVM []byte) (StructsVM, error) { - var out []interface{} - err := _Abi.contract.Call(opts, &out, "parseVM", encodedVM) - - if err != nil { - return *new(StructsVM), err - } - - out0 := *abi.ConvertType(out[0], new(StructsVM)).(*StructsVM) - - return out0, err - -} - -// ParseVM is a free data retrieval call binding the contract method 0xa9e11893. -// -// Solidity: function parseVM(bytes encodedVM) pure returns((uint8,uint32,uint32,uint16,bytes32,uint64,uint8,bytes,uint32,(bytes32,bytes32,uint8,uint8)[],bytes32) vm) -func (_Abi *AbiSession) ParseVM(encodedVM []byte) (StructsVM, error) { - return _Abi.Contract.ParseVM(&_Abi.CallOpts, encodedVM) -} - -// ParseVM is a free data retrieval call binding the contract method 0xa9e11893. -// -// Solidity: function parseVM(bytes encodedVM) pure returns((uint8,uint32,uint32,uint16,bytes32,uint64,uint8,bytes,uint32,(bytes32,bytes32,uint8,uint8)[],bytes32) vm) -func (_Abi *AbiCallerSession) ParseVM(encodedVM []byte) (StructsVM, error) { - return _Abi.Contract.ParseVM(&_Abi.CallOpts, encodedVM) -} - -// VerifySignatures is a free data retrieval call binding the contract method 0xa0cce1b3. -// -// Solidity: function verifySignatures(bytes32 hash, (bytes32,bytes32,uint8,uint8)[] signatures, (address[],uint32) guardianSet) pure returns(bool valid, string reason) -func (_Abi *AbiCaller) VerifySignatures(opts *bind.CallOpts, hash [32]byte, signatures []StructsSignature, guardianSet StructsGuardianSet) (struct { - Valid bool - Reason string -}, error) { - var out []interface{} - err := _Abi.contract.Call(opts, &out, "verifySignatures", hash, signatures, guardianSet) - - outstruct := new(struct { - Valid bool - Reason string - }) - if err != nil { - return *outstruct, err - } - - outstruct.Valid = *abi.ConvertType(out[0], new(bool)).(*bool) - outstruct.Reason = *abi.ConvertType(out[1], new(string)).(*string) - - return *outstruct, err - -} - -// VerifySignatures is a free data retrieval call binding the contract method 0xa0cce1b3. -// -// Solidity: function verifySignatures(bytes32 hash, (bytes32,bytes32,uint8,uint8)[] signatures, (address[],uint32) guardianSet) pure returns(bool valid, string reason) -func (_Abi *AbiSession) VerifySignatures(hash [32]byte, signatures []StructsSignature, guardianSet StructsGuardianSet) (struct { - Valid bool - Reason string -}, error) { - return _Abi.Contract.VerifySignatures(&_Abi.CallOpts, hash, signatures, guardianSet) -} - -// VerifySignatures is a free data retrieval call binding the contract method 0xa0cce1b3. -// -// Solidity: function verifySignatures(bytes32 hash, (bytes32,bytes32,uint8,uint8)[] signatures, (address[],uint32) guardianSet) pure returns(bool valid, string reason) -func (_Abi *AbiCallerSession) VerifySignatures(hash [32]byte, signatures []StructsSignature, guardianSet StructsGuardianSet) (struct { - Valid bool - Reason string -}, error) { - return _Abi.Contract.VerifySignatures(&_Abi.CallOpts, hash, signatures, guardianSet) -} - -// VerifyVM is a free data retrieval call binding the contract method 0x875be02a. -// -// Solidity: function verifyVM((uint8,uint32,uint32,uint16,bytes32,uint64,uint8,bytes,uint32,(bytes32,bytes32,uint8,uint8)[],bytes32) vm) view returns(bool valid, string reason) -func (_Abi *AbiCaller) VerifyVM(opts *bind.CallOpts, vm StructsVM) (struct { - Valid bool - Reason string -}, error) { - var out []interface{} - err := _Abi.contract.Call(opts, &out, "verifyVM", vm) - - outstruct := new(struct { - Valid bool - Reason string - }) - if err != nil { - return *outstruct, err - } - - outstruct.Valid = *abi.ConvertType(out[0], new(bool)).(*bool) - outstruct.Reason = *abi.ConvertType(out[1], new(string)).(*string) - - return *outstruct, err - -} - -// VerifyVM is a free data retrieval call binding the contract method 0x875be02a. -// -// Solidity: function verifyVM((uint8,uint32,uint32,uint16,bytes32,uint64,uint8,bytes,uint32,(bytes32,bytes32,uint8,uint8)[],bytes32) vm) view returns(bool valid, string reason) -func (_Abi *AbiSession) VerifyVM(vm StructsVM) (struct { - Valid bool - Reason string -}, error) { - return _Abi.Contract.VerifyVM(&_Abi.CallOpts, vm) -} - -// VerifyVM is a free data retrieval call binding the contract method 0x875be02a. -// -// Solidity: function verifyVM((uint8,uint32,uint32,uint16,bytes32,uint64,uint8,bytes,uint32,(bytes32,bytes32,uint8,uint8)[],bytes32) vm) view returns(bool valid, string reason) -func (_Abi *AbiCallerSession) VerifyVM(vm StructsVM) (struct { - Valid bool - Reason string -}, error) { - return _Abi.Contract.VerifyVM(&_Abi.CallOpts, vm) -} - -// PublishMessage is a paid mutator transaction binding the contract method 0xb19a437e. -// -// Solidity: function publishMessage(uint32 nonce, bytes payload, uint8 consistencyLevel) payable returns(uint64 sequence) -func (_Abi *AbiTransactor) PublishMessage(opts *bind.TransactOpts, nonce uint32, payload []byte, consistencyLevel uint8) (*types.Transaction, error) { - return _Abi.contract.Transact(opts, "publishMessage", nonce, payload, consistencyLevel) -} - -// PublishMessage is a paid mutator transaction binding the contract method 0xb19a437e. -// -// Solidity: function publishMessage(uint32 nonce, bytes payload, uint8 consistencyLevel) payable returns(uint64 sequence) -func (_Abi *AbiSession) PublishMessage(nonce uint32, payload []byte, consistencyLevel uint8) (*types.Transaction, error) { - return _Abi.Contract.PublishMessage(&_Abi.TransactOpts, nonce, payload, consistencyLevel) -} - -// PublishMessage is a paid mutator transaction binding the contract method 0xb19a437e. -// -// Solidity: function publishMessage(uint32 nonce, bytes payload, uint8 consistencyLevel) payable returns(uint64 sequence) -func (_Abi *AbiTransactorSession) PublishMessage(nonce uint32, payload []byte, consistencyLevel uint8) (*types.Transaction, error) { - return _Abi.Contract.PublishMessage(&_Abi.TransactOpts, nonce, payload, consistencyLevel) -} - -// SubmitContractUpgrade is a paid mutator transaction binding the contract method 0x5cb8cae2. -// -// Solidity: function submitContractUpgrade(bytes _vm) returns() -func (_Abi *AbiTransactor) SubmitContractUpgrade(opts *bind.TransactOpts, _vm []byte) (*types.Transaction, error) { - return _Abi.contract.Transact(opts, "submitContractUpgrade", _vm) -} - -// SubmitContractUpgrade is a paid mutator transaction binding the contract method 0x5cb8cae2. -// -// Solidity: function submitContractUpgrade(bytes _vm) returns() -func (_Abi *AbiSession) SubmitContractUpgrade(_vm []byte) (*types.Transaction, error) { - return _Abi.Contract.SubmitContractUpgrade(&_Abi.TransactOpts, _vm) -} - -// SubmitContractUpgrade is a paid mutator transaction binding the contract method 0x5cb8cae2. -// -// Solidity: function submitContractUpgrade(bytes _vm) returns() -func (_Abi *AbiTransactorSession) SubmitContractUpgrade(_vm []byte) (*types.Transaction, error) { - return _Abi.Contract.SubmitContractUpgrade(&_Abi.TransactOpts, _vm) -} - -// SubmitNewGuardianSet is a paid mutator transaction binding the contract method 0x6606b4e0. -// -// Solidity: function submitNewGuardianSet(bytes _vm) returns() -func (_Abi *AbiTransactor) SubmitNewGuardianSet(opts *bind.TransactOpts, _vm []byte) (*types.Transaction, error) { - return _Abi.contract.Transact(opts, "submitNewGuardianSet", _vm) -} - -// SubmitNewGuardianSet is a paid mutator transaction binding the contract method 0x6606b4e0. -// -// Solidity: function submitNewGuardianSet(bytes _vm) returns() -func (_Abi *AbiSession) SubmitNewGuardianSet(_vm []byte) (*types.Transaction, error) { - return _Abi.Contract.SubmitNewGuardianSet(&_Abi.TransactOpts, _vm) -} - -// SubmitNewGuardianSet is a paid mutator transaction binding the contract method 0x6606b4e0. -// -// Solidity: function submitNewGuardianSet(bytes _vm) returns() -func (_Abi *AbiTransactorSession) SubmitNewGuardianSet(_vm []byte) (*types.Transaction, error) { - return _Abi.Contract.SubmitNewGuardianSet(&_Abi.TransactOpts, _vm) -} - -// SubmitSetMessageFee is a paid mutator transaction binding the contract method 0xf42bc641. -// -// Solidity: function submitSetMessageFee(bytes _vm) returns() -func (_Abi *AbiTransactor) SubmitSetMessageFee(opts *bind.TransactOpts, _vm []byte) (*types.Transaction, error) { - return _Abi.contract.Transact(opts, "submitSetMessageFee", _vm) -} - -// SubmitSetMessageFee is a paid mutator transaction binding the contract method 0xf42bc641. -// -// Solidity: function submitSetMessageFee(bytes _vm) returns() -func (_Abi *AbiSession) SubmitSetMessageFee(_vm []byte) (*types.Transaction, error) { - return _Abi.Contract.SubmitSetMessageFee(&_Abi.TransactOpts, _vm) -} - -// SubmitSetMessageFee is a paid mutator transaction binding the contract method 0xf42bc641. -// -// Solidity: function submitSetMessageFee(bytes _vm) returns() -func (_Abi *AbiTransactorSession) SubmitSetMessageFee(_vm []byte) (*types.Transaction, error) { - return _Abi.Contract.SubmitSetMessageFee(&_Abi.TransactOpts, _vm) -} - -// SubmitTransferFees is a paid mutator transaction binding the contract method 0x93df337e. -// -// Solidity: function submitTransferFees(bytes _vm) returns() -func (_Abi *AbiTransactor) SubmitTransferFees(opts *bind.TransactOpts, _vm []byte) (*types.Transaction, error) { - return _Abi.contract.Transact(opts, "submitTransferFees", _vm) -} - -// SubmitTransferFees is a paid mutator transaction binding the contract method 0x93df337e. -// -// Solidity: function submitTransferFees(bytes _vm) returns() -func (_Abi *AbiSession) SubmitTransferFees(_vm []byte) (*types.Transaction, error) { - return _Abi.Contract.SubmitTransferFees(&_Abi.TransactOpts, _vm) -} - -// SubmitTransferFees is a paid mutator transaction binding the contract method 0x93df337e. -// -// Solidity: function submitTransferFees(bytes _vm) returns() -func (_Abi *AbiTransactorSession) SubmitTransferFees(_vm []byte) (*types.Transaction, error) { - return _Abi.Contract.SubmitTransferFees(&_Abi.TransactOpts, _vm) -} - -// TryParseLog attempts to parse a log. Returns the parsed log, evenName and whether it was succesfull -func (_Abi *AbiFilterer) TryParseLog(log types.Log) (eventName string, event interface{}, ok bool, err error) { - eventName, ok, err = _Abi.contract.LogEventName(log) - if err != nil || !ok { - return "", nil, false, err - } - - switch eventName { - case "AdminChanged": - event, err = _Abi.ParseAdminChanged(log) - case "BeaconUpgraded": - event, err = _Abi.ParseBeaconUpgraded(log) - case "ContractUpgraded": - event, err = _Abi.ParseContractUpgraded(log) - case "GuardianSetAdded": - event, err = _Abi.ParseGuardianSetAdded(log) - case "LogMessagePublished": - event, err = _Abi.ParseLogMessagePublished(log) - case "Upgraded": - event, err = _Abi.ParseUpgraded(log) - } - if err != nil { - return "", nil, false, err - } - - return eventName, event, ok, nil -} - -// Fallback is a paid mutator transaction binding the contract fallback function. -// -// Solidity: fallback() payable returns() -func (_Abi *AbiTransactor) Fallback(opts *bind.TransactOpts, calldata []byte) (*types.Transaction, error) { - return _Abi.contract.RawTransact(opts, calldata) -} - -// Fallback is a paid mutator transaction binding the contract fallback function. -// -// Solidity: fallback() payable returns() -func (_Abi *AbiSession) Fallback(calldata []byte) (*types.Transaction, error) { - return _Abi.Contract.Fallback(&_Abi.TransactOpts, calldata) -} - -// Fallback is a paid mutator transaction binding the contract fallback function. -// -// Solidity: fallback() payable returns() -func (_Abi *AbiTransactorSession) Fallback(calldata []byte) (*types.Transaction, error) { - return _Abi.Contract.Fallback(&_Abi.TransactOpts, calldata) -} - -// Receive is a paid mutator transaction binding the contract receive function. -// -// Solidity: receive() payable returns() -func (_Abi *AbiTransactor) Receive(opts *bind.TransactOpts) (*types.Transaction, error) { - return _Abi.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 (_Abi *AbiSession) Receive() (*types.Transaction, error) { - return _Abi.Contract.Receive(&_Abi.TransactOpts) -} - -// Receive is a paid mutator transaction binding the contract receive function. -// -// Solidity: receive() payable returns() -func (_Abi *AbiTransactorSession) Receive() (*types.Transaction, error) { - return _Abi.Contract.Receive(&_Abi.TransactOpts) -} - -// AbiAdminChangedIterator is returned from FilterAdminChanged and is used to iterate over the raw logs and unpacked data for AdminChanged events raised by the Abi contract. -type AbiAdminChangedIterator struct { - Event *AbiAdminChanged // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} - -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *AbiAdminChangedIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(AbiAdminChanged) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(AbiAdminChanged) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -// Error returns any retrieval or parsing error occurred during filtering. -func (it *AbiAdminChangedIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *AbiAdminChangedIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// AbiAdminChanged represents a AdminChanged event raised by the Abi contract. -type AbiAdminChanged 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 (_Abi *AbiFilterer) FilterAdminChanged(opts *bind.FilterOpts) (*AbiAdminChangedIterator, error) { - - logs, sub, err := _Abi.contract.FilterLogs(opts, "AdminChanged") - if err != nil { - return nil, err - } - return &AbiAdminChangedIterator{contract: _Abi.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 (_Abi *AbiFilterer) WatchAdminChanged(opts *bind.WatchOpts, sink chan<- *AbiAdminChanged) (event.Subscription, error) { - - logs, sub, err := _Abi.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(AbiAdminChanged) - if err := _Abi.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 (_Abi *AbiFilterer) ParseAdminChanged(log types.Log) (*AbiAdminChanged, error) { - event := new(AbiAdminChanged) - if err := _Abi.contract.UnpackLog(event, "AdminChanged", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -// AbiBeaconUpgradedIterator is returned from FilterBeaconUpgraded and is used to iterate over the raw logs and unpacked data for BeaconUpgraded events raised by the Abi contract. -type AbiBeaconUpgradedIterator struct { - Event *AbiBeaconUpgraded // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} - -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *AbiBeaconUpgradedIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(AbiBeaconUpgraded) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(AbiBeaconUpgraded) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -// Error returns any retrieval or parsing error occurred during filtering. -func (it *AbiBeaconUpgradedIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *AbiBeaconUpgradedIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// AbiBeaconUpgraded represents a BeaconUpgraded event raised by the Abi contract. -type AbiBeaconUpgraded struct { - Beacon common.Address - Raw types.Log // Blockchain specific contextual infos -} - -// FilterBeaconUpgraded is a free log retrieval operation binding the contract event 0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e. -// -// Solidity: event BeaconUpgraded(address indexed beacon) -func (_Abi *AbiFilterer) FilterBeaconUpgraded(opts *bind.FilterOpts, beacon []common.Address) (*AbiBeaconUpgradedIterator, error) { - - var beaconRule []interface{} - for _, beaconItem := range beacon { - beaconRule = append(beaconRule, beaconItem) - } - - logs, sub, err := _Abi.contract.FilterLogs(opts, "BeaconUpgraded", beaconRule) - if err != nil { - return nil, err - } - return &AbiBeaconUpgradedIterator{contract: _Abi.contract, event: "BeaconUpgraded", logs: logs, sub: sub}, nil -} - -// WatchBeaconUpgraded is a free log subscription operation binding the contract event 0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e. -// -// Solidity: event BeaconUpgraded(address indexed beacon) -func (_Abi *AbiFilterer) WatchBeaconUpgraded(opts *bind.WatchOpts, sink chan<- *AbiBeaconUpgraded, beacon []common.Address) (event.Subscription, error) { - - var beaconRule []interface{} - for _, beaconItem := range beacon { - beaconRule = append(beaconRule, beaconItem) - } - - logs, sub, err := _Abi.contract.WatchLogs(opts, "BeaconUpgraded", beaconRule) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(AbiBeaconUpgraded) - if err := _Abi.contract.UnpackLog(event, "BeaconUpgraded", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -// ParseBeaconUpgraded is a log parse operation binding the contract event 0x1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e. -// -// Solidity: event BeaconUpgraded(address indexed beacon) -func (_Abi *AbiFilterer) ParseBeaconUpgraded(log types.Log) (*AbiBeaconUpgraded, error) { - event := new(AbiBeaconUpgraded) - if err := _Abi.contract.UnpackLog(event, "BeaconUpgraded", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -// AbiContractUpgradedIterator is returned from FilterContractUpgraded and is used to iterate over the raw logs and unpacked data for ContractUpgraded events raised by the Abi contract. -type AbiContractUpgradedIterator struct { - Event *AbiContractUpgraded // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} - -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *AbiContractUpgradedIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(AbiContractUpgraded) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(AbiContractUpgraded) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -// Error returns any retrieval or parsing error occurred during filtering. -func (it *AbiContractUpgradedIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *AbiContractUpgradedIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// AbiContractUpgraded represents a ContractUpgraded event raised by the Abi contract. -type AbiContractUpgraded struct { - OldContract common.Address - NewContract common.Address - Raw types.Log // Blockchain specific contextual infos -} - -// FilterContractUpgraded is a free log retrieval operation binding the contract event 0x2e4cc16c100f0b55e2df82ab0b1a7e294aa9cbd01b48fbaf622683fbc0507a49. -// -// Solidity: event ContractUpgraded(address indexed oldContract, address indexed newContract) -func (_Abi *AbiFilterer) FilterContractUpgraded(opts *bind.FilterOpts, oldContract []common.Address, newContract []common.Address) (*AbiContractUpgradedIterator, error) { - - var oldContractRule []interface{} - for _, oldContractItem := range oldContract { - oldContractRule = append(oldContractRule, oldContractItem) - } - var newContractRule []interface{} - for _, newContractItem := range newContract { - newContractRule = append(newContractRule, newContractItem) - } - - logs, sub, err := _Abi.contract.FilterLogs(opts, "ContractUpgraded", oldContractRule, newContractRule) - if err != nil { - return nil, err - } - return &AbiContractUpgradedIterator{contract: _Abi.contract, event: "ContractUpgraded", logs: logs, sub: sub}, nil -} - -// WatchContractUpgraded is a free log subscription operation binding the contract event 0x2e4cc16c100f0b55e2df82ab0b1a7e294aa9cbd01b48fbaf622683fbc0507a49. -// -// Solidity: event ContractUpgraded(address indexed oldContract, address indexed newContract) -func (_Abi *AbiFilterer) WatchContractUpgraded(opts *bind.WatchOpts, sink chan<- *AbiContractUpgraded, oldContract []common.Address, newContract []common.Address) (event.Subscription, error) { - - var oldContractRule []interface{} - for _, oldContractItem := range oldContract { - oldContractRule = append(oldContractRule, oldContractItem) - } - var newContractRule []interface{} - for _, newContractItem := range newContract { - newContractRule = append(newContractRule, newContractItem) - } - - logs, sub, err := _Abi.contract.WatchLogs(opts, "ContractUpgraded", oldContractRule, newContractRule) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(AbiContractUpgraded) - if err := _Abi.contract.UnpackLog(event, "ContractUpgraded", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -// ParseContractUpgraded is a log parse operation binding the contract event 0x2e4cc16c100f0b55e2df82ab0b1a7e294aa9cbd01b48fbaf622683fbc0507a49. -// -// Solidity: event ContractUpgraded(address indexed oldContract, address indexed newContract) -func (_Abi *AbiFilterer) ParseContractUpgraded(log types.Log) (*AbiContractUpgraded, error) { - event := new(AbiContractUpgraded) - if err := _Abi.contract.UnpackLog(event, "ContractUpgraded", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -// AbiGuardianSetAddedIterator is returned from FilterGuardianSetAdded and is used to iterate over the raw logs and unpacked data for GuardianSetAdded events raised by the Abi contract. -type AbiGuardianSetAddedIterator struct { - Event *AbiGuardianSetAdded // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} - -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *AbiGuardianSetAddedIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(AbiGuardianSetAdded) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(AbiGuardianSetAdded) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -// Error returns any retrieval or parsing error occurred during filtering. -func (it *AbiGuardianSetAddedIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *AbiGuardianSetAddedIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// AbiGuardianSetAdded represents a GuardianSetAdded event raised by the Abi contract. -type AbiGuardianSetAdded struct { - Index uint32 - Raw types.Log // Blockchain specific contextual infos -} - -// FilterGuardianSetAdded is a free log retrieval operation binding the contract event 0x2384dbc52f7b617fb7c5aa71e5455a21ff21d58604bb6daef6af2bb44aadebdd. -// -// Solidity: event GuardianSetAdded(uint32 indexed index) -func (_Abi *AbiFilterer) FilterGuardianSetAdded(opts *bind.FilterOpts, index []uint32) (*AbiGuardianSetAddedIterator, error) { - - var indexRule []interface{} - for _, indexItem := range index { - indexRule = append(indexRule, indexItem) - } - - logs, sub, err := _Abi.contract.FilterLogs(opts, "GuardianSetAdded", indexRule) - if err != nil { - return nil, err - } - return &AbiGuardianSetAddedIterator{contract: _Abi.contract, event: "GuardianSetAdded", logs: logs, sub: sub}, nil -} - -// WatchGuardianSetAdded is a free log subscription operation binding the contract event 0x2384dbc52f7b617fb7c5aa71e5455a21ff21d58604bb6daef6af2bb44aadebdd. -// -// Solidity: event GuardianSetAdded(uint32 indexed index) -func (_Abi *AbiFilterer) WatchGuardianSetAdded(opts *bind.WatchOpts, sink chan<- *AbiGuardianSetAdded, index []uint32) (event.Subscription, error) { - - var indexRule []interface{} - for _, indexItem := range index { - indexRule = append(indexRule, indexItem) - } - - logs, sub, err := _Abi.contract.WatchLogs(opts, "GuardianSetAdded", indexRule) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(AbiGuardianSetAdded) - if err := _Abi.contract.UnpackLog(event, "GuardianSetAdded", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -// ParseGuardianSetAdded is a log parse operation binding the contract event 0x2384dbc52f7b617fb7c5aa71e5455a21ff21d58604bb6daef6af2bb44aadebdd. -// -// Solidity: event GuardianSetAdded(uint32 indexed index) -func (_Abi *AbiFilterer) ParseGuardianSetAdded(log types.Log) (*AbiGuardianSetAdded, error) { - event := new(AbiGuardianSetAdded) - if err := _Abi.contract.UnpackLog(event, "GuardianSetAdded", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -// AbiLogMessagePublishedIterator is returned from FilterLogMessagePublished and is used to iterate over the raw logs and unpacked data for LogMessagePublished events raised by the Abi contract. -type AbiLogMessagePublishedIterator struct { - Event *AbiLogMessagePublished // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} - -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *AbiLogMessagePublishedIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(AbiLogMessagePublished) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(AbiLogMessagePublished) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -// Error returns any retrieval or parsing error occurred during filtering. -func (it *AbiLogMessagePublishedIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *AbiLogMessagePublishedIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// AbiLogMessagePublished represents a LogMessagePublished event raised by the Abi contract. -type AbiLogMessagePublished struct { - Sender common.Address - Sequence uint64 - Nonce uint32 - Payload []byte - ConsistencyLevel uint8 - Raw types.Log // Blockchain specific contextual infos -} - -// FilterLogMessagePublished is a free log retrieval operation binding the contract event 0x6eb224fb001ed210e379b335e35efe88672a8ce935d981a6896b27ffdf52a3b2. -// -// Solidity: event LogMessagePublished(address indexed sender, uint64 sequence, uint32 nonce, bytes payload, uint8 consistencyLevel) -func (_Abi *AbiFilterer) FilterLogMessagePublished(opts *bind.FilterOpts, sender []common.Address) (*AbiLogMessagePublishedIterator, error) { - - var senderRule []interface{} - for _, senderItem := range sender { - senderRule = append(senderRule, senderItem) - } - - logs, sub, err := _Abi.contract.FilterLogs(opts, "LogMessagePublished", senderRule) - if err != nil { - return nil, err - } - return &AbiLogMessagePublishedIterator{contract: _Abi.contract, event: "LogMessagePublished", logs: logs, sub: sub}, nil -} - -// WatchLogMessagePublished is a free log subscription operation binding the contract event 0x6eb224fb001ed210e379b335e35efe88672a8ce935d981a6896b27ffdf52a3b2. -// -// Solidity: event LogMessagePublished(address indexed sender, uint64 sequence, uint32 nonce, bytes payload, uint8 consistencyLevel) -func (_Abi *AbiFilterer) WatchLogMessagePublished(opts *bind.WatchOpts, sink chan<- *AbiLogMessagePublished, sender []common.Address) (event.Subscription, error) { - - var senderRule []interface{} - for _, senderItem := range sender { - senderRule = append(senderRule, senderItem) - } - - logs, sub, err := _Abi.contract.WatchLogs(opts, "LogMessagePublished", 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(AbiLogMessagePublished) - if err := _Abi.contract.UnpackLog(event, "LogMessagePublished", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -// ParseLogMessagePublished is a log parse operation binding the contract event 0x6eb224fb001ed210e379b335e35efe88672a8ce935d981a6896b27ffdf52a3b2. -// -// Solidity: event LogMessagePublished(address indexed sender, uint64 sequence, uint32 nonce, bytes payload, uint8 consistencyLevel) -func (_Abi *AbiFilterer) ParseLogMessagePublished(log types.Log) (*AbiLogMessagePublished, error) { - event := new(AbiLogMessagePublished) - if err := _Abi.contract.UnpackLog(event, "LogMessagePublished", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -// AbiUpgradedIterator is returned from FilterUpgraded and is used to iterate over the raw logs and unpacked data for Upgraded events raised by the Abi contract. -type AbiUpgradedIterator struct { - Event *AbiUpgraded // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} - -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *AbiUpgradedIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(AbiUpgraded) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(AbiUpgraded) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -// Error returns any retrieval or parsing error occurred during filtering. -func (it *AbiUpgradedIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *AbiUpgradedIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// AbiUpgraded represents a Upgraded event raised by the Abi contract. -type AbiUpgraded 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 (_Abi *AbiFilterer) FilterUpgraded(opts *bind.FilterOpts, implementation []common.Address) (*AbiUpgradedIterator, error) { - - var implementationRule []interface{} - for _, implementationItem := range implementation { - implementationRule = append(implementationRule, implementationItem) - } - - logs, sub, err := _Abi.contract.FilterLogs(opts, "Upgraded", implementationRule) - if err != nil { - return nil, err - } - return &AbiUpgradedIterator{contract: _Abi.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 (_Abi *AbiFilterer) WatchUpgraded(opts *bind.WatchOpts, sink chan<- *AbiUpgraded, implementation []common.Address) (event.Subscription, error) { - - var implementationRule []interface{} - for _, implementationItem := range implementation { - implementationRule = append(implementationRule, implementationItem) - } - - logs, sub, err := _Abi.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(AbiUpgraded) - if err := _Abi.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 (_Abi *AbiFilterer) ParseUpgraded(log types.Log) (*AbiUpgraded, error) { - event := new(AbiUpgraded) - if err := _Abi.contract.UnpackLog(event, "Upgraded", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} diff --git a/node/pkg/watchers/evm/watcher.go b/node/pkg/watchers/evm/watcher.go index a0b5a75859..32e53cb219 100644 --- a/node/pkg/watchers/evm/watcher.go +++ b/node/pkg/watchers/evm/watcher.go @@ -120,8 +120,8 @@ type ( currentGuardianSet *uint32 // Interface to the chain specific ethereum library. - ethConn connectors.Connector - unsafeDevMode bool + ethConn connectors.Connector + env common.Environment latestBlockNumber uint64 latestSafeBlockNumber uint64 @@ -163,7 +163,7 @@ func NewEthWatcher( obsvReqC <-chan *gossipv1.ObservationRequest, queryReqC <-chan *query.PerChainQueryInternal, queryResponseC chan<- *query.PerChainQueryResponseInternal, - unsafeDevMode bool, + env common.Environment, ccqBackfillCache bool, ) *Watcher { return &Watcher{ @@ -178,7 +178,7 @@ func NewEthWatcher( queryReqC: queryReqC, queryResponseC: queryResponseC, pending: map[pendingKey]*pendingMessage{}, - unsafeDevMode: unsafeDevMode, + env: env, ccqConfig: query.GetPerChainConfig(chainID), ccqMaxBlockNumber: big.NewInt(0).SetUint64(math.MaxUint64), ccqBackfillCache: ccqBackfillCache, @@ -197,7 +197,7 @@ func (w *Watcher) Run(parentCtx context.Context) error { zap.String("contract", w.contract.String()), zap.String("networkName", w.networkName), zap.String("chainID", w.chainID.String()), - zap.Bool("unsafeDevMode", w.unsafeDevMode), + zap.String("env", string(w.env)), ) // later on we will spawn multiple go-routines through `RunWithScissors`, i.e. catching panics. @@ -232,15 +232,6 @@ func (w *Watcher) Run(parentCtx context.Context) error { return fmt.Errorf("dialing eth client failed: %w", err) } w.ethConn = connectors.NewBatchPollConnector(ctx, logger, baseConnector, safePollingSupported, 1000*time.Millisecond) - } else if w.chainID == vaa.ChainIDCelo { - // When we are running in mainnet or testnet, we need to use the Celo ethereum library rather than go-ethereum. - // However, in devnet, we currently run the standard ETH node for Celo, so we need to use the standard go-ethereum. - w.ethConn, err = connectors.NewCeloConnector(timeout, w.networkName, w.url, w.contract, logger) - if err != nil { - ethConnectionErrors.WithLabelValues(w.networkName, "dial_error").Inc() - p2p.DefaultRegistry.AddErrorCount(w.chainID, 1) - return fmt.Errorf("dialing eth client failed: %w", err) - } } else { // Everything else is instant finality. logger.Info("assuming instant finality") @@ -259,7 +250,7 @@ func (w *Watcher) Run(parentCtx context.Context) error { } if w.ccqConfig.TimestampCacheSupported { - w.ccqTimestampCache = NewBlocksByTimestamp(BTS_MAX_BLOCKS, w.unsafeDevMode) + w.ccqTimestampCache = NewBlocksByTimestamp(BTS_MAX_BLOCKS, (w.env == common.UnsafeDevNet)) } errC := make(chan error) @@ -336,7 +327,7 @@ func (w *Watcher) Run(parentCtx context.Context) error { if msg.ConsistencyLevel == vaa.ConsistencyLevelPublishImmediately { logger.Info("re-observed message publication transaction, publishing it immediately", zap.String("msgId", msg.MessageIDString()), - zap.Stringer("txHash", msg.TxHash), + zap.String("txHash", msg.TxIDString()), zap.Uint64("current_block", blockNumberU), zap.Uint64("observed_block", blockNumber), ) @@ -348,7 +339,7 @@ func (w *Watcher) Run(parentCtx context.Context) error { if safeBlockNumberU == 0 { logger.Error("no safe block number available, ignoring observation request", zap.String("msgId", msg.MessageIDString()), - zap.Stringer("txHash", msg.TxHash), + zap.String("txHash", msg.TxIDString()), ) continue } @@ -356,7 +347,7 @@ func (w *Watcher) Run(parentCtx context.Context) error { if blockNumber <= safeBlockNumberU { logger.Info("re-observed message publication transaction", zap.String("msgId", msg.MessageIDString()), - zap.Stringer("txHash", msg.TxHash), + zap.String("txHash", msg.TxIDString()), zap.Uint64("current_safe_block", safeBlockNumberU), zap.Uint64("observed_block", blockNumber), ) @@ -364,7 +355,7 @@ func (w *Watcher) Run(parentCtx context.Context) error { } else { logger.Info("ignoring re-observed message publication transaction", zap.String("msgId", msg.MessageIDString()), - zap.Stringer("txHash", msg.TxHash), + zap.String("txHash", msg.TxIDString()), zap.Uint64("current_safe_block", safeBlockNumberU), zap.Uint64("observed_block", blockNumber), ) @@ -376,7 +367,7 @@ func (w *Watcher) Run(parentCtx context.Context) error { if blockNumberU == 0 { logger.Error("no block number available, ignoring observation request", zap.String("msgId", msg.MessageIDString()), - zap.Stringer("txHash", msg.TxHash), + zap.String("txHash", msg.TxIDString()), ) continue } @@ -393,7 +384,7 @@ func (w *Watcher) Run(parentCtx context.Context) error { if blockNumber <= blockNumberU { logger.Info("re-observed message publication transaction", zap.String("msgId", msg.MessageIDString()), - zap.Stringer("txHash", msg.TxHash), + zap.String("txHash", msg.TxIDString()), zap.Uint64("current_block", blockNumberU), zap.Uint64("observed_block", blockNumber), ) @@ -401,7 +392,7 @@ func (w *Watcher) Run(parentCtx context.Context) error { } else { logger.Info("ignoring re-observed message publication transaction", zap.String("msgId", msg.MessageIDString()), - zap.Stringer("txHash", msg.TxHash), + zap.String("txHash", msg.TxIDString()), zap.Uint64("current_block", blockNumberU), zap.Uint64("observed_block", blockNumber), ) @@ -521,7 +512,7 @@ func (w *Watcher) Run(parentCtx context.Context) error { if pLock.height <= blockNumberU { msm := time.Now() timeout, cancel := context.WithTimeout(ctx, 5*time.Second) - tx, err := w.ethConn.TransactionReceipt(timeout, pLock.message.TxHash) + tx, err := w.ethConn.TransactionReceipt(timeout, eth_common.BytesToHash(pLock.message.TxID)) queryLatency.WithLabelValues(w.networkName, "transaction_receipt").Observe(time.Since(msm).Seconds()) cancel() @@ -536,7 +527,7 @@ func (w *Watcher) Run(parentCtx context.Context) error { if tx == nil || err == rpc.ErrNoResult || (err != nil && err.Error() == "not found") { logger.Warn("tx was orphaned", zap.String("msgId", pLock.message.MessageIDString()), - zap.Stringer("txHash", pLock.message.TxHash), + zap.String("txHash", pLock.message.TxIDString()), zap.Stringer("blockHash", key.BlockHash), zap.Uint64("target_blockNum", pLock.height), zap.Stringer("current_blockNum", ev.Number), @@ -554,7 +545,7 @@ func (w *Watcher) Run(parentCtx context.Context) error { if tx.Status != 1 { logger.Error("transaction receipt with non-success status", zap.String("msgId", pLock.message.MessageIDString()), - zap.Stringer("txHash", pLock.message.TxHash), + zap.String("txHash", pLock.message.TxIDString()), zap.Stringer("blockHash", key.BlockHash), zap.Uint64("target_blockNum", pLock.height), zap.Stringer("current_blockNum", ev.Number), @@ -572,7 +563,7 @@ func (w *Watcher) Run(parentCtx context.Context) error { // An error from this "transient" case has persisted for more than MaxWaitConfirmations. logger.Info("observation timed out", zap.String("msgId", pLock.message.MessageIDString()), - zap.Stringer("txHash", pLock.message.TxHash), + zap.String("txHash", pLock.message.TxIDString()), zap.Stringer("blockHash", key.BlockHash), zap.Uint64("target_blockNum", pLock.height), zap.Stringer("current_blockNum", ev.Number), @@ -584,7 +575,7 @@ func (w *Watcher) Run(parentCtx context.Context) error { } else { logger.Warn("transaction could not be fetched", zap.String("msgId", pLock.message.MessageIDString()), - zap.Stringer("txHash", pLock.message.TxHash), + zap.String("txHash", pLock.message.TxIDString()), zap.Stringer("blockHash", key.BlockHash), zap.Uint64("target_blockNum", pLock.height), zap.Stringer("current_blockNum", ev.Number), @@ -601,7 +592,7 @@ func (w *Watcher) Run(parentCtx context.Context) error { if tx.BlockHash != key.BlockHash { logger.Info("tx got dropped and mined in a different block; the message should have been reobserved", zap.String("msgId", pLock.message.MessageIDString()), - zap.Stringer("txHash", pLock.message.TxHash), + zap.String("txHash", pLock.message.TxIDString()), zap.Stringer("blockHash", key.BlockHash), zap.Uint64("target_blockNum", pLock.height), zap.Stringer("current_blockNum", ev.Number), @@ -615,7 +606,7 @@ func (w *Watcher) Run(parentCtx context.Context) error { logger.Info("observation confirmed", zap.String("msgId", pLock.message.MessageIDString()), - zap.Stringer("txHash", pLock.message.TxHash), + zap.String("txHash", pLock.message.TxIDString()), zap.Stringer("blockHash", key.BlockHash), zap.Uint64("target_blockNum", pLock.height), zap.Stringer("current_blockNum", ev.Number), @@ -706,7 +697,7 @@ func (w *Watcher) getFinality(ctx context.Context) (bool, bool, error) { safe := false // Tilt supports polling for both finalized and safe. - if w.unsafeDevMode { + if w.env == common.UnsafeDevNet { finalized = true safe = true @@ -724,10 +715,12 @@ func (w *Watcher) getFinality(ctx context.Context) (bool, bool, error) { w.chainID == vaa.ChainIDInk || w.chainID == vaa.ChainIDKarura || w.chainID == vaa.ChainIDMantle || + w.chainID == vaa.ChainIDMonad || w.chainID == vaa.ChainIDMonadDevnet || w.chainID == vaa.ChainIDMoonbeam || w.chainID == vaa.ChainIDOptimism || w.chainID == vaa.ChainIDOptimismSepolia || + w.chainID == vaa.ChainIDSeiEVM || w.chainID == vaa.ChainIDSepolia || w.chainID == vaa.ChainIDSnaxchain || w.chainID == vaa.ChainIDUnichain || @@ -736,9 +729,11 @@ func (w *Watcher) getFinality(ctx context.Context) (bool, bool, error) { finalized = true safe = true - // The following chains have their own specialized finalizers. } else if w.chainID == vaa.ChainIDCelo { - return false, false, nil + // TODO: Celo testnet now supports finalized and safe. As of January 2025, mainnet doesn't yet support safe. Once Celo mainnet cuts over, Celo can + // be added to the list above. That change won't be super urgent since we'll just continue to publish safe as finalized, which is not a huge deal. + finalized = true + safe = w.env != common.MainNet // Polygon now supports polling for finalized but not safe. // https://forum.polygon.technology/t/optimizing-decentralized-apps-ux-with-milestones-a-significantly-accelerated-finality-solution/13154 @@ -837,7 +832,7 @@ func (w *Watcher) getBlockTime(ctx context.Context, blockHash eth_common.Hash) ( // postMessage creates a message object from a log event and adds it to the pending list for processing. func (w *Watcher) postMessage(logger *zap.Logger, ev *ethabi.AbiLogMessagePublished, blockTime uint64) { message := &common.MessagePublication{ - TxHash: ev.Raw.TxHash, + TxID: ev.Raw.TxHash.Bytes(), Timestamp: time.Unix(int64(blockTime), 0), Nonce: ev.Nonce, Sequence: ev.Sequence, @@ -852,7 +847,7 @@ func (w *Watcher) postMessage(logger *zap.Logger, ev *ethabi.AbiLogMessagePublis if message.ConsistencyLevel == vaa.ConsistencyLevelPublishImmediately { logger.Info("found new message publication transaction, publishing it immediately", zap.String("msgId", message.MessageIDString()), - zap.Stringer("txHash", message.TxHash), + zap.String("txHash", message.TxIDString()), zap.Uint64("blockNum", ev.Raw.BlockNumber), zap.Uint64("latestFinalizedBlock", atomic.LoadUint64(&w.latestFinalizedBlockNumber)), zap.Stringer("blockHash", ev.Raw.BlockHash), @@ -868,7 +863,7 @@ func (w *Watcher) postMessage(logger *zap.Logger, ev *ethabi.AbiLogMessagePublis logger.Info("found new message publication transaction", zap.String("msgId", message.MessageIDString()), - zap.Stringer("txHash", message.TxHash), + zap.String("txHash", message.TxIDString()), zap.Uint64("blockNum", ev.Raw.BlockNumber), zap.Uint64("latestFinalizedBlock", atomic.LoadUint64(&w.latestFinalizedBlockNumber)), zap.Stringer("blockHash", ev.Raw.BlockHash), @@ -878,7 +873,7 @@ func (w *Watcher) postMessage(logger *zap.Logger, ev *ethabi.AbiLogMessagePublis ) key := pendingKey{ - TxHash: message.TxHash, + TxHash: eth_common.BytesToHash(message.TxID), BlockHash: ev.Raw.BlockHash, EmitterAddress: message.EmitterAddress, Sequence: message.Sequence, diff --git a/node/pkg/watchers/ibc/watcher.go b/node/pkg/watchers/ibc/watcher.go index 74ad36b8db..0292242751 100644 --- a/node/pkg/watchers/ibc/watcher.go +++ b/node/pkg/watchers/ibc/watcher.go @@ -537,7 +537,7 @@ func parseIbcReceivePublishEvent(logger *zap.Logger, desiredContract string, eve evt := new(ibcReceivePublishEvent) evt.Msg = new(common.MessagePublication) - evt.Msg.TxHash = txHash + evt.Msg.TxID = txHash.Bytes() evt.ChannelID, err = attributes.GetAsString("channel_id") if err != nil { @@ -595,7 +595,7 @@ func (w *Watcher) processIbcReceivePublishEvent(evt *ibcReceivePublishEvent, obs if err != nil { w.logger.Error("query for IBC channel ID failed", zap.String("IbcChannelID", evt.ChannelID), - zap.Stringer("TxHash", evt.Msg.TxHash), + zap.String("TxID", evt.Msg.TxIDString()), zap.Stringer("EmitterChain", evt.Msg.EmitterChain), zap.Stringer("EmitterAddress", evt.Msg.EmitterAddress), zap.Uint64("Sequence", evt.Msg.Sequence), @@ -613,7 +613,7 @@ func (w *Watcher) processIbcReceivePublishEvent(evt *ibcReceivePublishEvent, obs // Therefore we don't want to return an error here. Restarting won't help. w.logger.Error(fmt.Sprintf("received %s message from unknown IBC channel, dropping observation", observationType), zap.String("IbcChannelID", evt.ChannelID), - zap.Stringer("TxHash", evt.Msg.TxHash), + zap.String("TxID", evt.Msg.TxIDString()), zap.Stringer("EmitterChain", evt.Msg.EmitterChain), zap.Stringer("EmitterAddress", evt.Msg.EmitterAddress), zap.Uint64("Sequence", evt.Msg.Sequence), @@ -631,7 +631,7 @@ func (w *Watcher) processIbcReceivePublishEvent(evt *ibcReceivePublishEvent, obs w.logger.Debug(fmt.Sprintf("received %s message from an unconfigured chain, dropping observation", observationType), zap.String("IbcChannelID", evt.ChannelID), zap.Stringer("ChainID", mappedChainID), - zap.Stringer("TxHash", evt.Msg.TxHash), + zap.String("TxID", evt.Msg.TxIDString()), zap.Stringer("EmitterChain", evt.Msg.EmitterChain), zap.Stringer("EmitterAddress", evt.Msg.EmitterAddress), zap.Uint64("Sequence", evt.Msg.Sequence), @@ -647,7 +647,7 @@ func (w *Watcher) processIbcReceivePublishEvent(evt *ibcReceivePublishEvent, obs zap.String("IbcChannelID", evt.ChannelID), zap.Uint16("MappedChainID", uint16(mappedChainID)), zap.Uint16("ExpectedChainID", uint16(ce.chainID)), - zap.Stringer("TxHash", evt.Msg.TxHash), + zap.String("TxID", evt.Msg.TxIDString()), zap.Stringer("EmitterChain", evt.Msg.EmitterChain), zap.Stringer("EmitterAddress", evt.Msg.EmitterAddress), zap.Uint64("Sequence", evt.Msg.Sequence), @@ -662,7 +662,7 @@ func (w *Watcher) processIbcReceivePublishEvent(evt *ibcReceivePublishEvent, obs w.logger.Info(fmt.Sprintf("%s message detected", observationType), zap.String("IbcChannelID", evt.ChannelID), zap.String("ChainName", ce.chainName), - zap.Stringer("TxHash", evt.Msg.TxHash), + zap.String("TxID", evt.Msg.TxIDString()), zap.Stringer("EmitterChain", evt.Msg.EmitterChain), zap.Stringer("EmitterAddress", evt.Msg.EmitterAddress), zap.Uint64("Sequence", evt.Msg.Sequence), diff --git a/node/pkg/watchers/ibc/watcher_test.go b/node/pkg/watchers/ibc/watcher_test.go index 016af80970..0ebef19ccb 100644 --- a/node/pkg/watchers/ibc/watcher_test.go +++ b/node/pkg/watchers/ibc/watcher_test.go @@ -55,7 +55,7 @@ func TestParseIbcReceivePublishEvent(t *testing.T) { expectedResult := ibcReceivePublishEvent{ ChannelID: "channel-0", Msg: &common.MessagePublication{ - TxHash: txHash, + TxID: txHash.Bytes(), EmitterAddress: expectedSender, EmitterChain: vaa.ChainIDTerra2, Nonce: 1, diff --git a/node/pkg/watchers/near/tx_processing.go b/node/pkg/watchers/near/tx_processing.go index afcf17c79e..5a8f272e69 100644 --- a/node/pkg/watchers/near/tx_processing.go +++ b/node/pkg/watchers/near/tx_processing.go @@ -235,7 +235,7 @@ func (e *Watcher) processWormholeLog(logger *zap.Logger, _ context.Context, job ts := outcomeBlockHeader.Timestamp observation := &common.MessagePublication{ - TxHash: txHashEthFormat, + TxID: txHashEthFormat.Bytes(), Timestamp: time.Unix(int64(ts), 0), Nonce: pubEvent.Nonce, Sequence: pubEvent.Seq, diff --git a/node/pkg/watchers/near/watcher_test.go b/node/pkg/watchers/near/watcher_test.go index 0389c96251..1fa47f62a5 100644 --- a/node/pkg/watchers/near/watcher_test.go +++ b/node/pkg/watchers/near/watcher_test.go @@ -14,7 +14,6 @@ import ( gossipv1 "github.com/certusone/wormhole/node/pkg/proto/gossip/v1" "github.com/certusone/wormhole/node/pkg/supervisor" mockserver "github.com/certusone/wormhole/node/pkg/watchers/near/nearapi/mock" - eth_common "github.com/ethereum/go-ethereum/common" "github.com/stretchr/testify/assert" "github.com/wormhole-foundation/wormhole/sdk/vaa" "go.uber.org/zap" @@ -231,7 +230,7 @@ func TestWatcherSimple(t *testing.T) { }, expectedMsgObserved: []*common.MessagePublication{ { - TxHash: eth_common.BytesToHash(txHashBytes), + TxID: txHashBytes, EmitterAddress: portalEmitterAddress(), ConsistencyLevel: 0, EmitterChain: vaa.ChainIDNear, @@ -273,7 +272,7 @@ func TestWatcherSimple2(t *testing.T) { }, expectedMsgObserved: []*common.MessagePublication{ { - TxHash: eth_common.BytesToHash(txHashBytes), + TxID: txHashBytes, EmitterAddress: portalEmitterAddress(), ConsistencyLevel: 0, EmitterChain: vaa.ChainIDNear, @@ -309,7 +308,7 @@ func TestWatcherReobservation(t *testing.T) { }, expectedMsgReObserved: []*common.MessagePublication{ { - TxHash: eth_common.BytesToHash(txHashBytes), + TxID: txHashBytes, EmitterAddress: portalEmitterAddress(), ConsistencyLevel: 0, EmitterChain: vaa.ChainIDNear, @@ -359,7 +358,7 @@ func TestWatcherDelayedFinal(t *testing.T) { latestFinalBlocks: lfb, expectedMsgObserved: []*common.MessagePublication{ { - TxHash: eth_common.BytesToHash(txHashBytes), + TxID: txHashBytes, EmitterAddress: portalEmitterAddress(), ConsistencyLevel: 0, EmitterChain: vaa.ChainIDNear, @@ -398,7 +397,7 @@ func TestWatcherDelayedFinalAndGaps(t *testing.T) { }, expectedMsgObserved: []*common.MessagePublication{ { - TxHash: eth_common.BytesToHash(txHashBytes), + TxID: txHashBytes, EmitterAddress: portalEmitterAddress(), ConsistencyLevel: 0, EmitterChain: vaa.ChainIDNear, @@ -444,7 +443,7 @@ func TestWatcherSynthetic(t *testing.T) { }, expectedMsgReObserved: []*common.MessagePublication{ { - TxHash: eth_common.BytesToHash([]byte("_____________________________TX1")), + TxID: []byte("_____________________________TX1"), EmitterAddress: portalEmitterAddress(), ConsistencyLevel: 0, EmitterChain: vaa.ChainIDNear, @@ -455,7 +454,7 @@ func TestWatcherSynthetic(t *testing.T) { Unreliable: false, }, { - TxHash: eth_common.BytesToHash([]byte("_____________________________TX2")), + TxID: []byte("_____________________________TX2"), EmitterAddress: portalEmitterAddress(), ConsistencyLevel: 0, EmitterChain: vaa.ChainIDNear, @@ -466,7 +465,7 @@ func TestWatcherSynthetic(t *testing.T) { Unreliable: false, }, { - TxHash: eth_common.BytesToHash([]byte("_____________________________TX3")), + TxID: []byte("_____________________________TX3"), EmitterAddress: portalEmitterAddress(), ConsistencyLevel: 0, EmitterChain: vaa.ChainIDNear, @@ -537,7 +536,7 @@ func TestWatcherUnfinalized(t *testing.T) { }, expectedMsgReObserved: []*common.MessagePublication{ { - TxHash: eth_common.BytesToHash([]byte("_____________________________TX1")), + TxID: []byte("_____________________________TX1"), EmitterAddress: portalEmitterAddress(), ConsistencyLevel: 0, EmitterChain: vaa.ChainIDNear, @@ -548,7 +547,7 @@ func TestWatcherUnfinalized(t *testing.T) { Unreliable: false, }, { - TxHash: eth_common.BytesToHash([]byte("_____________________________TX3")), + TxID: []byte("_____________________________TX3"), EmitterAddress: portalEmitterAddress(), ConsistencyLevel: 0, EmitterChain: vaa.ChainIDNear, diff --git a/node/pkg/watchers/solana/client.go b/node/pkg/watchers/solana/client.go index 6dae0a2506..77f8248d90 100644 --- a/node/pkg/watchers/solana/client.go +++ b/node/pkg/watchers/solana/client.go @@ -10,6 +10,7 @@ import ( "time" "encoding/base64" + "encoding/hex" "encoding/json" "github.com/certusone/wormhole/node/pkg/common" @@ -76,6 +77,12 @@ type ( ccqConfig query.PerChainConfig ccqLogger *zap.Logger + + shimContractStr string + shimContractAddr solana.PublicKey + shimEnabled bool + shimPostMessageDiscriminator []byte + shimMessageEventDiscriminator []byte } EventSubscriptionError struct { @@ -125,6 +132,16 @@ type ( } ) +const ( + // NOTE: We have a test to make sure these constants don't change in solana-go. + + // SolanaAccountLen is the expected length of an account identifier, which is a public key. Using the number here because that's what the admin client will populate. + SolanaAccountLen = 32 + + // SolanaSignatureLen is the expected length of a signature. As of v1.12.0, solana-go does not have a const for this. + SolanaSignatureLen = 64 +) + var ( emptyAddressBytes = vaa.Address{}.Bytes() emptyGapBytes = []byte{0, 0, 0} @@ -221,6 +238,8 @@ func NewSolanaWatcher( chainID vaa.ChainID, queryReqC <-chan *query.PerChainQueryInternal, queryResponseC chan<- *query.PerChainQueryResponseInternal, + shimContractStr string, + shimContractAddr solana.PublicKey, ) *SolanaWatcher { msgObservedLogLevel := zapcore.InfoLevel if chainID == vaa.ChainIDPythNet { @@ -243,6 +262,8 @@ func NewSolanaWatcher( queryReqC: queryReqC, queryResponseC: queryResponseC, ccqConfig: query.GetPerChainConfig(chainID), + shimContractStr: shimContractStr, + shimContractAddr: shimContractAddr, } } @@ -334,10 +355,13 @@ func (s *SolanaWatcher) Run(ctx context.Context) error { zap.String("wsUrl", wsUrl), zap.String("contract", contractAddr), zap.String("rawContract", s.rawContract), + zap.String("shimContract", s.shimContractStr), ) logger.Info("Solana watcher connecting to RPC node ", zap.String("url", s.rpcUrl)) + s.shimSetup() + s.errC = make(chan error) s.pumpData = make(chan []byte) @@ -370,13 +394,39 @@ func (s *SolanaWatcher) Run(ctx context.Context) error { if m.ChainId != uint32(s.chainID) { panic("unexpected chain id") } - - acc := solana.PublicKeyFromBytes(m.TxHash) - logger.Info("received observation request", zap.String("account", acc.String())) - - rCtx, cancel := context.WithTimeout(ctx, rpcTimeout) - s.fetchMessageAccount(rCtx, logger, acc, 0, true) - cancel() + if len(m.TxHash) == SolanaAccountLen { // Request by account ID + acc := solana.PublicKeyFromBytes(m.TxHash) + logger.Info("received observation request with account id", zap.String("account", acc.String())) + rCtx, cancel := context.WithTimeout(ctx, rpcTimeout) + s.fetchMessageAccount(rCtx, logger, acc, 0, true) + cancel() + } else if len(m.TxHash) == SolanaSignatureLen { // Request by transaction ID + signature := solana.SignatureFromBytes(m.TxHash) + logger.Info("received observation request with transaction id", zap.Stringer("signature", signature)) + rCtx, cancel := context.WithTimeout(ctx, rpcTimeout) + version := uint64(0) + result, err := s.rpcClient.GetTransaction( + rCtx, + signature, + &rpc.GetTransactionOpts{ + MaxSupportedTransactionVersion: &version, + Encoding: solana.EncodingBase64, + }, + ) + cancel() + if err != nil { + logger.Error("failed to get transaction for observation request", zap.String("bytes", hex.EncodeToString(m.TxHash)), zap.Stringer("signature", signature), zap.Error(err)) + } else { + tx, err := result.Transaction.GetTransaction() + if err != nil { + logger.Error("failed to extract transaction for observation request", zap.String("bytes", hex.EncodeToString(m.TxHash)), zap.Stringer("signature", signature), zap.Error(err)) + } else { + s.processTransaction(ctx, logger, tx, result.Meta, result.Slot, true) + } + } + } else { + logger.Error("ignoring an observation request of unexpected length", zap.Int("len", len(m.TxHash)), zap.String("bytes", hex.EncodeToString(m.TxHash))) + } case <-timer.C: // Get current slot height rCtx, cancel := context.WithTimeout(ctx, rpcTimeout) @@ -561,6 +611,7 @@ func (s *SolanaWatcher) fetchBlock(ctx context.Context, logger *zap.Logger, slot // If the logs don't contain the contract address, skip the transaction. // ex: "Program 3u8hJUVTA4jH1wYAyUur7FFZVQ8H635K3tSHHF4ssjQ5 invoke [2]", + // Assumption: Transactions for the shim contract also contain the core contract address so this check is still valid. var possiblyWormhole bool for i := 0; i < len(txRpc.Meta.LogMessages) && !possiblyWormhole; i++ { possiblyWormhole = strings.HasPrefix(txRpc.Meta.LogMessages[i], s.whLogPrefix) @@ -580,36 +631,79 @@ func (s *SolanaWatcher) fetchBlock(ctx context.Context, logger *zap.Logger, slot continue } - err = s.populateLookupTableAccounts(ctx, tx) - if err != nil { - logger.Error("failed to fetch lookup table accounts", - zap.Uint64("slot", slot), - zap.Int("txNum", txNum), - zap.Error(err), - ) - continue - } + s.processTransaction(ctx, logger, tx, txRpc.Meta, slot, false) + } - signature := tx.Signatures[0] - var programIndex uint16 - for n, key := range tx.Message.AccountKeys { - if key.Equals(s.contract) { - programIndex = uint16(n) - } + if emptyRetry > 0 && logger.Level().Enabled(zapcore.DebugLevel) { + logger.Debug("skipped or unavailable block retrieved on retry attempt", + zap.Uint("empty_retry", emptyRetry), + zap.Uint64("slot", slot), + zap.String("commitment", string(s.commitment))) + } + + return true +} + +// processTransaction processes a transaction and publishes any Wormhole events. +func (s *SolanaWatcher) processTransaction(ctx context.Context, logger *zap.Logger, tx *solana.Transaction, meta *rpc.TransactionMeta, slot uint64, isReobservation bool) { + signature := tx.Signatures[0] + err := s.populateLookupTableAccounts(ctx, tx) + if err != nil { + logger.Error("failed to fetch lookup table accounts for transaction", + zap.Uint64("slot", slot), + zap.Stringer("signature", signature), + zap.Error(err), + ) + return + } + + var programIndex uint16 + var shimProgramIndex uint16 + var shimFound bool + for n, key := range tx.Message.AccountKeys { + if key.Equals(s.contract) { + programIndex = uint16(n) } - if programIndex == 0 { - continue + if s.shimEnabled && key.Equals(s.shimContractAddr) { + shimProgramIndex = uint16(n) + shimFound = true } + } + if programIndex == 0 { + return + } - if logger.Level().Enabled(zapcore.DebugLevel) { - logger.Debug("found Wormhole transaction", - zap.Stringer("signature", signature), - zap.Uint64("slot", slot), - zap.String("commitment", string(s.commitment))) - } + if logger.Level().Enabled(zapcore.DebugLevel) { + logger.Debug("found Wormhole transaction", + zap.Stringer("signature", signature), + zap.Uint64("slot", slot), + zap.String("commitment", string(s.commitment))) + } - // Find top-level instructions - for i, inst := range tx.Message.Instructions { + alreadyProcessed := ShimAlreadyProcessed{} + + // Find top-level instructions + for i, inst := range tx.Message.Instructions { + if shimFound && inst.ProgramIDIndex == shimProgramIndex { + found, err := s.shimProcessTopLevelInstruction(logger, programIndex, shimProgramIndex, tx, meta.InnerInstructions, i, alreadyProcessed, isReobservation) + if err != nil { + logger.Error("malformed wormhole shim instruction", + zap.Error(err), + zap.Int("idx", i), + zap.Stringer("signature", signature), + zap.Uint64("slot", slot), + zap.String("commitment", string(s.commitment)), + zap.Binary("data", inst.Data)) + } else if found { + if logger.Level().Enabled(zapcore.DebugLevel) { + logger.Debug("found a top-level wormhole shim instruction", + zap.Int("idx", i), + zap.Stringer("signature", signature), + zap.Uint64("slot", slot), + zap.String("commitment", string(s.commitment))) + } + } + } else { found, err := s.processInstruction(ctx, logger, slot, inst, programIndex, tx, signature, i, isReobservation) if err != nil { logger.Error("malformed Wormhole instruction", @@ -629,38 +723,55 @@ func (s *SolanaWatcher) fetchBlock(ctx context.Context, logger *zap.Logger, slot } } } + } - for _, inner := range txRpc.Meta.InnerInstructions { - for i, inst := range inner.Instructions { - found, err := s.processInstruction(ctx, logger, slot, inst, programIndex, tx, signature, i, isReobservation) - if err != nil { - logger.Error("malformed Wormhole instruction", - zap.Error(err), - zap.Int("idx", i), - zap.Stringer("signature", signature), - zap.Uint64("slot", slot), - zap.String("commitment", string(s.commitment))) - } else if found { - if logger.Level().Enabled(zapcore.DebugLevel) { - logger.Debug("found an inner Wormhole instruction", - zap.Int("idx", i), + for outerIdx, inner := range meta.InnerInstructions { + for innerIdx, inst := range inner.Instructions { + if !alreadyProcessed.exists(outerIdx, innerIdx) { + if shimFound && inst.ProgramIDIndex == shimProgramIndex { + found, err := s.shimProcessInnerInstruction(logger, programIndex, shimProgramIndex, tx, inner.Instructions, outerIdx, innerIdx, alreadyProcessed, isReobservation) + if err != nil { + logger.Error("malformed inner wormhole shim instruction", + zap.Error(err), + zap.Int("outerIdx", outerIdx), + zap.Int("innerIdx", innerIdx), zap.Stringer("signature", signature), zap.Uint64("slot", slot), zap.String("commitment", string(s.commitment))) + } else if found { + if logger.Level().Enabled(zapcore.DebugLevel) { + logger.Debug("found an inner wormhole shim instruction", + zap.Int("outerIdx", outerIdx), + zap.Int("innerIdx", innerIdx), + zap.Stringer("signature", signature), + zap.Uint64("slot", slot), + zap.String("commitment", string(s.commitment))) + } + } + } else { + found, err := s.processInstruction(ctx, logger, slot, inst, programIndex, tx, signature, innerIdx, isReobservation) + if err != nil { + logger.Error("malformed Wormhole instruction", + zap.Error(err), + zap.Int("outerIdx", outerIdx), + zap.Int("innerIdx", innerIdx), + zap.Stringer("signature", signature), + zap.Uint64("slot", slot), + zap.String("commitment", string(s.commitment))) + } else if found { + if logger.Level().Enabled(zapcore.DebugLevel) { + logger.Debug("found an inner Wormhole instruction", + zap.Int("outerIdx", outerIdx), + zap.Int("innerIdx", innerIdx), + zap.Stringer("signature", signature), + zap.Uint64("slot", slot), + zap.String("commitment", string(s.commitment))) + } } } } } } - - if emptyRetry > 0 && logger.Level().Enabled(zapcore.DebugLevel) { - logger.Debug("skipped or unavailable block retrieved on retry attempt", - zap.Uint("empty_retry", emptyRetry), - zap.Uint64("slot", slot), - zap.String("commitment", string(s.commitment))) - } - - return true } func (s *SolanaWatcher) processInstruction(ctx context.Context, logger *zap.Logger, slot uint64, inst solana.CompiledInstruction, programIndex uint16, tx *solana.Transaction, signature solana.Signature, idx int, isReobservation bool) (bool, error) { @@ -697,7 +808,14 @@ func (s *SolanaWatcher) processInstruction(ctx context.Context, logger *zap.Logg return false, fmt.Errorf("failed to determine commitment: %w", err) } - if level != s.commitment { + if !s.checkCommitment(level, isReobservation) { + if logger.Level().Enabled(zapcore.DebugLevel) { + logger.Debug("skipping message which does not match the watcher commitment", + zap.Stringer("signature", tx.Signatures[0]), + zap.String("message commitment", string(level)), + zap.String("watcher commitment", string(s.commitment)), + ) + } return true, nil } @@ -879,19 +997,16 @@ func (s *SolanaWatcher) processMessageAccount(logger *zap.Logger, data []byte, a zap.Error(err)) return } - if commitment != s.commitment { - if isReobservation && s.commitment == rpc.CommitmentFinalized { - // There is only a single reobservation request channel for each chain, which is assigned to the finalized watcher. - // If someone requests reobservation of a confirmed message, we should allow the observation to go through. - logger.Info("allowing reobservation although the commitment level does not match the watcher", - zap.Stringer("account", acc), zap.String("message commitment", string(commitment)), zap.String("watcher commitment", string(s.commitment)), + + if !s.checkCommitment(commitment, isReobservation) { + if logger.Level().Enabled(zapcore.DebugLevel) { + logger.Debug("skipping message which does not match the watcher commitment", + zap.Stringer("account", acc), + zap.String("message commitment", string(commitment)), + zap.String("watcher commitment", string(s.commitment)), ) - } else { - if logger.Level().Enabled(zapcore.DebugLevel) { - logger.Debug("skipping message which does not match the watcher commitment", zap.Stringer("account", acc), zap.String("message commitment", string(commitment)), zap.String("watcher commitment", string(s.commitment))) - } - return } + return } // As of 2023-11-09, Pythnet has a bug which is not zeroing out these fields appropriately. This carve out should be removed after a fix is deployed. @@ -921,7 +1036,7 @@ func (s *SolanaWatcher) processMessageAccount(logger *zap.Logger, data []byte, a } observation := &common.MessagePublication{ - TxHash: txHash, + TxID: txHash.Bytes(), Timestamp: time.Unix(int64(proposal.SubmissionTime), 0), Nonce: proposal.Nonce, Sequence: proposal.Sequence, @@ -933,6 +1048,23 @@ func (s *SolanaWatcher) processMessageAccount(logger *zap.Logger, data []byte, a Unreliable: !reliable, } + // SECURITY: An unreliable message with an empty payload is most like a PostMessage generated as part + // of a shim event where this guardian is not watching the shim contract. Those events should be ignored. + if !reliable && len(observation.Payload) == 0 { + logger.Debug("ignoring an observation because it is marked unreliable and has a zero length payload, probably from the shim", + zap.Stringer("account", acc), + zap.Time("timestamp", observation.Timestamp), + zap.Uint32("nonce", observation.Nonce), + zap.Uint64("sequence", observation.Sequence), + zap.Stringer("emitter_chain", observation.EmitterChain), + zap.Stringer("emitter_address", observation.EmitterAddress), + zap.Bool("isReobservation", isReobservation), + zap.Binary("payload", observation.Payload), + zap.Uint8("consistency_level", observation.ConsistencyLevel), + ) + return + } + solanaMessagesConfirmed.WithLabelValues(s.networkName).Inc() if logger.Level().Enabled(s.msgObservedLogLevel) { @@ -1016,3 +1148,16 @@ func (s *SolanaWatcher) populateLookupTableAccounts(ctx context.Context, tx *sol return nil } + +// checkCommitment checks to see if the commitment level of an observation matches the watcher. If it does, the observation should be published. +// If the commitment level does not match and the message is not a reobservation, then it should be dropped. In the case of a reobservation +// where the commitment level doesn't match, we need to check to see if this is the finalized watcher. If it is, then we should generate the +// observation. This is because all reobservation requests are handled by the finalized watcher. +func (s *SolanaWatcher) checkCommitment(commitment rpc.CommitmentType, isReobservation bool) bool { + if commitment != s.commitment { + if !isReobservation || s.commitment != rpc.CommitmentFinalized { + return false + } + } + return true +} diff --git a/node/pkg/watchers/solana/client_test.go b/node/pkg/watchers/solana/client_test.go new file mode 100644 index 0000000000..b350634c3c --- /dev/null +++ b/node/pkg/watchers/solana/client_test.go @@ -0,0 +1,58 @@ +package solana + +import ( + "testing" + + "github.com/stretchr/testify/assert" + + "github.com/gagliardetto/solana-go" + "github.com/gagliardetto/solana-go/rpc" +) + +func TestVerifyConstants(t *testing.T) { + // If either of these ever change, message publication and reobservation will break. + assert.Equal(t, SolanaAccountLen, solana.PublicKeyLength) + assert.Equal(t, SolanaSignatureLen, len(solana.Signature{})) +} + +func TestCheckCommitment(t *testing.T) { + type test struct { + commitment string + watcher string + isReobservation bool + result bool + } + tests := []test{ + // New observation success cases + {commitment: "finalized", watcher: "finalized", isReobservation: false, result: true}, + {commitment: "confirmed", watcher: "confirmed", isReobservation: false, result: true}, + + // New observation failure cases + {commitment: "finalized", watcher: "confirmed", isReobservation: false, result: false}, + {commitment: "confirmed", watcher: "finalized", isReobservation: false, result: false}, + + // Reobservation success cases + {commitment: "finalized", watcher: "finalized", isReobservation: true, result: true}, + {commitment: "confirmed", watcher: "finalized", isReobservation: true, result: true}, + + // Reobservation case that never really happen because only the finalized watcher does reobservations + {commitment: "finalized", watcher: "confirmed", isReobservation: true, result: false}, + {commitment: "confirmed", watcher: "confirmed", isReobservation: true, result: true}, + } + + for _, tc := range tests { + var label string + if tc.isReobservation { + label = "reobserved_" + } else { + label = "new_" + } + label += tc.commitment + "_message_on_" + tc.watcher + "_watcher" + t.Run(label, func(t *testing.T) { + commitment := rpc.CommitmentType(tc.commitment) + watcher := rpc.CommitmentType(tc.watcher) + s := &SolanaWatcher{commitment: watcher} + assert.Equal(t, tc.result, s.checkCommitment(commitment, tc.isReobservation)) + }) + } +} diff --git a/node/pkg/watchers/solana/config.go b/node/pkg/watchers/solana/config.go index 0abca5af0f..ebb98140ff 100644 --- a/node/pkg/watchers/solana/config.go +++ b/node/pkg/watchers/solana/config.go @@ -7,6 +7,7 @@ import ( "github.com/certusone/wormhole/node/pkg/supervisor" "github.com/certusone/wormhole/node/pkg/watchers" "github.com/certusone/wormhole/node/pkg/watchers/interfaces" + "github.com/gagliardetto/solana-go" solana_types "github.com/gagliardetto/solana-go" solana_rpc "github.com/gagliardetto/solana-go/rpc" "github.com/wormhole-foundation/wormhole/sdk/vaa" @@ -19,6 +20,7 @@ type WatcherConfig struct { Rpc string // RPC URL Websocket string // Websocket URL Contract string // hex representation of the contract address + ShimContract string // Address of the shim contract (empty string if disabled) Commitment solana_rpc.CommitmentType } @@ -51,11 +53,19 @@ func (wc *WatcherConfig) Create( return nil, nil, err } + var shimContractAddr solana.PublicKey + if wc.ShimContract != "" { + shimContractAddr, err = solana_types.PublicKeyFromBase58(wc.ShimContract) + if err != nil { + return nil, nil, err + } + } + if !wc.ReceiveObsReq { obsvReqC = nil } - watcher := NewSolanaWatcher(wc.Rpc, &wc.Websocket, solAddress, wc.Contract, msgC, obsvReqC, wc.Commitment, wc.ChainID, queryReqC, queryResponseC) + watcher := NewSolanaWatcher(wc.Rpc, &wc.Websocket, solAddress, wc.Contract, msgC, obsvReqC, wc.Commitment, wc.ChainID, queryReqC, queryResponseC, wc.ShimContract, shimContractAddr) return watcher, watcher.Run, nil } diff --git a/node/pkg/watchers/solana/shim.go b/node/pkg/watchers/solana/shim.go new file mode 100644 index 0000000000..9562813862 --- /dev/null +++ b/node/pkg/watchers/solana/shim.go @@ -0,0 +1,353 @@ +// This code is responsible for processing events from the shim contract and publishing them as message observations, +// similar to what the watcher does for legacy account-based events from the core contract. +// +// There are three events that are generated for each shim event: +// - Shim PostMessage - This is the first message generated by the shim and it contains some of the data needed to generate an observation. +// +// - Core PostMessage - This is the existing event generated by the core, but in this scenario it is generated by a call from the shim contract. +// The core event generated on behalf of the shim is always marked unreliable and has an empty payload. This code enforces that. +// +// - Shim MessageEvent - This event appears after the core PostMessage and contains the remaining fields needed to generate an observation. +// +// There are two ways the shim can publish events: Direct and integrator originated. +// +// The direct scenario is when a user directly calls the shim contract to post a message. This looks as follows: +// - The shim PostMessage appears as a top-level instruction in the transaction. +// - The inner instructions for the matching top-level instruction (innerInstructions.Index matches the top-level instruction index) will contain +// the core PostMessage and the shim MessageEvent. Note that there may be other inner instructions that will be ignored. Also note that the +// code enforces that the shim MessageEvent follows the core PostMessage. +// +// The integrator originated scenario happens when the shim PostMessage event appears in the inner instructions. This looks as follows: +// - Everything for this event appears in a single inner instruction set (the entries for a given innerInstructions.Index). Note that there +// may be other instructions in that set which are ignored, and there could be the instructions for multiple shim events which are handled separately. +// - Within the given inner instruction set, there is a shim PostMessage, a core PostMessage and a ShimMessageEvent. +// +// When processing inner instructions, this code ensures that events that are processed as part of a shim transaction are not processed more than once using the ShimAlreadyProcessed map. + +package solana + +import ( + "bytes" + "encoding/hex" + "fmt" + "time" + + "github.com/certusone/wormhole/node/pkg/common" + "github.com/gagliardetto/solana-go" + "github.com/gagliardetto/solana-go/rpc" + "github.com/near/borsh-go" + "go.uber.org/zap" + "go.uber.org/zap/zapcore" +) + +const ( + shimPostMessageDiscriminatorStr = "d63264d12622074c" + shimMessageEventDiscriminatorStr = "e445a52e51cb9a1d441b8f004d4c8970" +) + +type ( + + // ShimPostMessageData defines the shim PostMessage payload following the eight byte discriminator (shimPostMessageDiscriminatorStr) + ShimPostMessageData struct { + Nonce uint32 + ConsistencyLevel ConsistencyLevel + Payload []byte + } + + // ShimMessageEventData defines the shim MessageEvent payload following the sixteen byte discriminator (shimMessageEventDiscriminatorStr) + ShimMessageEventData struct { + EmitterAddress [32]byte + Sequence uint64 + Timestamp uint32 + } + + // ShimAlreadyProcessed is a map that tracks the inner index identifier pairs already processed as part of shim transactions. + // This allows us to avoid double processing instructions. + ShimAlreadyProcessed map[ShimInnerIdx]struct{} + + // InnerIdx is the key to the set of instructions already processed as part of shim transactions + ShimInnerIdx struct { + topLevelIdx int + innerIdx int + } +) + +// add adds the specified inner index identifier pair into a ShimAlreadyProcessed. +func (sap *ShimAlreadyProcessed) add(outerIdx int, innerIdx int) { + (*sap)[ShimInnerIdx{outerIdx, innerIdx}] = struct{}{} +} + +// exists returns true if the specified inner index identifier pair is in a ShimAlreadyProcessed. +func (sap *ShimAlreadyProcessed) exists(outerIdx int, innerIdx int) bool { + _, exists := (*sap)[ShimInnerIdx{outerIdx, innerIdx}] + return exists +} + +// shimSetup performs any initialization that is specific to monitoring the shim contract. +func (s *SolanaWatcher) shimSetup() { + s.shimEnabled = s.shimContractStr != "" + if s.shimEnabled { + var err error + s.shimPostMessageDiscriminator, err = hex.DecodeString(shimPostMessageDiscriminatorStr) + if err != nil { + panic("failed to decode shim post message discriminator") + } + s.shimMessageEventDiscriminator, err = hex.DecodeString(shimMessageEventDiscriminatorStr) + if err != nil { + panic("failed to decode shim post message discriminator") + } + } +} + +// shimMatchPrefix verifies that the instruction data starts with the specified prefix bytes. +func shimMatchPrefix(discriminator []byte, buf []byte) bool { + if len(buf) < len(discriminator) { + return false + } + return bytes.Equal(discriminator, buf[:len(discriminator)]) +} + +// shimParsePostMessage parses a shim PostMessage and returns the results. +func shimParsePostMessage(shimPostMessageDiscriminator []byte, buf []byte) (*ShimPostMessageData, error) { + if !shimMatchPrefix(shimPostMessageDiscriminator, buf) { + return nil, nil + } + + data := new(ShimPostMessageData) + if err := borsh.Deserialize(data, buf[len(shimPostMessageDiscriminator):]); err != nil { + return nil, fmt.Errorf("failed to deserialize shim post message: %w", err) + } + + return data, nil +} + +// shimVerifyCoreMessage verifies that an instruction from the core contract is what we expect to accompany a shim instruction. +// This includes being marked unreliable and having a zero length payload. +func shimVerifyCoreMessage(buf []byte) (bool, error) { + if len(buf) == 0 { + return false, nil + } + + if buf[0] != postMessageUnreliableInstructionID { + return false, nil + } + + var data PostMessageData + if err := borsh.Deserialize(&data, buf[1:]); err != nil { + return false, fmt.Errorf("failed to deserialize core instruction data: %w", err) + } + + if len(data.Payload) != 0 { + return false, nil + } + + return true, nil +} + +// shimParseMessageEvent parses a shim MessageEvent and returns the results. +func shimParseMessageEvent(shimMessageEventDiscriminator []byte, buf []byte) (*ShimMessageEventData, error) { + if !shimMatchPrefix(shimMessageEventDiscriminator, buf) { + return nil, nil + } + + data := new(ShimMessageEventData) + if err := borsh.Deserialize(data, buf[len(shimMessageEventDiscriminator):]); err != nil { + return nil, fmt.Errorf("failed to deserialize shim message event: %w", err) + } + + return data, nil +} + +// shimProcessTopLevelInstruction handles a top-level instruction where the program ID matches the shim contract. It does the following: +// - Verifies that the instruction is a shim PostMessage. If not, it just returns. If it is, it parses it. +// - Searches the sets of inner instructions to find the ones generated by this top-level instruction (by matching the index). +// - Searches through those inner instructions to find the entry for the core. Makes sure it is unreliable with no payload. +// - Searches for the inner shim MessageEvent to get the remaining fields needed to generate the observation. +// - Publishes the observation. +func (s *SolanaWatcher) shimProcessTopLevelInstruction( + logger *zap.Logger, + whProgramIndex uint16, + shimProgramIndex uint16, + tx *solana.Transaction, + innerInstructions []rpc.InnerInstruction, + topLevelIndex int, + alreadyProcessed ShimAlreadyProcessed, + isReobservation bool, +) (bool, error) { + topLevelIdx := uint16(topLevelIndex) + inst := tx.Message.Instructions[topLevelIdx] + + // The only top-level instruction generated by the shim contract is the PostMessage event. Parse that to get + // the fields we need to generate an observation. + postMessage, err := shimParsePostMessage(s.shimPostMessageDiscriminator, inst.Data) + if err != nil { + return false, fmt.Errorf("failed to parse top-level shim instruction %d: %w", topLevelIdx, err) + } + + if postMessage == nil { + return false, nil + } + + // Find the set of inner instructions that go with this top level instruction by matching the index. + outerIdx := -1 + for idx, inner := range innerInstructions { + if inner.Index == topLevelIdx { + outerIdx = int(idx) + break + } + } + + if outerIdx == -1 { + return false, fmt.Errorf("failed to find inner instructions for top-level shim instruction %d", topLevelIdx) + } + + // Process the inner instructions associated with this shim top-level instruction and produce an observation event. + err = s.shimProcessRest(logger, whProgramIndex, shimProgramIndex, tx, innerInstructions[outerIdx].Instructions, outerIdx, 0, postMessage, alreadyProcessed, isReobservation) + if err != nil { + return false, fmt.Errorf("failed to process inner instructions for top-level shim instruction %d: %w", topLevelIdx, err) + } + + return true, nil +} + +// shimProcessInnerInstruction handles an inner instruction where the program ID matches the shim contract. It does the following: +// - Verifies that the instruction is a shim PostMessage. If not, it just returns. If it is, it parses it. +// - Searches through the subsequent inner instructions in the set to find the entry for the core. Makes sure it is unreliable with no payload. +// - Searches for the inner shim MessageEvent to get the remaining fields needed to generate the observation. +// - Publishes the observation. +func (s *SolanaWatcher) shimProcessInnerInstruction( + logger *zap.Logger, + whProgramIndex uint16, + shimProgramIndex uint16, + tx *solana.Transaction, + innerInstructions []solana.CompiledInstruction, + outerIdx int, + startIdx int, + alreadyProcessed ShimAlreadyProcessed, + isReobservation bool, +) (bool, error) { + // See if this is a PostMessage event from the shim contract. If so, parse it. If not, bail out now. + postMessage, err := shimParsePostMessage(s.shimPostMessageDiscriminator, innerInstructions[startIdx].Data) + if err != nil { + return false, fmt.Errorf("failed to parse inner shim post message instruction %d, %d: %w", outerIdx, startIdx, err) + } + + if postMessage == nil { + return false, nil + } + + alreadyProcessed.add(outerIdx, startIdx) + + err = s.shimProcessRest(logger, whProgramIndex, shimProgramIndex, tx, innerInstructions, outerIdx, startIdx+1, postMessage, alreadyProcessed, isReobservation) + if err != nil { + return false, fmt.Errorf("failed to process inner instructions for inner shim instruction %d: %w", outerIdx, err) + } + + return true, nil +} + +// shimProcessRest performs the processing of the inner instructions that is common to both the direct and integrator case. It looks for the PostMessage from +// the core and the MessageEvent from the shim. Note that the startIdx parameter tells us where to start looking for these events. In the direct case, this +// will be zero. In the integrator case, it is one after the shim PostMessage event. +func (s *SolanaWatcher) shimProcessRest( + logger *zap.Logger, + whProgramIndex uint16, + shimProgramIndex uint16, + tx *solana.Transaction, + innerInstructions []solana.CompiledInstruction, + outerIdx int, + startIdx int, + postMessage *ShimPostMessageData, + alreadyProcessed ShimAlreadyProcessed, + isReobservation bool, +) error { + // Loop through the inner instructions after the shim PostMessage and do the following: + // 1) Find the core event and verify it is unreliable with an empty payload. + // 2) Find the shim MessageEvent to get the rest of the fields we need for the observation. + // 3) Verify that the shim MessageEvent comes after the core event. + + var verifiedCoreEvent bool + var messageEvent *ShimMessageEventData + var err error + coreEventFound := false + for idx := startIdx; idx < len(innerInstructions); idx++ { + inst := innerInstructions[idx] + if inst.ProgramIDIndex == whProgramIndex { + if verifiedCoreEvent, err = shimVerifyCoreMessage(inst.Data); err != nil { + return fmt.Errorf("failed to verify inner core instruction for shim instruction %d, %d: %w", outerIdx, idx, err) + } + alreadyProcessed.add(outerIdx, idx) + coreEventFound = true + } else if inst.ProgramIDIndex == shimProgramIndex { + if !coreEventFound { + return fmt.Errorf("detected an inner shim message event instruction before the core event for shim instruction %d, %d: %w", outerIdx, idx, err) + } + messageEvent, err = shimParseMessageEvent(s.shimMessageEventDiscriminator, inst.Data) + if err != nil { + return fmt.Errorf("failed to parse inner shim message event instruction for shim instruction %d, %d: %w", outerIdx, idx, err) + } + alreadyProcessed.add(outerIdx, idx) + } + + if verifiedCoreEvent && messageEvent != nil { + break + } + } + + if !verifiedCoreEvent { + return fmt.Errorf("failed to find inner core instruction for shim instruction %d", outerIdx) + } + + if messageEvent == nil { + return fmt.Errorf("failed to find inner shim message event instruction for shim instruction %d", outerIdx) + } + + commitment, err := postMessage.ConsistencyLevel.Commitment() + if err != nil { + return fmt.Errorf("failed to determine commitment for shim instruction %d: %w", outerIdx, err) + } + + if !s.checkCommitment(commitment, isReobservation) { + if logger.Level().Enabled(zapcore.DebugLevel) { + logger.Debug("skipping shim message which does not match the watcher commitment", + zap.Stringer("signature", tx.Signatures[0]), + zap.String("message commitment", string(commitment)), + zap.String("watcher commitment", string(s.commitment)), + ) + } + return nil + } + + observation := &common.MessagePublication{ + TxID: tx.Signatures[0][:], + Timestamp: time.Unix(int64(messageEvent.Timestamp), 0), + Nonce: postMessage.Nonce, + Sequence: messageEvent.Sequence, + EmitterChain: s.chainID, + EmitterAddress: messageEvent.EmitterAddress, + Payload: postMessage.Payload, + ConsistencyLevel: uint8(postMessage.ConsistencyLevel), + IsReobservation: isReobservation, + Unreliable: false, + } + + solanaMessagesConfirmed.WithLabelValues(s.networkName).Inc() + + if logger.Level().Enabled(s.msgObservedLogLevel) { + logger.Log(s.msgObservedLogLevel, "message observed from shim", + zap.Stringer("signature", tx.Signatures[0]), + zap.Time("timestamp", observation.Timestamp), + zap.Uint32("nonce", observation.Nonce), + zap.Uint64("sequence", observation.Sequence), + zap.Stringer("emitter_chain", observation.EmitterChain), + zap.Stringer("emitter_address", observation.EmitterAddress), + zap.Bool("isReobservation", false), + zap.Binary("payload", observation.Payload), + zap.Uint8("consistency_level", observation.ConsistencyLevel), + ) + } + + s.msgC <- observation + + return nil +} diff --git a/node/pkg/watchers/solana/shim_test.go b/node/pkg/watchers/solana/shim_test.go new file mode 100644 index 0000000000..5017fe949c --- /dev/null +++ b/node/pkg/watchers/solana/shim_test.go @@ -0,0 +1,1009 @@ +package solana + +import ( + "bytes" + "encoding/hex" + "encoding/json" + "testing" + "time" + + "github.com/certusone/wormhole/node/pkg/common" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/wormhole-foundation/wormhole/sdk/vaa" + "go.uber.org/zap" + + "github.com/gagliardetto/solana-go" + "github.com/gagliardetto/solana-go/rpc" +) + +func TestShimMatchPrefix(t *testing.T) { + type test struct { + input string + result bool + label string + } + tests := []test{ + {input: "d63264d12622074cdeadbeef", result: true, label: "Success"}, + {input: "d6", result: false, label: "Too_short"}, + {input: "", result: false, label: "Empty"}, + {input: shimPostMessageDiscriminatorStr, result: true, label: "Exact_match"}, + {input: "d73264d12622074cdeadbeef", result: false, label: "No_match"}, + } + + shimPostMessage, err := hex.DecodeString(shimPostMessageDiscriminatorStr) + require.NoError(t, err) + + for _, tc := range tests { + t.Run(tc.label, func(t *testing.T) { + buf, err := hex.DecodeString(tc.input) + require.NoError(t, err) + + assert.Equal(t, tc.result, shimMatchPrefix(shimPostMessage, buf)) + }) + } +} + +func Test_shimParsePostMessage(t *testing.T) { + shimPostMessage, err := hex.DecodeString(shimPostMessageDiscriminatorStr) + require.NoError(t, err) + + data, err := hex.DecodeString("d63264d12622074c2a000000010b00000068656c6c6f20776f726c64") + require.NoError(t, err) + + postMsgData, err := shimParsePostMessage(shimPostMessage, data) + require.NoError(t, err) + require.NotNil(t, postMsgData) + + assert.Equal(t, uint32(42), postMsgData.Nonce) + assert.Equal(t, consistencyLevelFinalized, postMsgData.ConsistencyLevel) + assert.Equal(t, 11, len(postMsgData.Payload)) + assert.True(t, bytes.Equal([]byte("hello world"), postMsgData.Payload)) +} + +func Test_shimVerifyCoreMessage(t *testing.T) { + data, err := hex.DecodeString("082a0000000000000001") + require.NoError(t, err) + + coreMsgDataAsExpected, err := shimVerifyCoreMessage(data) + require.NoError(t, err) + assert.True(t, coreMsgDataAsExpected) +} + +func Test_shimParseMessageEvent(t *testing.T) { + shimMessageEvent, err := hex.DecodeString("e445a52e51cb9a1d441b8f004d4c8970") + require.NoError(t, err) + + expectedEmitter, err := hex.DecodeString("041c657e845d65d009d59ceeb1dda172bd6bc9e7ee5a19e56573197cf7fdffde") + require.NoError(t, err) + + data, err := hex.DecodeString("e445a52e51cb9a1d441b8f004d4c8970041c657e845d65d009d59ceeb1dda172bd6bc9e7ee5a19e56573197cf7fdffde00000000000000007c5b8167") + require.NoError(t, err) + + msgEventData, err := shimParseMessageEvent(shimMessageEvent, data) + require.NoError(t, err) + require.NotNil(t, msgEventData) + + assert.True(t, bytes.Equal(expectedEmitter, msgEventData.EmitterAddress[:])) + assert.Equal(t, uint64(0), msgEventData.Sequence) + assert.Equal(t, uint32(1736530812), msgEventData.Timestamp) +} + +func TestShimAlreadyProcessed(t *testing.T) { + alreadyProcessed := ShimAlreadyProcessed{} + assert.False(t, alreadyProcessed.exists(5, 7)) + alreadyProcessed.add(5, 7) + assert.True(t, alreadyProcessed.exists(5, 7)) + assert.False(t, alreadyProcessed.exists(5, 8)) +} + +// WARNING: This only populates a few fields needed by the shim code! +func shimNewWatcherForTest(t *testing.T, msgC chan<- *common.MessagePublication) *SolanaWatcher { + t.Helper() + + rawContract := "worm2ZoG2kUd4vFXhvjh93UUH596ayRfgQ2MgjNMTth" + contractAddress, err := solana.PublicKeyFromBase58(rawContract) + require.NoError(t, err) + + shimContractStr := "EtZMZM22ViKMo4r5y4Anovs3wKQ2owUmDpjygnMMcdEX" + shimContractAddr, err := solana.PublicKeyFromBase58(shimContractStr) + require.NoError(t, err) + + s := &SolanaWatcher{ + contract: contractAddress, + rawContract: rawContract, + shimContractStr: shimContractStr, + shimContractAddr: shimContractAddr, + chainID: vaa.ChainIDSolana, + commitment: rpc.CommitmentFinalized, + msgC: msgC, + } + + s.shimSetup() + return s +} + +func TestVerifyShimSetup(t *testing.T) { + msgC := make(chan *common.MessagePublication, 10) + s := shimNewWatcherForTest(t, msgC) + assert.True(t, s.shimEnabled) + assert.Equal(t, shimPostMessageDiscriminatorStr, hex.EncodeToString(s.shimPostMessageDiscriminator)) + assert.Equal(t, shimMessageEventDiscriminatorStr, hex.EncodeToString(s.shimMessageEventDiscriminator)) +} + +func TestShimDirect(t *testing.T) { + eventJson := ` + { + "blockTime": 1736530812, + "meta": { + "computeUnitsConsumed": 84252, + "err": null, + "fee": 5000, + "innerInstructions": [ + { + "index": 1, + "instructions": [ + { + "accounts": [1, 3, 0, 4, 0, 2, 8, 5, 9], + "data": "TbyPDfUoyRxsr", + "programIdIndex": 10, + "stackHeight": 2 + }, + { + "accounts": [0, 4], + "data": "3Bxs4NLhqXb3ofom", + "programIdIndex": 5, + "stackHeight": 3 + }, + { + "accounts": [4], + "data": "9krTD1mFP1husSVM", + "programIdIndex": 5, + "stackHeight": 3 + }, + { + "accounts": [4], + "data": "SYXsBvR59WTsF4KEVN8LCQ1X9MekXCGPPNo3Af36taxCQBED", + "programIdIndex": 5, + "stackHeight": 3 + }, + { + "accounts": [0, 3], + "data": "3Bxs4bm7oSCPMeKR", + "programIdIndex": 5, + "stackHeight": 3 + }, + { + "accounts": [3], + "data": "9krTDGKFuDw9nLmM", + "programIdIndex": 5, + "stackHeight": 3 + }, + { + "accounts": [3], + "data": "SYXsBvR59WTsF4KEVN8LCQ1X9MekXCGPPNo3Af36taxCQBED", + "programIdIndex": 5, + "stackHeight": 3 + }, + { + "accounts": [7], + "data": "hTEY7jEqBPdDRkTWweeDPgyCUykRXEQVCUwrYmn4HZo84DdQrTJT2nBMiJFB3jXUVxHVd9mGq7BX9htuAN", + "programIdIndex": 6, + "stackHeight": 2 + } + ] + } + ], + "loadedAddresses": { + "readonly": [], + "writable": [] + }, + "logMessages": [ + "Program 11111111111111111111111111111111 invoke [1]", + "Program 11111111111111111111111111111111 success", + "Program EtZMZM22ViKMo4r5y4Anovs3wKQ2owUmDpjygnMMcdEX invoke [1]", + "Program log: Instruction: PostMessage", + "Program worm2ZoG2kUd4vFXhvjh93UUH596ayRfgQ2MgjNMTth invoke [2]", + "Program 11111111111111111111111111111111 invoke [3]", + "Program 11111111111111111111111111111111 success", + "Program 11111111111111111111111111111111 invoke [3]", + "Program 11111111111111111111111111111111 success", + "Program 11111111111111111111111111111111 invoke [3]", + "Program 11111111111111111111111111111111 success", + "Program log: Sequence: 0", + "Program 11111111111111111111111111111111 invoke [3]", + "Program 11111111111111111111111111111111 success", + "Program 11111111111111111111111111111111 invoke [3]", + "Program 11111111111111111111111111111111 success", + "Program 11111111111111111111111111111111 invoke [3]", + "Program 11111111111111111111111111111111 success", + "Program worm2ZoG2kUd4vFXhvjh93UUH596ayRfgQ2MgjNMTth consumed 60384 of 380989 compute units", + "Program worm2ZoG2kUd4vFXhvjh93UUH596ayRfgQ2MgjNMTth success", + "Program EtZMZM22ViKMo4r5y4Anovs3wKQ2owUmDpjygnMMcdEX invoke [2]", + "Program EtZMZM22ViKMo4r5y4Anovs3wKQ2owUmDpjygnMMcdEX consumed 2000 of 318068 compute units", + "Program EtZMZM22ViKMo4r5y4Anovs3wKQ2owUmDpjygnMMcdEX success", + "Program EtZMZM22ViKMo4r5y4Anovs3wKQ2owUmDpjygnMMcdEX consumed 84102 of 399850 compute units", + "Program EtZMZM22ViKMo4r5y4Anovs3wKQ2owUmDpjygnMMcdEX success" + ], + "postBalances": [ + 499999999997496260, 1057920, 2350640170, 1552080, 946560, 1, 1141440, 0, + 1169280, 1009200, 1141440 + ], + "postTokenBalances": [], + "preBalances": [ + 500000000000000000, 1057920, 2350640070, 0, 0, 1, 1141440, 0, 1169280, + 1009200, 1141440 + ], + "preTokenBalances": [], + "rewards": [], + "status": { + "Ok": null + } + }, + "slot": 3, + "transaction": { + "message": { + "header": { + "numReadonlySignedAccounts": 0, + "numReadonlyUnsignedAccounts": 6, + "numRequiredSignatures": 1 + }, + "accountKeys": [ + "H3kCPjpQDT4hgwWHr9E9pC99rZT2yHAwiwSwku6Bne9", + "2yVjuQwpsvdsrywzsJJVs9Ueh4zayyo5DYJbBNc3DDpn", + "9bFNrXNb2WTx8fMHXCheaZqkLZ3YCCaiqTftHxeintHy", + "9vohBn118ZEctRmuTRvoUZg1B1HGfSH8C5QX6twtUFrJ", + "HeccUHmoyMi5S6nuTcyUBh4w4me3FP541a52ErYJRT8a", + "11111111111111111111111111111111", + "EtZMZM22ViKMo4r5y4Anovs3wKQ2owUmDpjygnMMcdEX", + "HQS31aApX3DDkuXgSpV9XyDUNtFgQ31pUn5BNWHG2PSp", + "SysvarC1ock11111111111111111111111111111111", + "SysvarRent111111111111111111111111111111111", + "worm2ZoG2kUd4vFXhvjh93UUH596ayRfgQ2MgjNMTth" + ], + "recentBlockhash": "CMqPGm4icRdNuHsWJUK4Kgu4Cbe2nDQkYNqugQkKPa4Y", + "instructions": [ + { + "accounts": [0, 2], + "data": "3Bxs4HanWsHUZCbH", + "programIdIndex": 5, + "stackHeight": null + }, + { + "accounts": [1, 3, 0, 4, 0, 2, 8, 5, 9, 10, 7, 6], + "data": "3Cn8VBJReY7Bku3RduhBfYpk7tiw1R6pKcTWv9R", + "programIdIndex": 6, + "stackHeight": null + } + ], + "indexToProgramIds": {} + }, + "signatures": [ + "3NACxoZLehbdKGjTWZKTTXJPuovyqAih1AD1BrkYj8nzDAtjiQUEaNmhkoU1jcFfoPTAjrvnaLFgTafNWr3fBrdB" + ] + }, + "version": "legacy" + } + ` + + ///////// A bunch of checks to verify we parsed the JSON correctly. + var txRpc rpc.TransactionWithMeta + err := json.Unmarshal([]byte(eventJson), &txRpc) + require.NoError(t, err) + + tx, err := txRpc.GetParsedTransaction() + require.NoError(t, err) + + require.Equal(t, 2, len(tx.Message.Instructions)) + require.Equal(t, 1, len(txRpc.Meta.InnerInstructions)) + + ///////// Now we start the real test. + + logger := zap.NewNop() + msgC := make(chan *common.MessagePublication, 10) + s := shimNewWatcherForTest(t, msgC) + require.True(t, s.shimEnabled) + + var whProgramIndex uint16 + var shimProgramIndex uint16 + var shimFound bool + for n, key := range tx.Message.AccountKeys { + if key.Equals(s.contract) { + whProgramIndex = uint16(n) + } + if key.Equals(s.shimContractAddr) { + shimProgramIndex = uint16(n) + shimFound = true + } + } + + require.Equal(t, uint16(10), whProgramIndex) + require.True(t, shimFound) + require.Equal(t, uint16(6), shimProgramIndex) + + alreadyProcessed := ShimAlreadyProcessed{} + found, err := s.shimProcessTopLevelInstruction(logger, whProgramIndex, shimProgramIndex, tx, txRpc.Meta.InnerInstructions, 1, alreadyProcessed, false) + require.NoError(t, err) + require.True(t, found) + require.Equal(t, 1, len(s.msgC)) + + msg := <-msgC + require.NotNil(t, msg) + + // TODO: Can't check this until we switch MessagePublication.TxHash to be a byte array rather than a hash. + // expectedTxHash, err := vaa.StringToHash("7647cd98fd14c6e3cdfe35bc64bbc476abcdb5ab12e8d31e3151d132ed1e0eeb4595fda4779f69dbe00ff14aadad3fdcf537b88a22f48f3acb7b31f340670506") + // require.NoError(t, err) + + expectedEmitterAddress, err := vaa.StringToAddress("041c657e845d65d009d59ceeb1dda172bd6bc9e7ee5a19e56573197cf7fdffde") + require.NoError(t, err) + + // assert.Equal(t, expectedTxHash, msg.TxHash) + assert.Equal(t, time.Unix(int64(1736530812), 0), msg.Timestamp) + assert.Equal(t, uint32(42), msg.Nonce) + assert.Equal(t, uint64(0), msg.Sequence) + assert.Equal(t, vaa.ChainIDSolana, msg.EmitterChain) + assert.Equal(t, expectedEmitterAddress, msg.EmitterAddress) + assert.Equal(t, uint8(1), msg.ConsistencyLevel) + assert.Equal(t, "hello world", string(msg.Payload)) + assert.False(t, msg.IsReobservation) + assert.False(t, msg.Unreliable) +} + +func TestShimFromIntegrator(t *testing.T) { + eventJson := ` + { + "blockTime": 1736542615, + "meta": { + "computeUnitsConsumed": 48958, + "err": null, + "fee": 5000, + "innerInstructions": [ + { + "index": 1, + "instructions": [ + { + "accounts": [1, 4, 11, 3, 0, 2, 9, 5, 10, 12, 8, 7], + "data": "BeHixXyfSZ8dzFJzxTYRV18L6KSgTuqcTjaqeXgDVbXHC7mCjAgSyhz", + "programIdIndex": 7, + "stackHeight": 2 + }, + { + "accounts": [1, 4, 11, 3, 0, 2, 9, 5, 10], + "data": "T4xyMHqZi66JU", + "programIdIndex": 12, + "stackHeight": 3 + }, + { + "accounts": [8], + "data": "hTEY7jEqBPdDRkTWweeDPgzBpsiybJCHnVTVt8aCDem8p58yeQcQLJWk7hgGHrX79qZyKmCM89vCgPY7SE", + "programIdIndex": 7, + "stackHeight": 3 + } + ] + } + ], + "loadedAddresses": { "readonly": [], "writable": [] }, + "logMessages": [ + "Program 11111111111111111111111111111111 invoke [1]", + "Program 11111111111111111111111111111111 success", + "Program AEwubmehHNvkMXoH2C5MgDSemZgQ3HUSYpeaF3UrNZdQ invoke [1]", + "Program log: Instruction: PostMessage", + "Program EtZMZM22ViKMo4r5y4Anovs3wKQ2owUmDpjygnMMcdEX invoke [2]", + "Program log: Instruction: PostMessage", + "Program worm2ZoG2kUd4vFXhvjh93UUH596ayRfgQ2MgjNMTth invoke [3]", + "Program log: Sequence: 1", + "Program worm2ZoG2kUd4vFXhvjh93UUH596ayRfgQ2MgjNMTth consumed 18679 of 375180 compute units", + "Program worm2ZoG2kUd4vFXhvjh93UUH596ayRfgQ2MgjNMTth success", + "Program EtZMZM22ViKMo4r5y4Anovs3wKQ2owUmDpjygnMMcdEX invoke [3]", + "Program EtZMZM22ViKMo4r5y4Anovs3wKQ2owUmDpjygnMMcdEX consumed 2000 of 353964 compute units", + "Program EtZMZM22ViKMo4r5y4Anovs3wKQ2owUmDpjygnMMcdEX success", + "Program EtZMZM22ViKMo4r5y4Anovs3wKQ2owUmDpjygnMMcdEX consumed 33649 of 385286 compute units", + "Program EtZMZM22ViKMo4r5y4Anovs3wKQ2owUmDpjygnMMcdEX success", + "Program AEwubmehHNvkMXoH2C5MgDSemZgQ3HUSYpeaF3UrNZdQ consumed 48808 of 399850 compute units", + "Program AEwubmehHNvkMXoH2C5MgDSemZgQ3HUSYpeaF3UrNZdQ success" + ], + "postBalances": [ + 499999999997491140, 1057920, 2350640270, 946560, 1552080, 1, 1141440, + 1141440, 0, 1169280, 1009200, 0, 1141440 + ], + "postTokenBalances": [], + "preBalances": [ + 499999999997496260, 1057920, 2350640170, 946560, 1552080, 1, 1141440, + 1141440, 0, 1169280, 1009200, 0, 1141440 + ], + "preTokenBalances": [], + "rewards": [], + "status": { "Ok": null } + }, + "slot": 5, + "transaction": { + "message": { + "header": { + "numReadonlySignedAccounts": 0, + "numReadonlyUnsignedAccounts": 8, + "numRequiredSignatures": 1 + }, + "accountKeys": [ + "H3kCPjpQDT4hgwWHr9E9pC99rZT2yHAwiwSwku6Bne9", + "2yVjuQwpsvdsrywzsJJVs9Ueh4zayyo5DYJbBNc3DDpn", + "9bFNrXNb2WTx8fMHXCheaZqkLZ3YCCaiqTftHxeintHy", + "G4zDzQLktwvU4rn6A4dSAy9eU76cJxppCaumZhjjhXjv", + "GXUAWs1h6Nh1KLByvfeEyig9yn92LmKMjXDNxHGddyXR", + "11111111111111111111111111111111", + "AEwubmehHNvkMXoH2C5MgDSemZgQ3HUSYpeaF3UrNZdQ", + "EtZMZM22ViKMo4r5y4Anovs3wKQ2owUmDpjygnMMcdEX", + "HQS31aApX3DDkuXgSpV9XyDUNtFgQ31pUn5BNWHG2PSp", + "SysvarC1ock11111111111111111111111111111111", + "SysvarRent111111111111111111111111111111111", + "UvCifi1D8qj5FSJQdWL3KENnmaZjm62XUMa7NReceer", + "worm2ZoG2kUd4vFXhvjh93UUH596ayRfgQ2MgjNMTth" + ], + "recentBlockhash": "EqNQXbHebHwD1Vs4BSStmUVh2y6GjMxF3NBsDXsYuvRh", + "instructions": [ + { + "accounts": [0, 2], + "data": "3Bxs4HanWsHUZCbH", + "programIdIndex": 5, + "stackHeight": null + }, + { + "accounts": [0, 7, 1, 4, 11, 3, 2, 9, 5, 10, 12, 8], + "data": "cpyiD6CEaBD", + "programIdIndex": 6, + "stackHeight": null + } + ], + "indexToProgramIds": {} + }, + "signatures": [ + "G4jVHcH6F4Np1NRvYC6ridv5jGfPSVGgiEVZrjprpMdBFhJH7eVxUuxsvkDF2rkx4JseUftz3HnWoSomGt3czSY" + ] + }, + "version": "legacy" + } + ` + + ///////// A bunch of checks to verify we parsed the JSON correctly. + var txRpc rpc.TransactionWithMeta + err := json.Unmarshal([]byte(eventJson), &txRpc) + require.NoError(t, err) + + tx, err := txRpc.GetParsedTransaction() + require.NoError(t, err) + + require.Equal(t, 2, len(tx.Message.Instructions)) + require.Equal(t, 1, len(txRpc.Meta.InnerInstructions)) + + ///////// Now we start the real test. + + logger := zap.NewNop() + msgC := make(chan *common.MessagePublication, 10) + s := shimNewWatcherForTest(t, msgC) + require.True(t, s.shimEnabled) + + var whProgramIndex uint16 + var shimProgramIndex uint16 + var shimFound bool + for n, key := range tx.Message.AccountKeys { + if key.Equals(s.contract) { + whProgramIndex = uint16(n) + } + if key.Equals(s.shimContractAddr) { + shimProgramIndex = uint16(n) + shimFound = true + } + } + + require.Equal(t, uint16(12), whProgramIndex) + require.True(t, shimFound) + require.Equal(t, uint16(7), shimProgramIndex) + + alreadyProcessed := ShimAlreadyProcessed{} + found, err := s.shimProcessInnerInstruction(logger, whProgramIndex, shimProgramIndex, tx, txRpc.Meta.InnerInstructions[0].Instructions, 0, 0, alreadyProcessed, false) + require.NoError(t, err) + require.True(t, found) + require.Equal(t, 1, len(s.msgC)) + + msg := <-msgC + require.NotNil(t, msg) + + // TODO: Can't check this until we switch MessagePublication.TxHash to be a byte array rather than a hash. + // expectedTxHash, err := vaa.StringToHash("0cfdad68fdee85b49aea65e48c0d8def74f0968e7e1cf2c33305cfc33fec02a4742895c1d32f7c4093f75133104e70bd126fbbf8b71e5d8cb723a390cd976305") + // require.NoError(t, err) + + expectedEmitterAddress, err := vaa.StringToAddress("0726d66bf942e942332ddf34a2edb7b83c4cdfd25b15d4247e2e15057cdfc3cf") + require.NoError(t, err) + + // assert.Equal(t, expectedTxHash, msg.TxHash) + assert.Equal(t, time.Unix(int64(1736542615), 0), msg.Timestamp) + assert.Equal(t, uint32(0), msg.Nonce) + assert.Equal(t, uint64(1), msg.Sequence) + assert.Equal(t, vaa.ChainIDSolana, msg.EmitterChain) + assert.Equal(t, expectedEmitterAddress, msg.EmitterAddress) + assert.Equal(t, uint8(1), msg.ConsistencyLevel) + assert.Equal(t, "your message goes here!", string(msg.Payload)) + assert.False(t, msg.IsReobservation) + assert.False(t, msg.Unreliable) +} + +func TestShimDirectWithMultipleShimTransactions(t *testing.T) { + eventJson := ` + { + "blockTime": 1736530812, + "meta": { + "computeUnitsConsumed": 84252, + "err": null, + "fee": 5000, + "innerInstructions": [ + { + "index": 1, + "instructions": [ + { + "accounts": [1, 3, 0, 4, 0, 2, 8, 5, 9], + "data": "TbyPDfUoyRxsr", + "programIdIndex": 10, + "stackHeight": 2 + }, + { + "accounts": [0, 4], + "data": "3Bxs4NLhqXb3ofom", + "programIdIndex": 5, + "stackHeight": 3 + }, + { + "accounts": [4], + "data": "9krTD1mFP1husSVM", + "programIdIndex": 5, + "stackHeight": 3 + }, + { + "accounts": [4], + "data": "SYXsBvR59WTsF4KEVN8LCQ1X9MekXCGPPNo3Af36taxCQBED", + "programIdIndex": 5, + "stackHeight": 3 + }, + { + "accounts": [0, 3], + "data": "3Bxs4bm7oSCPMeKR", + "programIdIndex": 5, + "stackHeight": 3 + }, + { + "accounts": [3], + "data": "9krTDGKFuDw9nLmM", + "programIdIndex": 5, + "stackHeight": 3 + }, + { + "accounts": [3], + "data": "SYXsBvR59WTsF4KEVN8LCQ1X9MekXCGPPNo3Af36taxCQBED", + "programIdIndex": 5, + "stackHeight": 3 + }, + { + "accounts": [7], + "data": "hTEY7jEqBPdDRkTWweeDPgyCUykRXEQVCUwrYmn4HZo84DdQrTJT2nBMiJFB3jXUVxHVd9mGq7BX9htuAN", + "programIdIndex": 6, + "stackHeight": 2 + } + ] + }, + { + "index": 2, + "instructions": [ + { + "accounts": [1, 3, 0, 4, 0, 2, 8, 5, 9], + "data": "TbyPDfUoyRxsr", + "programIdIndex": 10, + "stackHeight": 2 + }, + { + "accounts": [7], + "data": "hTEY7jEqBPdDRkTWweeDPgyCUykRXEQVCUwrYmn4HZo84DdQrTJT2nBMiJFB3jXUVxJb75nmkwJkw2Varz", + "programIdIndex": 6, + "stackHeight": 2 + } + ] + } + ], + "loadedAddresses": { + "readonly": [], + "writable": [] + }, + "logMessages": [ + "Program 11111111111111111111111111111111 invoke [1]", + "Program 11111111111111111111111111111111 success", + "Program EtZMZM22ViKMo4r5y4Anovs3wKQ2owUmDpjygnMMcdEX invoke [1]", + "Program log: Instruction: PostMessage", + "Program worm2ZoG2kUd4vFXhvjh93UUH596ayRfgQ2MgjNMTth invoke [2]", + "Program 11111111111111111111111111111111 invoke [3]", + "Program 11111111111111111111111111111111 success", + "Program 11111111111111111111111111111111 invoke [3]", + "Program 11111111111111111111111111111111 success", + "Program 11111111111111111111111111111111 invoke [3]", + "Program 11111111111111111111111111111111 success", + "Program log: Sequence: 0", + "Program 11111111111111111111111111111111 invoke [3]", + "Program 11111111111111111111111111111111 success", + "Program 11111111111111111111111111111111 invoke [3]", + "Program 11111111111111111111111111111111 success", + "Program 11111111111111111111111111111111 invoke [3]", + "Program 11111111111111111111111111111111 success", + "Program worm2ZoG2kUd4vFXhvjh93UUH596ayRfgQ2MgjNMTth consumed 60384 of 380989 compute units", + "Program worm2ZoG2kUd4vFXhvjh93UUH596ayRfgQ2MgjNMTth success", + "Program EtZMZM22ViKMo4r5y4Anovs3wKQ2owUmDpjygnMMcdEX invoke [2]", + "Program EtZMZM22ViKMo4r5y4Anovs3wKQ2owUmDpjygnMMcdEX consumed 2000 of 318068 compute units", + "Program EtZMZM22ViKMo4r5y4Anovs3wKQ2owUmDpjygnMMcdEX success", + "Program EtZMZM22ViKMo4r5y4Anovs3wKQ2owUmDpjygnMMcdEX consumed 84102 of 399850 compute units", + "Program EtZMZM22ViKMo4r5y4Anovs3wKQ2owUmDpjygnMMcdEX success" + ], + "postBalances": [ + 499999999997496260, 1057920, 2350640170, 1552080, 946560, 1, 1141440, 0, + 1169280, 1009200, 1141440 + ], + "postTokenBalances": [], + "preBalances": [ + 500000000000000000, 1057920, 2350640070, 0, 0, 1, 1141440, 0, 1169280, + 1009200, 1141440 + ], + "preTokenBalances": [], + "rewards": [], + "status": { + "Ok": null + } + }, + "slot": 3, + "transaction": { + "message": { + "header": { + "numReadonlySignedAccounts": 0, + "numReadonlyUnsignedAccounts": 6, + "numRequiredSignatures": 1 + }, + "accountKeys": [ + "H3kCPjpQDT4hgwWHr9E9pC99rZT2yHAwiwSwku6Bne9", + "2yVjuQwpsvdsrywzsJJVs9Ueh4zayyo5DYJbBNc3DDpn", + "9bFNrXNb2WTx8fMHXCheaZqkLZ3YCCaiqTftHxeintHy", + "9vohBn118ZEctRmuTRvoUZg1B1HGfSH8C5QX6twtUFrJ", + "HeccUHmoyMi5S6nuTcyUBh4w4me3FP541a52ErYJRT8a", + "11111111111111111111111111111111", + "EtZMZM22ViKMo4r5y4Anovs3wKQ2owUmDpjygnMMcdEX", + "HQS31aApX3DDkuXgSpV9XyDUNtFgQ31pUn5BNWHG2PSp", + "SysvarC1ock11111111111111111111111111111111", + "SysvarRent111111111111111111111111111111111", + "worm2ZoG2kUd4vFXhvjh93UUH596ayRfgQ2MgjNMTth" + ], + "recentBlockhash": "CMqPGm4icRdNuHsWJUK4Kgu4Cbe2nDQkYNqugQkKPa4Y", + "instructions": [ + { + "accounts": [0, 2], + "data": "3Bxs4HanWsHUZCbH", + "programIdIndex": 5, + "stackHeight": null + }, + { + "accounts": [1, 3, 0, 4, 0, 2, 8, 5, 9, 10, 7, 6], + "data": "3Cn8VBJReY7Bku3RduhBfYpk7tiw1R6pKcTWv9R", + "programIdIndex": 6, + "stackHeight": null + }, + { + "accounts": [1, 3, 0, 4, 0, 2, 8, 5, 9, 10, 7, 6], + "data": "3Cn8VBJReY7BmhufSsqDhta36ruYh9KwEjTqqv3", + "programIdIndex": 6, + "stackHeight": null + } + ], + "indexToProgramIds": {} + }, + "signatures": [ + "3NACxoZLehbdKGjTWZKTTXJPuovyqAih1AD1BrkYj8nzDAtjiQUEaNmhkoU1jcFfoPTAjrvnaLFgTafNWr3fBrdB" + ] + }, + "version": "legacy" + } + ` + + ///////// A bunch of checks to verify we parsed the JSON correctly. + var txRpc rpc.TransactionWithMeta + err := json.Unmarshal([]byte(eventJson), &txRpc) + require.NoError(t, err) + + tx, err := txRpc.GetParsedTransaction() + require.NoError(t, err) + + require.Equal(t, 3, len(tx.Message.Instructions)) + require.Equal(t, 2, len(txRpc.Meta.InnerInstructions)) + + ///////// Set up the watcher and do the one-time transaction processing. + + logger := zap.NewNop() + msgC := make(chan *common.MessagePublication, 10) + s := shimNewWatcherForTest(t, msgC) + require.True(t, s.shimEnabled) + + var whProgramIndex uint16 + var shimProgramIndex uint16 + var shimFound bool + for n, key := range tx.Message.AccountKeys { + if key.Equals(s.contract) { + whProgramIndex = uint16(n) + } + if key.Equals(s.shimContractAddr) { + shimProgramIndex = uint16(n) + shimFound = true + } + } + + require.Equal(t, uint16(10), whProgramIndex) + require.True(t, shimFound) + require.Equal(t, uint16(6), shimProgramIndex) + + // TODO: Can't check this until we switch MessagePublication.TxHash to be a byte array rather than a hash. + // expectedTxHash, err := vaa.StringToHash("7647cd98fd14c6e3cdfe35bc64bbc476abcdb5ab12e8d31e3151d132ed1e0eeb4595fda4779f69dbe00ff14aadad3fdcf537b88a22f48f3acb7b31f340670506") + // require.NoError(t, err) + + expectedEmitterAddress, err := vaa.StringToAddress("041c657e845d65d009d59ceeb1dda172bd6bc9e7ee5a19e56573197cf7fdffde") + require.NoError(t, err) + + //////////// Process the first shim top level instruction. + + alreadyProcessed := ShimAlreadyProcessed{} + found, err := s.shimProcessTopLevelInstruction(logger, whProgramIndex, shimProgramIndex, tx, txRpc.Meta.InnerInstructions, 1, alreadyProcessed, false) + require.NoError(t, err) + require.True(t, found) + require.Equal(t, 1, len(s.msgC)) + + msg := <-msgC + require.NotNil(t, msg) + + // assert.Equal(t, expectedTxHash, msg.TxHash) + assert.Equal(t, time.Unix(int64(1736530812), 0), msg.Timestamp) + assert.Equal(t, uint32(42), msg.Nonce) + assert.Equal(t, uint64(0), msg.Sequence) + assert.Equal(t, vaa.ChainIDSolana, msg.EmitterChain) + assert.Equal(t, expectedEmitterAddress, msg.EmitterAddress) + assert.Equal(t, uint8(1), msg.ConsistencyLevel) + assert.Equal(t, "hello world", string(msg.Payload)) + assert.False(t, msg.IsReobservation) + assert.False(t, msg.Unreliable) + + //////////// Process the second shim top level instruction. + + found, err = s.shimProcessTopLevelInstruction(logger, whProgramIndex, shimProgramIndex, tx, txRpc.Meta.InnerInstructions, 2, alreadyProcessed, false) + require.NoError(t, err) + require.True(t, found) + require.Equal(t, 1, len(s.msgC)) + + msg = <-msgC + require.NotNil(t, msg) + + // assert.Equal(t, expectedTxHash, msg.TxHash) + assert.Equal(t, time.Unix(int64(1736530813), 0), msg.Timestamp) + assert.Equal(t, uint32(43), msg.Nonce) + assert.Equal(t, uint64(1), msg.Sequence) + assert.Equal(t, vaa.ChainIDSolana, msg.EmitterChain) + assert.Equal(t, expectedEmitterAddress, msg.EmitterAddress) + assert.Equal(t, uint8(1), msg.ConsistencyLevel) + assert.Equal(t, "hello world", string(msg.Payload)) + assert.False(t, msg.IsReobservation) + assert.False(t, msg.Unreliable) +} + +func TestShimFromIntegratorWithMultipleShimTransactions(t *testing.T) { + eventJson := ` + { + "blockTime": 1736542615, + "meta": { + "computeUnitsConsumed": 48958, + "err": null, + "fee": 5000, + "innerInstructions": [ + { + "index": 1, + "instructions": [ + { + "accounts": [1, 4, 11, 3, 0, 2, 9, 5, 10, 12, 8, 7], + "data": "BeHixXyfSZ8dzFJzxTYRV18L6KSgTuqcTjaqeXgDVbXHC7mCjAgSyhz", + "programIdIndex": 7, + "stackHeight": 2 + }, + { + "accounts": [1, 4, 11, 3, 0, 2, 9, 5, 10], + "data": "T4xyMHqZi66JU", + "programIdIndex": 12, + "stackHeight": 3 + }, + { + "accounts": [8], + "data": "hTEY7jEqBPdDRkTWweeDPgzBpsiybJCHnVTVt8aCDem8p58yeQcQLJWk7hgGHrX79qZyKmCM89vCgPY7SE", + "programIdIndex": 7, + "stackHeight": 3 + }, + { + "accounts": [1, 4, 11, 3, 0, 2, 9, 5, 10, 12, 8, 7], + "data": "BeHixXyfSZ8gpCS9kw5xbo7V9NN3f6bDP3Bi4G3sPsbod54LvCUimUU", + "programIdIndex": 7, + "stackHeight": 2 + }, + { + "accounts": [1, 4, 11, 3, 0, 2, 9, 5, 10], + "data": "T4xyMHqZi66JU", + "programIdIndex": 12, + "stackHeight": 3 + }, + { + "accounts": [8], + "data": "hTEY7jEqBPdDRkTWweeDPgzBpsiybJCHnVTVt8aCDem8p58yeQcQLJWk7hgGHrX79qb4ohDr3z3STi8o8r", + "programIdIndex": 7, + "stackHeight": 3 + } + ] + } + ], + "loadedAddresses": { "readonly": [], "writable": [] }, + "logMessages": [ + "Program 11111111111111111111111111111111 invoke [1]", + "Program 11111111111111111111111111111111 success", + "Program AEwubmehHNvkMXoH2C5MgDSemZgQ3HUSYpeaF3UrNZdQ invoke [1]", + "Program log: Instruction: PostMessage", + "Program EtZMZM22ViKMo4r5y4Anovs3wKQ2owUmDpjygnMMcdEX invoke [2]", + "Program log: Instruction: PostMessage", + "Program worm2ZoG2kUd4vFXhvjh93UUH596ayRfgQ2MgjNMTth invoke [3]", + "Program log: Sequence: 1", + "Program worm2ZoG2kUd4vFXhvjh93UUH596ayRfgQ2MgjNMTth consumed 18679 of 375180 compute units", + "Program worm2ZoG2kUd4vFXhvjh93UUH596ayRfgQ2MgjNMTth success", + "Program EtZMZM22ViKMo4r5y4Anovs3wKQ2owUmDpjygnMMcdEX invoke [3]", + "Program EtZMZM22ViKMo4r5y4Anovs3wKQ2owUmDpjygnMMcdEX consumed 2000 of 353964 compute units", + "Program EtZMZM22ViKMo4r5y4Anovs3wKQ2owUmDpjygnMMcdEX success", + "Program EtZMZM22ViKMo4r5y4Anovs3wKQ2owUmDpjygnMMcdEX consumed 33649 of 385286 compute units", + "Program EtZMZM22ViKMo4r5y4Anovs3wKQ2owUmDpjygnMMcdEX success", + "Program AEwubmehHNvkMXoH2C5MgDSemZgQ3HUSYpeaF3UrNZdQ consumed 48808 of 399850 compute units", + "Program AEwubmehHNvkMXoH2C5MgDSemZgQ3HUSYpeaF3UrNZdQ success" + ], + "postBalances": [ + 499999999997491140, 1057920, 2350640270, 946560, 1552080, 1, 1141440, + 1141440, 0, 1169280, 1009200, 0, 1141440 + ], + "postTokenBalances": [], + "preBalances": [ + 499999999997496260, 1057920, 2350640170, 946560, 1552080, 1, 1141440, + 1141440, 0, 1169280, 1009200, 0, 1141440 + ], + "preTokenBalances": [], + "rewards": [], + "status": { "Ok": null } + }, + "slot": 5, + "transaction": { + "message": { + "header": { + "numReadonlySignedAccounts": 0, + "numReadonlyUnsignedAccounts": 8, + "numRequiredSignatures": 1 + }, + "accountKeys": [ + "H3kCPjpQDT4hgwWHr9E9pC99rZT2yHAwiwSwku6Bne9", + "2yVjuQwpsvdsrywzsJJVs9Ueh4zayyo5DYJbBNc3DDpn", + "9bFNrXNb2WTx8fMHXCheaZqkLZ3YCCaiqTftHxeintHy", + "G4zDzQLktwvU4rn6A4dSAy9eU76cJxppCaumZhjjhXjv", + "GXUAWs1h6Nh1KLByvfeEyig9yn92LmKMjXDNxHGddyXR", + "11111111111111111111111111111111", + "AEwubmehHNvkMXoH2C5MgDSemZgQ3HUSYpeaF3UrNZdQ", + "EtZMZM22ViKMo4r5y4Anovs3wKQ2owUmDpjygnMMcdEX", + "HQS31aApX3DDkuXgSpV9XyDUNtFgQ31pUn5BNWHG2PSp", + "SysvarC1ock11111111111111111111111111111111", + "SysvarRent111111111111111111111111111111111", + "UvCifi1D8qj5FSJQdWL3KENnmaZjm62XUMa7NReceer", + "worm2ZoG2kUd4vFXhvjh93UUH596ayRfgQ2MgjNMTth" + ], + "recentBlockhash": "EqNQXbHebHwD1Vs4BSStmUVh2y6GjMxF3NBsDXsYuvRh", + "instructions": [ + { + "accounts": [0, 2], + "data": "3Bxs4HanWsHUZCbH", + "programIdIndex": 5, + "stackHeight": null + }, + { + "accounts": [0, 7, 1, 4, 11, 3, 2, 9, 5, 10, 12, 8], + "data": "cpyiD6CEaBD", + "programIdIndex": 6, + "stackHeight": null + } + ], + "indexToProgramIds": {} + }, + "signatures": [ + "G4jVHcH6F4Np1NRvYC6ridv5jGfPSVGgiEVZrjprpMdBFhJH7eVxUuxsvkDF2rkx4JseUftz3HnWoSomGt3czSY" + ] + }, + "version": "legacy" + } + ` + + ///////// A bunch of checks to verify we parsed the JSON correctly. + var txRpc rpc.TransactionWithMeta + err := json.Unmarshal([]byte(eventJson), &txRpc) + require.NoError(t, err) + + tx, err := txRpc.GetParsedTransaction() + require.NoError(t, err) + + require.Equal(t, 2, len(tx.Message.Instructions)) + require.Equal(t, 1, len(txRpc.Meta.InnerInstructions)) + + ///////// Set up the watcher and do the one-time transaction processing. + + logger := zap.NewNop() + msgC := make(chan *common.MessagePublication, 10) + s := shimNewWatcherForTest(t, msgC) + require.True(t, s.shimEnabled) + + var whProgramIndex uint16 + var shimProgramIndex uint16 + var shimFound bool + for n, key := range tx.Message.AccountKeys { + if key.Equals(s.contract) { + whProgramIndex = uint16(n) + } + if key.Equals(s.shimContractAddr) { + shimProgramIndex = uint16(n) + shimFound = true + } + } + + require.Equal(t, uint16(12), whProgramIndex) + require.True(t, shimFound) + require.Equal(t, uint16(7), shimProgramIndex) + + // TODO: Can't check this until we switch MessagePublication.TxHash to be a byte array rather than a hash. + // expectedTxHash, err := vaa.StringToHash("0cfdad68fdee85b49aea65e48c0d8def74f0968e7e1cf2c33305cfc33fec02a4742895c1d32f7c4093f75133104e70bd126fbbf8b71e5d8cb723a390cd976305") + // require.NoError(t, err) + + expectedEmitterAddress, err := vaa.StringToAddress("0726d66bf942e942332ddf34a2edb7b83c4cdfd25b15d4247e2e15057cdfc3cf") + require.NoError(t, err) + + //////////// Process the first shim inner instruction. + + alreadyProcessed := ShimAlreadyProcessed{} + found, err := s.shimProcessInnerInstruction(logger, whProgramIndex, shimProgramIndex, tx, txRpc.Meta.InnerInstructions[0].Instructions, 0, 0, alreadyProcessed, false) + require.NoError(t, err) + require.True(t, found) + require.Equal(t, 1, len(s.msgC)) + + msg := <-msgC + require.NotNil(t, msg) + + // assert.Equal(t, expectedTxHash, msg.TxHash) + assert.Equal(t, time.Unix(int64(1736542615), 0), msg.Timestamp) + assert.Equal(t, uint32(0), msg.Nonce) + assert.Equal(t, uint64(1), msg.Sequence) + assert.Equal(t, vaa.ChainIDSolana, msg.EmitterChain) + assert.Equal(t, expectedEmitterAddress, msg.EmitterAddress) + assert.Equal(t, uint8(1), msg.ConsistencyLevel) + assert.Equal(t, "your message goes here!", string(msg.Payload)) + assert.False(t, msg.IsReobservation) + assert.False(t, msg.Unreliable) + + //////////// Process the second shim inner instruction. + + found, err = s.shimProcessInnerInstruction(logger, whProgramIndex, shimProgramIndex, tx, txRpc.Meta.InnerInstructions[0].Instructions, 0, 3, alreadyProcessed, false) + require.NoError(t, err) + require.True(t, found) + require.Equal(t, 1, len(s.msgC)) + + msg = <-msgC + require.NotNil(t, msg) + + // assert.Equal(t, expectedTxHash, msg.TxHash) + assert.Equal(t, time.Unix(int64(1736542616), 0), msg.Timestamp) + assert.Equal(t, uint32(42), msg.Nonce) + assert.Equal(t, uint64(2), msg.Sequence) + assert.Equal(t, vaa.ChainIDSolana, msg.EmitterChain) + assert.Equal(t, expectedEmitterAddress, msg.EmitterAddress) + assert.Equal(t, uint8(1), msg.ConsistencyLevel) + assert.Equal(t, "your message goes here!", string(msg.Payload)) + assert.False(t, msg.IsReobservation) + assert.False(t, msg.Unreliable) +} diff --git a/node/pkg/watchers/sui/watcher.go b/node/pkg/watchers/sui/watcher.go index fae0635d52..8327092ebc 100644 --- a/node/pkg/watchers/sui/watcher.go +++ b/node/pkg/watchers/sui/watcher.go @@ -262,7 +262,7 @@ func (e *Watcher) inspectBody(logger *zap.Logger, body SuiResult, isReobservatio } observation := &common.MessagePublication{ - TxHash: txHashEthFormat, + TxID: txHashEthFormat.Bytes(), Timestamp: time.Unix(ts, 0), Nonce: uint32(*fields.Nonce), Sequence: seq, @@ -276,7 +276,7 @@ func (e *Watcher) inspectBody(logger *zap.Logger, body SuiResult, isReobservatio suiMessagesConfirmed.Inc() logger.Info("message observed", - zap.Stringer("txHash", observation.TxHash), + zap.String("txHash", observation.TxIDString()), zap.Time("timestamp", observation.Timestamp), zap.Uint32("nonce", observation.Nonce), zap.Uint64("sequence", observation.Sequence), diff --git a/proto/gossip/v1/gossip.proto b/proto/gossip/v1/gossip.proto index b71be47543..f053128cd8 100644 --- a/proto/gossip/v1/gossip.proto +++ b/proto/gossip/v1/gossip.proto @@ -6,7 +6,7 @@ option go_package = "github.com/certusone/wormhole/node/pkg/proto/gossip/v1;goss message GossipMessage { oneof message { - SignedObservation signed_observation = 2; + // SignedObservation signed_observation = 2; SignedHeartbeat signed_heartbeat = 3; SignedVAAWithQuorum signed_vaa_with_quorum = 4; SignedObservationRequest signed_observation_request = 5; @@ -72,34 +72,6 @@ message Heartbeat { bytes p2p_node_id = 9; } -// A SignedObservation is a signed statement by a given guardian node -// that they observed a given event. -// -// Observations always result from an external, final event being observed. -// Examples are emitted messages in finalized blocks on a block or guardian set changes -// injected by node operators after reaching off-chain consensus. -// -// The event is uniquely identified by its hashed (tx_hash, nonce, values...) tuple. -// -// Other nodes will verify the signature. Once any node has observed a quorum of -// guardians submitting valid signatures for a given hash, they can be assembled into a VAA. -// -// Messages without valid signature are dropped unceremoniously. -message SignedObservation { - // Guardian pubkey as truncated eth address. - bytes addr = 1; - // The observation's deterministic, unique hash. - bytes hash = 2; - // ECSDA signature of the hash using the node's guardian key. - bytes signature = 3; - // Transaction hash this observation was made from. - // Optional, included for observability. - bytes tx_hash = 4; - // Message ID (chain/emitter/seq) for this observation. - // Optional, included for observability. - string message_id = 5; -} - // A SignedVAAWithQuorum message is sent by nodes whenever one of the VAAs they observed // reached a 2/3+ quorum to be considered valid. Signed VAAs are broadcasted to the gossip // network to allow nodes to persist them even if they failed to observe the signature. diff --git a/proto/publicrpc/v1/publicrpc.proto b/proto/publicrpc/v1/publicrpc.proto index 5482e03e14..b6d6b8907c 100644 --- a/proto/publicrpc/v1/publicrpc.proto +++ b/proto/publicrpc/v1/publicrpc.proto @@ -35,9 +35,11 @@ enum ChainID { CHAIN_ID_OPTIMISM = 24; CHAIN_ID_GNOSIS = 25; CHAIN_ID_PYTHNET = 26; + // 27 belongs to a chain that was never deployed. CHAIN_ID_XPLA = 28; CHAIN_ID_BTC = 29; CHAIN_ID_BASE = 30; + CHAIN_ID_FILECOIN = 31; CHAIN_ID_SEI = 32; CHAIN_ID_ROOTSTOCK = 33; CHAIN_ID_SCROLL = 34; @@ -47,10 +49,15 @@ enum ChainID { CHAIN_ID_LINEA = 38; CHAIN_ID_BERACHAIN = 39; CHAIN_ID_SEIEVM = 40; + CHAIN_ID_ECLIPSE = 41; + CHAIN_ID_BOB = 42; CHAIN_ID_SNAXCHAIN = 43; CHAIN_ID_UNICHAIN = 44; CHAIN_ID_WORLDCHAIN = 45; CHAIN_ID_INK = 46; + CHAIN_ID_HYPER_EVM = 47; + CHAIN_ID_MONAD = 48; + CHAIN_ID_MOVEMENT = 49; CHAIN_ID_WORMCHAIN = 3104; CHAIN_ID_COSMOSHUB = 4000; CHAIN_ID_EVMOS = 4001; @@ -61,6 +68,7 @@ enum ChainID { CHAIN_ID_SEDA = 4006; CHAIN_ID_DYMENSION = 4007; CHAIN_ID_PROVENANCE = 4008; + CHAIN_ID_NOBLE = 4009; CHAIN_ID_SEPOLIA = 10002; CHAIN_ID_ARBITRUM_SEPOLIA = 10003; CHAIN_ID_BASE_SEPOLIA = 10004; diff --git a/scripts/check-docker-pin.sh b/scripts/check-docker-pin.sh index 9c2eb96b13..35d43801f5 100755 --- a/scripts/check-docker-pin.sh +++ b/scripts/check-docker-pin.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# This script is checks to that all our Docker images are pinned to a specific SHA256 hash +# This script checks that all our Docker images are pinned to a specific SHA256 hash. # # References as to why... # - https://nickjanetakis.com/blog/docker-tip-18-please-pin-your-docker-image-versions diff --git a/scripts/sui-transfer-verifier.sh b/scripts/sui-transfer-verifier.sh new file mode 100755 index 0000000000..3954baf593 --- /dev/null +++ b/scripts/sui-transfer-verifier.sh @@ -0,0 +1,20 @@ +#!/usr/bin/env bash +set -xeuo pipefail + +# mainnet core contract +CORE_CONTRACT="0x5306f64e312b581766351c07af79c72fcb1cd25147157fdc2f8ad76de9a3fb6a" +# mainnet token bridge contract +TOKEN_BRIDGE_CONTRACT="0x26efee2b51c911237888e5dc6702868abca3c7ac12c53f76ef8eba0697695e3d" + +TOKEN_BRIDGE_EMITTER="0xccceeb29348f71bdd22ffef43a2a19c1f5b5e17c5cca5411529120182672ade5" + +RPC= + +LOG_LEVEL="info" + +# Do `make node` first to compile transfer-verifier into guardiand +/guardiand transfer-verifier-sui --suiRPC "${RPC}" \ + --suiCoreContract "${CORE_CONTRACT}" \ + --suiTokenBridgeContract "${TOKEN_BRIDGE_CONTRACT}" \ + --suiTokenBridgeEmitter "${TOKEN_BRIDGE_EMITTER}" \ + --logLevel "${LOG_LEVEL}" diff --git a/scripts/transfer-verifier-localnet.sh b/scripts/transfer-verifier-localnet.sh new file mode 100755 index 0000000000..2fbdbd7350 --- /dev/null +++ b/scripts/transfer-verifier-localnet.sh @@ -0,0 +1,31 @@ +#!/usr/bin/env bash +# Before running this script, ensure that anvil is running, e.g.: +# +# anvil --host 0.0.0.0 --base-fee 0 --fork-url $(worm info rpc mainnet ethereum) --mnemonic "myth like bonus scare over problem client lizard pioneer submit female collect" --fork-block-number 20641947 --fork-chain-id 1 --chain-id 1 --steps-tracing --auto-impersonate + +set -xeuo pipefail + +# mainnet +# CORE_CONTRACT="0x98f3c9e6E3fAce36bAAd05FE09d375Ef1464288B" +# TOKEN_BRIDGE_CONTRACT="0x3ee18B2214AFF97000D974cf647E7C347E8fa585" +# WRAPPED_NATIVE_CONTRACT="0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2" +# devnet +CORE_CONTRACT="0xC89Ce4735882C9F0f0FE26686c53074E09B0D550" +TOKEN_BRIDGE_CONTRACT="0x0290FB167208Af455bB137780163b7B7a9a10C16" +WRAPPED_NATIVE_CONTRACT="0xDDb64fE46a91D46ee29420539FC25FD07c5FEa3E" + +# Needs to be websockets so that the eth connector can get notifications +ETH_RPC_DEVNET="ws://localhost:8545" # from Tilt, via Anvil + +# RPC="${ALCHEMY_RPC}" +RPC="${ETH_RPC_DEVNET}" + +LOG_LEVEL="debug" + +# Do `make node` first to compile transfer-verifier into guardiand. Note that the telemetry parameters are omitted here. +./build/bin/guardiand transfer-verifier evm \ + --rpcUrl "${RPC}" \ + --coreContract "${CORE_CONTRACT}" \ + --tokenContract "${TOKEN_BRIDGE_CONTRACT}" \ + --wrappedNativeContract "${WRAPPED_NATIVE_CONTRACT}" \ + --logLevel "${LOG_LEVEL}" diff --git a/sdk/testnet_consts.go b/sdk/testnet_consts.go index 2a9b689900..a19e89d336 100644 --- a/sdk/testnet_consts.go +++ b/sdk/testnet_consts.go @@ -35,15 +35,18 @@ var knownTestnetTokenbridgeEmitters = map[vaa.ChainID]string{ vaa.ChainIDSei: "9328673cb5de3fd99974cefbbd90fea033f4c59a572abfd7e1a4eebcc5d18157", vaa.ChainIDScroll: "00000000000000000000000022427d90B7dA3fA4642F7025A854c7254E4e45BF", vaa.ChainIDMantle: "00000000000000000000000075Bfa155a9D7A3714b0861c8a8aF0C4633c45b5D", + vaa.ChainIDMovement: "0000000000000000000000000000000000000000000000000000000000000002", vaa.ChainIDBlast: "000000000000000000000000430855B4D43b8AEB9D2B9869B74d58dda79C0dB2", vaa.ChainIDXLayer: "000000000000000000000000dA91a06299BBF302091B053c6B9EF86Eff0f930D", vaa.ChainIDLinea: "000000000000000000000000C7A204bDBFe983FCD8d8E61D02b475D4073fF97e", vaa.ChainIDBerachain: "000000000000000000000000a10f2eF61dE1f19f586ab8B6F2EbA89bACE63F7a", + vaa.ChainIDSeiEVM: "00000000000000000000000023908A62110e21C04F3A4e011d24F901F911744A", vaa.ChainIDSnaxchain: "000000000000000000000000a10f2eF61dE1f19f586ab8B6F2EbA89bACE63F7a", vaa.ChainIDUnichain: "000000000000000000000000a10f2eF61dE1f19f586ab8B6F2EbA89bACE63F7a", vaa.ChainIDWorldchain: "000000000000000000000000430855B4D43b8AEB9D2B9869B74d58dda79C0dB2", vaa.ChainIDInk: "000000000000000000000000376428e7f26D5867e69201b275553C45B09EE090", vaa.ChainIDHyperEVM: "0000000000000000000000004a8bc80Ed5a4067f1CCf107057b8270E0cC11A78", + vaa.ChainIDMonad: "000000000000000000000000F323dcDe4d33efe83cf455F78F9F6cc656e6B659", vaa.ChainIDSepolia: "000000000000000000000000DB5492265f6038831E89f495670FF909aDe94bd9", vaa.ChainIDHolesky: "00000000000000000000000076d093BbaE4529a342080546cAFEec4AcbA59EC6", vaa.ChainIDArbitrumSepolia: "000000000000000000000000C7A204bDBFe983FCD8d8E61D02b475D4073fF97e", diff --git a/sdk/vaa/structs.go b/sdk/vaa/structs.go index 3ddd8ee835..bed3b106bb 100644 --- a/sdk/vaa/structs.go +++ b/sdk/vaa/structs.go @@ -147,18 +147,12 @@ func (c ChainID) String() string { return "avalanche" case ChainIDOasis: return "oasis" + case ChainIDAlgorand: + return "algorand" case ChainIDAurora: return "aurora" case ChainIDFantom: return "fantom" - case ChainIDAlgorand: - return "algorand" - case ChainIDNear: - return "near" - case ChainIDAptos: - return "aptos" - case ChainIDSui: - return "sui" case ChainIDKarura: return "karura" case ChainIDAcala: @@ -167,6 +161,8 @@ func (c ChainID) String() string { return "klaytn" case ChainIDCelo: return "celo" + case ChainIDNear: + return "near" case ChainIDMoonbeam: return "moonbeam" case ChainIDTerra2: @@ -175,6 +171,10 @@ func (c ChainID) String() string { return "injective" case ChainIDOsmosis: return "osmosis" + case ChainIDSui: + return "sui" + case ChainIDAptos: + return "aptos" case ChainIDArbitrum: return "arbitrum" case ChainIDOptimism: @@ -183,14 +183,14 @@ func (c ChainID) String() string { return "gnosis" case ChainIDPythNet: return "pythnet" - case ChainIDWormchain: - return "wormchain" case ChainIDXpla: return "xpla" case ChainIDBtc: return "btc" case ChainIDBase: return "base" + case ChainIDFileCoin: + return "filecoin" case ChainIDSei: return "sei" case ChainIDRootstock: @@ -209,6 +209,10 @@ func (c ChainID) String() string { return "berachain" case ChainIDSeiEVM: return "seievm" + case ChainIDEclipse: + return "eclipse" + case ChainIDBOB: + return "bob" case ChainIDSnaxchain: return "snaxchain" case ChainIDUnichain: @@ -219,6 +223,12 @@ func (c ChainID) String() string { return "ink" case ChainIDHyperEVM: return "hyperevm" + case ChainIDMonad: + return "monad" + case ChainIDMovement: + return "movement" + case ChainIDWormchain: + return "wormchain" case ChainIDCosmoshub: return "cosmoshub" case ChainIDEvmos: @@ -276,18 +286,12 @@ func ChainIDFromString(s string) (ChainID, error) { return ChainIDAvalanche, nil case "oasis": return ChainIDOasis, nil + case "algorand": + return ChainIDAlgorand, nil case "aurora": return ChainIDAurora, nil case "fantom": return ChainIDFantom, nil - case "algorand": - return ChainIDAlgorand, nil - case "near": - return ChainIDNear, nil - case "sui": - return ChainIDSui, nil - case "aptos": - return ChainIDAptos, nil case "karura": return ChainIDKarura, nil case "acala": @@ -296,6 +300,8 @@ func ChainIDFromString(s string) (ChainID, error) { return ChainIDKlaytn, nil case "celo": return ChainIDCelo, nil + case "near": + return ChainIDNear, nil case "moonbeam": return ChainIDMoonbeam, nil case "terra2": @@ -304,6 +310,10 @@ func ChainIDFromString(s string) (ChainID, error) { return ChainIDInjective, nil case "osmosis": return ChainIDOsmosis, nil + case "sui": + return ChainIDSui, nil + case "aptos": + return ChainIDAptos, nil case "arbitrum": return ChainIDArbitrum, nil case "optimism": @@ -312,14 +322,14 @@ func ChainIDFromString(s string) (ChainID, error) { return ChainIDGnosis, nil case "pythnet": return ChainIDPythNet, nil - case "wormchain": - return ChainIDWormchain, nil case "xpla": return ChainIDXpla, nil case "btc": return ChainIDBtc, nil case "base": return ChainIDBase, nil + case "filecoin": + return ChainIDFileCoin, nil case "sei": return ChainIDSei, nil case "rootstock": @@ -336,6 +346,12 @@ func ChainIDFromString(s string) (ChainID, error) { return ChainIDLinea, nil case "berachain": return ChainIDBerachain, nil + case "seievm": + return ChainIDSeiEVM, nil + case "eclipse": + return ChainIDEclipse, nil + case "bob": + return ChainIDBOB, nil case "snaxchain": return ChainIDSnaxchain, nil case "unichain": @@ -346,10 +362,14 @@ func ChainIDFromString(s string) (ChainID, error) { return ChainIDInk, nil case "hyperevm": return ChainIDHyperEVM, nil + case "monad": + return ChainIDMonad, nil + case "movement": + return ChainIDMovement, nil + case "wormchain": + return ChainIDWormchain, nil case "cosmoshub": return ChainIDCosmoshub, nil - case "seievm": - return ChainIDSeiEVM, nil case "evmos": return ChainIDEvmos, nil case "kujira": @@ -417,6 +437,7 @@ func GetAllNetworkIDs() []ChainID { ChainIDXpla, ChainIDBtc, ChainIDBase, + ChainIDFileCoin, ChainIDSei, ChainIDRootstock, ChainIDScroll, @@ -425,11 +446,16 @@ func GetAllNetworkIDs() []ChainID { ChainIDXLayer, ChainIDLinea, ChainIDBerachain, + ChainIDSeiEVM, + ChainIDEclipse, + ChainIDBOB, ChainIDSnaxchain, ChainIDUnichain, ChainIDWorldchain, ChainIDInk, ChainIDHyperEVM, + ChainIDMonad, + ChainIDMovement, ChainIDWormchain, ChainIDCosmoshub, ChainIDEvmos, @@ -451,6 +477,7 @@ func GetAllNetworkIDs() []ChainID { } } +// NOTE: Please keep these in numerical order. const ( ChainIDUnset ChainID = 0 // ChainIDSolana is the ChainID of Solana @@ -504,12 +531,15 @@ const ( ChainIDGnosis ChainID = 25 // ChainIDPythNet is the ChainID of PythNet ChainIDPythNet ChainID = 26 + // NOTE: 27 belongs to a chain that was never deployed. // ChainIDXpla is the ChainID of Xpla ChainIDXpla ChainID = 28 //ChainIDBtc is the ChainID of Bitcoin ChainIDBtc ChainID = 29 // ChainIDBase is the ChainID of Base ChainIDBase ChainID = 30 + // ChainIDFileCoin is the ChainID of FileCoin + ChainIDFileCoin ChainID = 31 // ChainIDSei is the ChainID of Sei ChainIDSei ChainID = 32 // ChainIDRootstock is the ChainID of Rootstock @@ -528,6 +558,10 @@ const ( ChainIDBerachain ChainID = 39 // ChainIDSeiEVM is the ChainID of SeiEVM ChainIDSeiEVM ChainID = 40 + // ChainIDEclipse is the ChainID of Eclipse + ChainIDEclipse ChainID = 41 + // ChainIDBOB is the ChainID of BOB + ChainIDBOB ChainID = 42 // ChainIDSnaxchain is the ChainID of Snaxchain ChainIDSnaxchain ChainID = 43 // ChainIDUnichain is the ChainID of Unichain @@ -538,8 +572,16 @@ const ( ChainIDInk ChainID = 46 // ChainIDHyperEVM is the ChainID of HyperEVM ChainIDHyperEVM ChainID = 47 + // ChainIDMonad is the ChainID of Monad + ChainIDMonad ChainID = 48 + // ChainIDMovement is the ChainID of Movement + ChainIDMovement ChainID = 49 //ChainIDWormchain is the ChainID of Wormchain + + // Wormchain is in it's own range. ChainIDWormchain ChainID = 3104 + + // The IBC chains start at 4000. // ChainIDCosmoshub is the ChainID of Cosmoshub ChainIDCosmoshub ChainID = 4000 // ChainIDEvmos is the ChainID of Evmos @@ -561,6 +603,8 @@ const ( // ChainIDNoble is the ChainID of Noble ChainIDNoble ChainID = 4009 // ChainIDSepolia is the ChainID of Sepolia + + // The Testnet only chains start at 10000. ChainIDSepolia ChainID = 10002 // ChainIDArbitrumSepolia is the ChainID of Arbitrum on Sepolia ChainIDArbitrumSepolia ChainID = 10003 diff --git a/sdk/vaa/structs_test.go b/sdk/vaa/structs_test.go index fb5d4b58a5..261f39ce32 100644 --- a/sdk/vaa/structs_test.go +++ b/sdk/vaa/structs_test.go @@ -37,26 +37,27 @@ func TestChainIDFromString(t *testing.T) { {input: "avalanche", output: ChainIDAvalanche}, {input: "oasis", output: ChainIDOasis}, {input: "algorand", output: ChainIDAlgorand}, - {input: "aptos", output: ChainIDAptos}, - {input: "sui", output: ChainIDSui}, - {input: "near", output: ChainIDNear}, {input: "aurora", output: ChainIDAurora}, {input: "fantom", output: ChainIDFantom}, {input: "karura", output: ChainIDKarura}, {input: "acala", output: ChainIDAcala}, {input: "klaytn", output: ChainIDKlaytn}, {input: "celo", output: ChainIDCelo}, + {input: "near", output: ChainIDNear}, {input: "moonbeam", output: ChainIDMoonbeam}, {input: "terra2", output: ChainIDTerra2}, {input: "injective", output: ChainIDInjective}, {input: "osmosis", output: ChainIDOsmosis}, + {input: "sui", output: ChainIDSui}, + {input: "aptos", output: ChainIDAptos}, {input: "arbitrum", output: ChainIDArbitrum}, - {input: "pythnet", output: ChainIDPythNet}, {input: "optimism", output: ChainIDOptimism}, {input: "gnosis", output: ChainIDGnosis}, + {input: "pythnet", output: ChainIDPythNet}, {input: "xpla", output: ChainIDXpla}, {input: "btc", output: ChainIDBtc}, {input: "base", output: ChainIDBase}, + {input: "filecoin", output: ChainIDFileCoin}, {input: "sei", output: ChainIDSei}, {input: "rootstock", output: ChainIDRootstock}, {input: "scroll", output: ChainIDScroll}, @@ -65,12 +66,16 @@ func TestChainIDFromString(t *testing.T) { {input: "xlayer", output: ChainIDXLayer}, {input: "linea", output: ChainIDLinea}, {input: "berachain", output: ChainIDBerachain}, + {input: "eclipse", output: ChainIDEclipse}, + {input: "bob", output: ChainIDBOB}, + {input: "seievm", output: ChainIDSeiEVM}, {input: "snaxchain", output: ChainIDSnaxchain}, {input: "unichain", output: ChainIDUnichain}, {input: "worldchain", output: ChainIDWorldchain}, {input: "ink", output: ChainIDInk}, {input: "hyperevm", output: ChainIDHyperEVM}, - {input: "seievm", output: ChainIDSeiEVM}, + {input: "monad", output: ChainIDMonad}, + {input: "movement", output: ChainIDMovement}, {input: "wormchain", output: ChainIDWormchain}, {input: "cosmoshub", output: ChainIDCosmoshub}, {input: "evmos", output: ChainIDEvmos}, @@ -98,19 +103,19 @@ func TestChainIDFromString(t *testing.T) { {input: "Avalanche", output: ChainIDAvalanche}, {input: "Oasis", output: ChainIDOasis}, {input: "Algorand", output: ChainIDAlgorand}, - {input: "Aptos", output: ChainIDAptos}, - {input: "Sui", output: ChainIDSui}, - {input: "Near", output: ChainIDNear}, {input: "Aurora", output: ChainIDAurora}, {input: "Fantom", output: ChainIDFantom}, {input: "Karura", output: ChainIDKarura}, {input: "Acala", output: ChainIDAcala}, {input: "Klaytn", output: ChainIDKlaytn}, {input: "Celo", output: ChainIDCelo}, + {input: "Near", output: ChainIDNear}, {input: "Moonbeam", output: ChainIDMoonbeam}, {input: "Terra2", output: ChainIDTerra2}, {input: "Injective", output: ChainIDInjective}, {input: "Osmosis", output: ChainIDOsmosis}, + {input: "Sui", output: ChainIDSui}, + {input: "Aptos", output: ChainIDAptos}, {input: "Arbitrum", output: ChainIDArbitrum}, {input: "Optimism", output: ChainIDOptimism}, {input: "Gnosis", output: ChainIDGnosis}, @@ -118,6 +123,7 @@ func TestChainIDFromString(t *testing.T) { {input: "XPLA", output: ChainIDXpla}, {input: "BTC", output: ChainIDBtc}, {input: "Base", output: ChainIDBase}, + {input: "filecoin", output: ChainIDFileCoin}, {input: "Sei", output: ChainIDSei}, {input: "Rootstock", output: ChainIDRootstock}, {input: "Scroll", output: ChainIDScroll}, @@ -126,12 +132,16 @@ func TestChainIDFromString(t *testing.T) { {input: "XLayer", output: ChainIDXLayer}, {input: "Linea", output: ChainIDLinea}, {input: "Berachain", output: ChainIDBerachain}, + {input: "SeiEVM", output: ChainIDSeiEVM}, + {input: "Eclipse", output: ChainIDEclipse}, + {input: "BOB", output: ChainIDBOB}, {input: "Snaxchain", output: ChainIDSnaxchain}, {input: "Unichain", output: ChainIDUnichain}, {input: "Worldchain", output: ChainIDWorldchain}, {input: "Ink", output: ChainIDInk}, {input: "HyperEVM", output: ChainIDHyperEVM}, - {input: "SeiEVM", output: ChainIDSeiEVM}, + {input: "Monad", output: ChainIDMonad}, + {input: "Movement", output: ChainIDMovement}, {input: "Wormchain", output: ChainIDWormchain}, {input: "Cosmoshub", output: ChainIDCosmoshub}, {input: "Evmos", output: ChainIDEvmos}, @@ -307,6 +317,7 @@ func TestChainId_String(t *testing.T) { {input: 14, output: "celo"}, {input: 15, output: "near"}, {input: 16, output: "moonbeam"}, + // 17 (Neon) is obsolete. {input: 18, output: "terra2"}, {input: 19, output: "injective"}, {input: 20, output: "osmosis"}, @@ -316,9 +327,11 @@ func TestChainId_String(t *testing.T) { {input: 24, output: "optimism"}, {input: 25, output: "gnosis"}, {input: 26, output: "pythnet"}, + // NOTE: 27 belongs to a chain that was never deployed. {input: 28, output: "xpla"}, {input: 29, output: "btc"}, {input: 30, output: "base"}, + {input: 31, output: "filecoin"}, {input: 32, output: "sei"}, {input: 33, output: "rootstock"}, {input: 34, output: "scroll"}, @@ -328,11 +341,15 @@ func TestChainId_String(t *testing.T) { {input: 38, output: "linea"}, {input: 39, output: "berachain"}, {input: 40, output: "seievm"}, + {input: 41, output: "eclipse"}, + {input: 42, output: "bob"}, {input: 43, output: "snaxchain"}, {input: 44, output: "unichain"}, {input: 45, output: "worldchain"}, {input: 46, output: "ink"}, {input: 47, output: "hyperevm"}, + {input: 48, output: "monad"}, + {input: 49, output: "movement"}, {input: 3104, output: "wormchain"}, {input: 4000, output: "cosmoshub"}, {input: 4001, output: "evmos"}, @@ -341,6 +358,9 @@ func TestChainId_String(t *testing.T) { {input: 4004, output: "celestia"}, {input: 4005, output: "stargaze"}, {input: 4006, output: "seda"}, + {input: 4007, output: "dymension"}, + {input: 4008, output: "provenance"}, + {input: 4009, output: "noble"}, {input: 10002, output: "sepolia"}, {input: 10003, output: "arbitrum_sepolia"}, {input: 10004, output: "base_sepolia"}, diff --git a/whitepapers/0004_message_publishing.md b/whitepapers/0004_message_publishing.md index fe2a611084..9af319187d 100644 --- a/whitepapers/0004_message_publishing.md +++ b/whitepapers/0004_message_publishing.md @@ -102,6 +102,8 @@ Fee uint256 TransferFees: +> **NOTE:** The Wormhole CosmWasm Core Contract does not conform to this spec. The `Amount` and `To` fields are in reverse order. (Ref: [CosmWasm Core Contract](../cosmwasm/contracts/wormhole/src/state.rs#L386-L397)) + ``` // Core Wormhole Module Module [32]byte = "Core" diff --git a/wormchain/Makefile b/wormchain/Makefile index c54c6eadf1..7fbdb3a6be 100644 --- a/wormchain/Makefile +++ b/wormchain/Makefile @@ -109,7 +109,10 @@ ictest-wormchain: rm-testcache ictest-ibc-receiver: rm-testcache cd interchaintest && go test -race -v -run ^TestIbcReceiver ./... +ictest-cw-wormhole: rm-testcache + cd interchaintest && go test -race -v -run ^TestCWWormhole ./... + ictest-validator-hotswap: rm-testcache cd interchaintest && go test -race -v -run ^TestValidatorHotswap$$ ./... -.PHONY: ictest-cancel-upgrade ictest-malformed-payload ictest-upgrade-failure ictest-upgrade ictest-wormchain ictest-ibc-receiver ictest-validator-hotswap \ No newline at end of file +.PHONY: ictest-cancel-upgrade ictest-malformed-payload ictest-upgrade-failure ictest-upgrade ictest-wormchain ictest-ibc-receiver ictest-cw-wormhole ictest-validator-hotswap diff --git a/wormchain/interchaintest/contracts/cw_wormhole.wasm b/wormchain/interchaintest/contracts/cw_wormhole.wasm new file mode 100644 index 0000000000..b852a957a3 Binary files /dev/null and b/wormchain/interchaintest/contracts/cw_wormhole.wasm differ diff --git a/wormchain/interchaintest/cw_wormhole_test.go b/wormchain/interchaintest/cw_wormhole_test.go new file mode 100644 index 0000000000..bd59557838 --- /dev/null +++ b/wormchain/interchaintest/cw_wormhole_test.go @@ -0,0 +1,492 @@ +package ictest + +import ( + "bytes" + "context" + "encoding/base64" + "encoding/hex" + "encoding/json" + "testing" + + "github.com/docker/docker/client" + "github.com/strangelove-ventures/interchaintest/v4" + "github.com/strangelove-ventures/interchaintest/v4/chain/cosmos" + "github.com/strangelove-ventures/interchaintest/v4/ibc" + "github.com/strangelove-ventures/interchaintest/v4/testutil" + "go.uber.org/zap/zaptest" + + "github.com/stretchr/testify/require" + + "github.com/wormhole-foundation/wormchain/interchaintest/guardians" + "github.com/wormhole-foundation/wormchain/interchaintest/helpers" + "github.com/wormhole-foundation/wormchain/interchaintest/helpers/cw_wormhole" + "github.com/wormhole-foundation/wormhole/sdk/vaa" +) + +func createSingleNodeCluster(t *testing.T, wormchainVersion string, guardians guardians.ValSet) ibc.Chain { + numWormchainVals := len(guardians.Vals) + numFullNodes := 0 + + wormchainConfig.Images[0].Version = wormchainVersion + wormchainConfig.ModifyGenesis = ModifyGenesis(votingPeriod, maxDepositPeriod, guardians, numWormchainVals, true) + + cf := interchaintest.NewBuiltinChainFactory(zaptest.NewLogger(t), []*interchaintest.ChainSpec{ + { + ChainName: "wormchain", + ChainConfig: wormchainConfig, + NumValidators: &numWormchainVals, + NumFullNodes: &numFullNodes, + }, + }) + + // Get chains from the chain factory + chains, err := cf.Chains(t.Name()) + require.NoError(t, err) + + return chains[0] +} + +func buildSingleNodeInterchain(t *testing.T, chain ibc.Chain) (context.Context, *client.Client) { + ic := interchaintest.NewInterchain() + ic.AddChain(chain) + + ctx := context.Background() + client, network := interchaintest.DockerSetup(t) + + err := ic.Build(ctx, nil, interchaintest.InterchainBuildOptions{ + TestName: t.Name(), + Client: client, + NetworkID: network, + SkipPathCreation: true, + }) + require.NoError(t, err) + + t.Cleanup(func() { + _ = ic.Close() + }) + + return ctx, client +} + +// TestCWWormholeQueries tests the query functions of the cw_wormhole contract +func TestCWWormholeQueries(t *testing.T) { + // Base setup + numVals := 1 + guardians := guardians.CreateValSet(t, numVals) + + chain := createSingleNodeCluster(t, "v2.24.2", *guardians) + ctx, _ := buildSingleNodeInterchain(t, chain) + + wormchain := chain.(*cosmos.CosmosChain) + + // Instantiate the cw_wormhole contract + coreInstantiateMsg := helpers.CoreContractInstantiateMsg(t, wormchainConfig, vaa.ChainIDWormchain, guardians) + wormchainCoreContractInfo := helpers.StoreAndInstantiateWormholeContract(t, ctx, wormchain, "faucet", "./contracts/cw_wormhole.wasm", "wormhole_core", coreInstantiateMsg, guardians) + contractAddr := wormchainCoreContractInfo.Address + + // Query the contract to check that the guardian set is correct + var guardianSetResp cw_wormhole.GuardianSetQueryResponse + err := wormchain.QueryContract(ctx, contractAddr, cw_wormhole.QueryMsg{ + GuardianSetInfo: &cw_wormhole.QueryMsg_GuardianSetInfo{}, + }, &guardianSetResp) + require.NoError(t, err) + require.Equal(t, numVals, len(guardianSetResp.Data.Addresses), "guardian set should have the correct number of guardians") + // Check that all the guardians from the query are the ones in the running valset + for _, val := range guardians.Vals { + found := false + for _, guardian := range guardianSetResp.Data.Addresses { + decoded, err := base64.StdEncoding.DecodeString(string(guardian.Bytes)) + require.NoError(t, err) + guardianDecodedBytes := []byte(decoded) + if bytes.Equal(val.Addr, guardianDecodedBytes) { + found = true + break + } + } + require.True(t, found, "guardian not found in guardian set") + } + + // Check that the core contract fee is set to 0uworm + var stateResp cw_wormhole.GetStateQueryResponse + err = wormchain.QueryContract(ctx, contractAddr, cw_wormhole.QueryMsg{ + GetState: &cw_wormhole.QueryMsg_GetState{}, + }, &stateResp) + require.NoError(t, err) + require.Equal(t, "uworm", stateResp.Data.Fee.Denom, "core contract fee should be in uworm") + require.Equal(t, cw_wormhole.Uint128("0"), stateResp.Data.Fee.Amount, "core contract fee should be 0") + + // Check that hex addresse are able to be queried + var hexAddressResp cw_wormhole.QueryAddressHexQueryResponse + err = wormchain.QueryContract(ctx, contractAddr, cw_wormhole.QueryMsg{ + QueryAddressHex: &cw_wormhole.QueryMsg_QueryAddressHex{ + Address: "wormhole14hj2tavq8fpesdwxxcu44rty3hh90vhujrvcmstl4zr3txmfvw9srrg465", + }, + }, &hexAddressResp) + require.NoError(t, err) + require.IsType(t, "", hexAddressResp.Data.Hex, "hex address should be a string") + + // Check that the core contract can properly verify a VAA + guardianSetIndex := helpers.QueryConsensusGuardianSetIndex(t, wormchain, ctx) + vaa := helpers.GenerateGovernanceVaa(uint32(guardianSetIndex), guardians, []byte("test")) + vaaBz, err := vaa.Marshal() + require.NoError(t, err) + encodedVaa := base64.StdEncoding.EncodeToString(vaaBz) + vaaBinary := cw_wormhole.Binary(encodedVaa) + + currentWormchainBlock, err := wormchain.Height(ctx) + require.NoError(t, err) + + var parsedVaaResponse cw_wormhole.VerifyVAAQueryResponse + err = wormchain.QueryContract(ctx, contractAddr, cw_wormhole.QueryMsg{ + VerifyVaa: &cw_wormhole.QueryMsg_VerifyVAA{ + BlockTime: int(currentWormchainBlock), + Vaa: vaaBinary, + }, + }, &parsedVaaResponse) + require.NoError(t, err) + require.NotNil(t, parsedVaaResponse.Data, "VAA should be verified") + require.Equal(t, "test", string(parsedVaaResponse.Data.Payload), "VAA payload should be what we passed in") +} + +// TestCWWormholePostMessage tests the PostMessage function of the cw_wormhole contract +func TestCWWormholePostMessage(t *testing.T) { + numVals := 1 + guardians := guardians.CreateValSet(t, numVals) + chain := createSingleNodeCluster(t, "v2.24.2", *guardians) + ctx, _ := buildSingleNodeInterchain(t, chain) + wormchain := chain.(*cosmos.CosmosChain) + + // Instantiate contract + coreInstantiateMsg := helpers.CoreContractInstantiateMsg(t, wormchainConfig, vaa.ChainIDWormchain, guardians) + contractInfo := helpers.StoreAndInstantiateWormholeContract(t, ctx, wormchain, "faucet", "./contracts/cw_wormhole.wasm", "wormhole_core", coreInstantiateMsg, guardians) + contractAddr := contractInfo.Address + + // Create message and encode to base64 + message := []byte("test message") + messageBase64 := base64.StdEncoding.EncodeToString(message) + nonce := 1 + + executeMsg, err := json.Marshal(cw_wormhole.ExecuteMsg{ + PostMessage: &cw_wormhole.ExecuteMsg_PostMessage{ + Message: cw_wormhole.Binary(messageBase64), + Nonce: nonce, + }, + }) + require.NoError(t, err) + + // Execute contract + txHash, err := wormchain.ExecuteContract(ctx, "faucet", contractAddr, string(executeMsg)) + require.NoError(t, err) + + // Wait 2 blocks + err = testutil.WaitForBlocks(ctx, 2, wormchain) + require.NoError(t, err) + + // Query and parse the response + txResult, _, err := wormchain.Validators[0].ExecQuery(ctx, "tx", txHash) + require.NoError(t, err) + + var txResponse cw_wormhole.TxResponse + err = json.Unmarshal(txResult, &txResponse) + require.NoError(t, err) + + // Verify event attributes + cw_wormhole.VerifyEventAttributes(t, &txResponse, map[string]string{ + "_contract_address": contractAddr, + "message.message": hex.EncodeToString(message), + "message.nonce": "1", + "message.sequence": "0", + }) +} + +// TestCWWormholeUpdateGuardianSet tests the UpdateGuardianSet function of the cw_wormhole contract +func TestCWWormholeUpdateGuardianSet(t *testing.T) { + // Setup chain and contract + numVals := 1 + oldGuardians := guardians.CreateValSet(t, numVals) + chain := createSingleNodeCluster(t, "v2.24.2", *oldGuardians) + ctx, _ := buildSingleNodeInterchain(t, chain) + wormchain := chain.(*cosmos.CosmosChain) + + // Deploy contract + coreInstantiateMsg := helpers.CoreContractInstantiateMsg(t, wormchainConfig, vaa.ChainIDWormchain, oldGuardians) + contractInfo := helpers.StoreAndInstantiateWormholeContract(t, ctx, wormchain, "faucet", "./contracts/cw_wormhole.wasm", "wormhole_core", coreInstantiateMsg, oldGuardians) + contractAddr := contractInfo.Address + + // Get initial guardian set index + initialIndex := int(helpers.QueryConsensusGuardianSetIndex(t, wormchain, ctx)) + signingGuardians := guardians.CreateValSet(t, numVals+1) + + t.Run("successful update", func(t *testing.T) { + newGuardians := signingGuardians + err := cw_wormhole.SubmitGuardianSetUpdate(t, ctx, wormchain, contractAddr, newGuardians, uint32(initialIndex+1), oldGuardians) + require.NoError(t, err) + cw_wormhole.VerifyGuardianSet(t, ctx, wormchain, contractAddr, newGuardians, initialIndex+1) + }) + + t.Run("invalid guardian set index", func(t *testing.T) { + // Try to update with non-sequential index + newGuardians := guardians.CreateValSet(t, numVals+1) + err := cw_wormhole.SubmitGuardianSetUpdate(t, ctx, wormchain, contractAddr, newGuardians, uint32(initialIndex+3), signingGuardians) + require.Error(t, err) + + // Try to update with same index + err = cw_wormhole.SubmitGuardianSetUpdate(t, ctx, wormchain, contractAddr, newGuardians, uint32(initialIndex), signingGuardians) + require.Error(t, err) + }) + + t.Run("empty guardian set", func(t *testing.T) { + emptyGuardians := guardians.CreateValSet(t, 0) + err := cw_wormhole.SubmitGuardianSetUpdate(t, ctx, wormchain, contractAddr, emptyGuardians, uint32(initialIndex+1), signingGuardians) + require.Error(t, err) + require.Contains(t, err.Error(), "GuardianSignatureError") + }) + + t.Run("duplicate guardians", func(t *testing.T) { + // Create guardian set with duplicate addresses + dupGuardians := guardians.CreateValSet(t, 1) + dupGuardians.Vals = append(dupGuardians.Vals, dupGuardians.Vals[0]) + dupGuardians.Total = 2 + + err := cw_wormhole.SubmitGuardianSetUpdate(t, ctx, wormchain, contractAddr, dupGuardians, uint32(initialIndex+1), signingGuardians) + require.Error(t, err) + require.Contains(t, err.Error(), "GuardianSignatureError") + }) + + t.Run("wrong signing guardian set", func(t *testing.T) { + // Create new guardians and try to use them to sign the update + wrongSigners := guardians.CreateValSet(t, numVals) + newGuardians := guardians.CreateValSet(t, numVals+1) + + err := cw_wormhole.SubmitGuardianSetUpdate(t, ctx, wormchain, contractAddr, newGuardians, uint32(initialIndex+1), wrongSigners) + require.Error(t, err) + require.Contains(t, err.Error(), "governance VAAs must be signed by the current guardian set") + }) + + t.Run("insufficient signatures", func(t *testing.T) { + // Create a guardian set with only one signer (below quorum) + insufficientSigners := guardians.CreateValSet(t, 1) + newGuardians := guardians.CreateValSet(t, numVals+1) + + err := cw_wormhole.SubmitGuardianSetUpdate(t, ctx, wormchain, contractAddr, newGuardians, uint32(initialIndex+1), insufficientSigners) + require.Error(t, err) + require.Contains(t, err.Error(), "governance VAAs must be signed by the current guardian set") + + // too many signatures + insufficientSigners = guardians.CreateValSet(t, numVals+2) + err = cw_wormhole.SubmitGuardianSetUpdate(t, ctx, wormchain, contractAddr, newGuardians, uint32(initialIndex+1), insufficientSigners) + require.Error(t, err) + require.Contains(t, err.Error(), "GuardianSignatureError") + }) + + // Verify signing validators did not change + cw_wormhole.VerifyGuardianSet(t, ctx, wormchain, contractAddr, signingGuardians, initialIndex+1) +} + +// TestCWWormholeContractUpgrade tests the SubmitContractUpgrade function of the cw_wormhole contract +func TestCWWormholeContractUpgrade(t *testing.T) { + // Setup chain and contract + numVals := 1 + guardians := guardians.CreateValSet(t, numVals) + chains := CreateChains(t, "v2.24.2", *guardians) + ctx, _, _, _ := BuildInterchain(t, chains) + + // Chains + wormchain := chains[0].(*cosmos.CosmosChain) + + // Deploy contract to wormhole + coreInstantiateMsg := helpers.CoreContractInstantiateMsg(t, wormchainConfig, vaa.ChainIDWormchain, guardians) + contractInfo := helpers.StoreAndInstantiateWormholeContract(t, ctx, wormchain, "faucet", "./contracts/cw_wormhole.wasm", "wormhole_core", coreInstantiateMsg, guardians) + wormContractAddr := contractInfo.Address + + // Store a new version of the contract to upgrade to + wormNewCodeId := helpers.StoreContract(t, ctx, wormchain, "faucet", "./contracts/cw_wormhole.wasm", guardians) + + t.Run("successful upgrade", func(t *testing.T) { + err := cw_wormhole.SubmitContractUpgrade(t, ctx, guardians, wormchain, wormContractAddr, wormNewCodeId) + require.NoError(t, err) + + contractInfo = helpers.QueryContractInfo(t, wormchain, ctx, wormContractAddr) + require.NoError(t, err) + require.Equal(t, wormNewCodeId, contractInfo.ContractInfo.CodeID) + }) + + t.Run("invalid code id", func(t *testing.T) { + err := cw_wormhole.SubmitContractUpgrade(t, ctx, guardians, wormchain, wormContractAddr, "999999") + require.Error(t, err) + }) + + // VAA payload to upgrade contract is not allowed on Wormchain, must use the wormhole module + t.Run("upgrade wormhole contract with vaa: fails - use x/wormhole", func(t *testing.T) { + // Submit VAA + err := cw_wormhole.SubmitContractUpgradeWithVaa(t, ctx, guardians, 0, vaa.ChainIDWormchain, wormchain, wormContractAddr, wormNewCodeId, "faucet") + require.Error(t, err) + require.Contains(t, err.Error(), "must use x/wormhole") + }) + + // Test osmo chain + osmo := chains[2].(*cosmos.CosmosChain) + users := interchaintest.GetAndFundTestUsers(t, ctx, t.Name(), 10_000_000_000, osmo) + osmoUser := users[0] + + // Deploy contract to osmo + osmoCodeId, err := osmo.StoreContract(ctx, osmoUser.KeyName, "./contracts/cw_wormhole.wasm") + require.NoError(t, err) + + instantiateMsg := helpers.CoreContractInstantiateMsg(t, wormchainConfig, vaa.ChainIDOsmosis, guardians) + + osmoContractAddr, err := osmo.InstantiateContract(ctx, osmoUser.KeyName, osmoCodeId, instantiateMsg, false, "--admin", osmoUser.Bech32Address("osmo")) + require.NoError(t, err) + + // Update admin to contract addr + _, err = osmo.GetFullNode().ExecTx(ctx, osmoUser.KeyName, "wasm", "set-contract-admin", osmoContractAddr, osmoContractAddr) + require.NoError(t, err) + err = testutil.WaitForBlocks(ctx, 2, osmo) + require.NoError(t, err) + + // Verify new admin is contract + contractInfo = helpers.QueryContractInfo(t, osmo, ctx, osmoContractAddr) + require.NoError(t, err) + require.Equal(t, osmoContractAddr, contractInfo.ContractInfo.Admin) + + // Store a new version of the contract to upgrade to + osmoNewCodeId, err := osmo.StoreContract(ctx, osmoUser.KeyName, "./contracts/cw_wormhole.wasm") + require.NoError(t, err) + + t.Run("migrate osmosis via payload", func(t *testing.T) { + // Submit VAA + err := cw_wormhole.SubmitContractUpgradeWithVaa(t, ctx, guardians, 0, vaa.ChainIDOsmosis, osmo, osmoContractAddr, osmoNewCodeId, osmoUser.KeyName) + require.NoError(t, err) + + contractInfo := helpers.QueryContractInfo(t, osmo, ctx, osmoContractAddr) + require.NoError(t, err) + require.Equal(t, osmoNewCodeId, contractInfo.ContractInfo.CodeID) + }) + +} + +// TestCWWormholeSetFee tests the SetFee function of the cw_wormhole contract +func TestCWWormholeSetFee(t *testing.T) { + // Setup chain and contract + numVals := 1 + guardians := guardians.CreateValSet(t, numVals) + chain := createSingleNodeCluster(t, "v2.24.2", *guardians) + ctx, _ := buildSingleNodeInterchain(t, chain) + wormchain := chain.(*cosmos.CosmosChain) + + // Deploy contract + coreInstantiateMsg := helpers.CoreContractInstantiateMsg(t, wormchainConfig, vaa.ChainIDWormchain, guardians) + contractInfo := helpers.StoreAndInstantiateWormholeContract(t, ctx, wormchain, "faucet", "./contracts/cw_wormhole.wasm", "wormhole_core", coreInstantiateMsg, guardians) + contractAddr := contractInfo.Address + + // wrapper around helper function for cleaner test code + submitFeeUpdate := func(amount string, replay bool) (*cw_wormhole.TxResponse, error) { + return cw_wormhole.SubmitFeeUpdate(t, ctx, guardians, wormchain, contractAddr, amount, replay) + } + + t.Run("successful fee update", func(t *testing.T) { + txResponse, err := submitFeeUpdate("1000000", true) // Set fee to 1 WORM (1000000 uworm) + require.NoError(t, err) + cw_wormhole.VerifyEventAttributes(t, txResponse, map[string]string{ + "action": "fee_change", + "new_fee.amount": "1000000", + "new_fee.denom": "uworm", + }) + cw_wormhole.VerifyFee(t, ctx, wormchain, contractAddr, "1000000") + + // post a message with fee under the new fee + err = cw_wormhole.PostMessageWithFee(t, ctx, wormchain, contractAddr, "message1", 999999) + require.Error(t, err) + require.Contains(t, err.Error(), "FeeTooLow") + + // post a message with fee equal to the new fee + err = cw_wormhole.PostMessageWithFee(t, ctx, wormchain, contractAddr, "message2", 1000000) + require.NoError(t, err) + + // post a message with fee above the new fee + err = cw_wormhole.PostMessageWithFee(t, ctx, wormchain, contractAddr, "message3", 1000001) + require.NoError(t, err) + }) + + t.Run("zero fee", func(t *testing.T) { + txResponse, err := submitFeeUpdate("0", false) + require.NoError(t, err) + cw_wormhole.VerifyEventAttributes(t, txResponse, map[string]string{ + "action": "fee_change", + "new_fee.amount": "0", + "new_fee.denom": "uworm", + }) + cw_wormhole.VerifyFee(t, ctx, wormchain, contractAddr, "0") + }) + + t.Run("very large fee", func(t *testing.T) { + txResponse, err := submitFeeUpdate("1000000000000", false) // 1M WORM + require.NoError(t, err) + cw_wormhole.VerifyEventAttributes(t, txResponse, map[string]string{ + "action": "fee_change", + "new_fee.amount": "1000000000000", + "new_fee.denom": "uworm", + }) + cw_wormhole.VerifyFee(t, ctx, wormchain, contractAddr, "1000000000000") + }) +} + +// TestCWWormholeTransferFees tests transferring the accumulated fees to the core contract +func TestCWWormholeTransferFees(t *testing.T) { + // Setup chain and contract + numVals := 1 + guardians := guardians.CreateValSet(t, numVals) + chain := createSingleNodeCluster(t, "v2.24.2", *guardians) + ctx, _ := buildSingleNodeInterchain(t, chain) + wormchain := chain.(*cosmos.CosmosChain) + + // Deploy contract + coreInstantiateMsg := helpers.CoreContractInstantiateMsg(t, wormchainConfig, vaa.ChainIDWormchain, guardians) + contractInfo := helpers.StoreAndInstantiateWormholeContract(t, ctx, wormchain, "faucet", "./contracts/cw_wormhole.wasm", "wormhole_core", coreInstantiateMsg, guardians) + contractAddr := contractInfo.Address + + users := interchaintest.GetAndFundTestUsers(t, ctx, t.Name(), 1, wormchain) + user := users[0] + userAddr := user.Bech32Address("wormhole") + + t.Run("successful fee transfer", func(t *testing.T) { + // Set fee to 1000000 uworm + _, err := cw_wormhole.SubmitFeeUpdate(t, ctx, guardians, wormchain, contractAddr, "1000000", false) + require.NoError(t, err) + + // Post some messages with fees to build up balance + err = cw_wormhole.PostMessageWithFee(t, ctx, wormchain, contractAddr, "message1", 1000000) + require.NoError(t, err) + err = cw_wormhole.PostMessageWithFee(t, ctx, wormchain, contractAddr, "message2", 1000000) + require.NoError(t, err) + + // Get recipient's initial balance + initialBalance, err := cw_wormhole.GetUwormBalance(t, ctx, wormchain, userAddr) + require.NoError(t, err) + + // Transfer 1500000 uworm + _, err = cw_wormhole.SubmitTransferFee(t, ctx, guardians, wormchain, contractAddr, []byte(user.Address), "1500000", true) + require.NoError(t, err) + + // Verify successful transfer + finalBalance, err := cw_wormhole.GetUwormBalance(t, ctx, wormchain, userAddr) + require.NoError(t, err) + require.Equal(t, initialBalance+1500000, finalBalance) + }) + + t.Run("transfer more than balance", func(t *testing.T) { + _, err := cw_wormhole.SubmitTransferFee(t, ctx, guardians, wormchain, contractAddr, []byte(user.Address), "10000000000", false) + require.Error(t, err) + require.Contains(t, err.Error(), "insufficient funds") + }) + + t.Run("invalid recipient", func(t *testing.T) { + _, err := cw_wormhole.SubmitTransferFee(t, ctx, guardians, wormchain, contractAddr, []byte("invalid"), "1000000", false) + require.Error(t, err) + }) + + t.Run("zero amount - invalid coins", func(t *testing.T) { + _, err := cw_wormhole.SubmitTransferFee(t, ctx, guardians, wormchain, contractAddr, []byte(user.Address), "0", false) + require.Error(t, err) + }) +} diff --git a/wormchain/interchaintest/helpers/cw_wormhole/cw_wormhole.go b/wormchain/interchaintest/helpers/cw_wormhole/cw_wormhole.go new file mode 100644 index 0000000000..b8d7d0b849 --- /dev/null +++ b/wormchain/interchaintest/helpers/cw_wormhole/cw_wormhole.go @@ -0,0 +1,110 @@ +/* Code generated by github.com/srdtrk/go-codegen, DO NOT EDIT. */ +package cw_wormhole + +// The instantiation parameters of the core bridge contract. See [`crate::state::ConfigInfo`] for more details on what these fields mean. +type InstantiateMsg struct { + FeeDenom string `json:"fee_denom"` + GovAddress Binary `json:"gov_address"` + GovChain int `json:"gov_chain"` + GuardianSetExpirity int `json:"guardian_set_expirity"` + // Guardian set to initialise the contract with. + InitialGuardianSet GuardianSetInfo `json:"initial_guardian_set"` + ChainId int `json:"chain_id"` +} + +type ExecuteMsg struct { + SubmitVaa *ExecuteMsg_SubmitVAA `json:"submit_v_a_a,omitempty"` + PostMessage *ExecuteMsg_PostMessage `json:"post_message,omitempty"` +} + +type QueryMsg struct { + GuardianSetInfo *QueryMsg_GuardianSetInfo `json:"guardian_set_info,omitempty"` + VerifyVaa *QueryMsg_VerifyVAA `json:"verify_v_a_a,omitempty"` + GetState *QueryMsg_GetState `json:"get_state,omitempty"` + QueryAddressHex *QueryMsg_QueryAddressHex `json:"query_address_hex,omitempty"` +} + +type ExecuteMsg_PostMessage struct { + Message Binary `json:"message"` + Nonce int `json:"nonce"` +} + +type GuardianSetInfoResponse struct { + Addresses []GuardianAddress `json:"addresses"` + GuardianSetIndex int `json:"guardian_set_index"` +} + +/* +A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq. + +# Examples + +Use `from` to create instances of this and `u128` to get the value out: + +``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123); + +let b = Uint128::from(42u64); assert_eq!(b.u128(), 42); + +let c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ``` +*/ +type Uint128 string + +type GetStateResponse struct { + Fee Coin `json:"fee"` +} + +type GuardianAddress struct { + Bytes Binary `json:"bytes"` +} + +type QueryMsg_GetState struct{} + +type QueryMsg_QueryAddressHex struct { + Address string `json:"address"` +} + +/* +Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline. + +This is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also . +*/ +type Binary string + +type ExecuteMsg_SubmitVAA struct { + Vaa Binary `json:"vaa"` +} + +type QueryMsg_VerifyVAA struct { + BlockTime int `json:"block_time"` + Vaa Binary `json:"vaa"` +} + +type ParsedVAA struct { + ConsistencyLevel int `json:"consistency_level"` + EmitterAddress []int `json:"emitter_address"` + Hash []int `json:"hash"` + LenSigners int `json:"len_signers"` + Timestamp int `json:"timestamp"` + Version int `json:"version"` + EmitterChain int `json:"emitter_chain"` + GuardianSetIndex int `json:"guardian_set_index"` + Nonce int `json:"nonce"` + Payload []byte `json:"payload"` + Sequence int `json:"sequence"` +} + +type Coin struct { + Amount Uint128 `json:"amount"` + Denom string `json:"denom"` +} + +type GuardianSetInfo struct { + Addresses []GuardianAddress `json:"addresses"` + ExpirationTime int `json:"expiration_time"` +} + +type GetAddressHexResponse struct { + Hex string `json:"hex"` +} + +type QueryMsg_GuardianSetInfo struct{} diff --git a/wormchain/interchaintest/helpers/cw_wormhole/helpers.go b/wormchain/interchaintest/helpers/cw_wormhole/helpers.go new file mode 100644 index 0000000000..6468094bc2 --- /dev/null +++ b/wormchain/interchaintest/helpers/cw_wormhole/helpers.go @@ -0,0 +1,408 @@ +package cw_wormhole + +import ( + "bytes" + "context" + "encoding/base64" + "encoding/binary" + "encoding/json" + "math/big" + "testing" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/ethereum/go-ethereum/common" + "github.com/strangelove-ventures/interchaintest/v4/chain/cosmos" + "github.com/strangelove-ventures/interchaintest/v4/testutil" + + "github.com/stretchr/testify/require" + + "github.com/wormhole-foundation/wormchain/interchaintest/guardians" + "github.com/wormhole-foundation/wormchain/interchaintest/helpers" + "github.com/wormhole-foundation/wormhole/sdk/vaa" +) + +type GuardianSetQueryResponse struct { + Data GuardianSetInfoResponse `json:"data"` +} + +type VerifyVAAQueryResponse struct { + Data ParsedVAA `json:"data"` +} + +type GetStateQueryResponse struct { + Data GetStateResponse `json:"data"` +} + +type QueryAddressHexQueryResponse struct { + Data GetAddressHexResponse `json:"data"` +} + +// Custom response type to handle string numbers +type TxResponse struct { + Code uint32 `json:"code"` + Logs sdk.ABCIMessageLogs `json:"logs"` +} + +// SubmitGuardianSetUpdate submits a VAA to update the guardian set +func SubmitGuardianSetUpdate( + t *testing.T, + ctx context.Context, + wormchain *cosmos.CosmosChain, + contractAddr string, + newGuardians *guardians.ValSet, + newIndex uint32, + signingGuardians *guardians.ValSet, +) error { + // Create guardian set update payload + guardianKeys := make([]common.Address, len(newGuardians.Vals)) + for i, g := range newGuardians.Vals { + copy(guardianKeys[i][:], g.Addr) + } + + updateMsg := vaa.BodyGuardianSetUpdate{ + Keys: guardianKeys, + NewIndex: newIndex, + } + + payload, err := updateMsg.Serialize() + require.NoError(t, err) + + // Generate and sign the governance VAA using the signing guardian set + guardianSetIndex := helpers.QueryConsensusGuardianSetIndex(t, wormchain, ctx) + govVaa := helpers.GenerateGovernanceVaa(uint32(guardianSetIndex), signingGuardians, payload) + vaaBz, err := govVaa.Marshal() + require.NoError(t, err) + + encodedVaa := base64.StdEncoding.EncodeToString(vaaBz) + executeVAAPayload, err := json.Marshal(ExecuteMsg{ + SubmitVaa: &ExecuteMsg_SubmitVAA{ + Vaa: Binary(encodedVaa), + }, + }) + require.NoError(t, err) + + // Submit VAA + _, err = wormchain.ExecuteContract(ctx, "faucet", contractAddr, string(executeVAAPayload)) + if err != nil { + return err + } + + // Wait for transaction + return testutil.WaitForBlocks(ctx, 2, wormchain) +} + +// VerifyGuardianSet verifies the guardian set in the contract state +func VerifyGuardianSet( + t *testing.T, + ctx context.Context, + wormchain *cosmos.CosmosChain, + contractAddr string, + expectedGuardians *guardians.ValSet, + expectedIndex int, +) { + var guardianSetResp GuardianSetQueryResponse + err := wormchain.QueryContract(ctx, contractAddr, QueryMsg{ + GuardianSetInfo: &QueryMsg_GuardianSetInfo{}, + }, &guardianSetResp) + require.NoError(t, err) + + require.Equal(t, len(expectedGuardians.Vals), len(guardianSetResp.Data.Addresses), "unexpected number of guardians") + require.Equal(t, expectedIndex, guardianSetResp.Data.GuardianSetIndex, "unexpected guardian set index") + + for i, val := range expectedGuardians.Vals { + found := false + for _, guardian := range guardianSetResp.Data.Addresses { + decoded, err := base64.StdEncoding.DecodeString(string(guardian.Bytes)) + require.NoError(t, err) + guardianDecodedBytes := []byte(decoded) + if bytes.Equal(val.Addr, guardianDecodedBytes) { + found = true + break + } + } + require.True(t, found, "guardian %d not found in guardian set", i) + } +} + +// SubmitContractUpgrade submits a VAA to upgrade the contract code +func SubmitContractUpgrade( + t *testing.T, + ctx context.Context, + guardians *guardians.ValSet, + wormchain *cosmos.CosmosChain, + contractAddr string, + newCodeId string, +) error { + if err := helpers.MigrateContract(t, ctx, wormchain, "faucet", contractAddr, newCodeId, "{}", guardians); err != nil { + return err + } + + // Wait for transaction + return testutil.WaitForBlocks(ctx, 2, wormchain) +} + +func SubmitContractUpgradeWithVaa( + t *testing.T, + ctx context.Context, + guardians *guardians.ValSet, + guardianSetIndex uint64, + vaaChainId vaa.ChainID, + chain *cosmos.CosmosChain, + contractAddr string, + newCodeId string, + keyName string, +) error { + // convert newCodeId to Uint256 + var newCodeIdBz [32]byte + newCodeIdInt := new(big.Int) + newCodeIdInt.SetString(newCodeId, 10) + newCodeIdInt.FillBytes(newCodeIdBz[:]) + + // Create contract upgrade payload + updateMsg := vaa.BodyContractUpgrade{ + ChainID: vaaChainId, + NewContract: vaa.Address(newCodeIdBz), + } + + payload, err := updateMsg.Serialize() + require.NoError(t, err) + + // Generate and sign the governance VAA + govVaa := helpers.GenerateGovernanceVaa(uint32(guardianSetIndex), guardians, payload) + vaaBz, err := govVaa.Marshal() + require.NoError(t, err) + + encodedVaa := base64.StdEncoding.EncodeToString(vaaBz) + executeVAAPayload, err := json.Marshal(ExecuteMsg{ + SubmitVaa: &ExecuteMsg_SubmitVAA{ + Vaa: Binary(encodedVaa), + }, + }) + require.NoError(t, err) + + // Submit VAA + _, err = chain.ExecuteContract(ctx, keyName, contractAddr, string(executeVAAPayload)) + return err +} + +// SubmitFeeUpdate submits a VAA to update the fee amount +func SubmitFeeUpdate( + t *testing.T, + ctx context.Context, + guardians *guardians.ValSet, + wormchain *cosmos.CosmosChain, + contractAddr string, + amount string, + replay bool, +) (*TxResponse, error) { + // Get current guardian set index + guardianSetIndex := helpers.QueryConsensusGuardianSetIndex(t, wormchain, ctx) + + // Create a fixed 32-byte array for the fee amount + var amountBytes [32]byte + amountInt := new(big.Int) + amountInt.SetString(amount, 10) + amountInt.FillBytes(amountBytes[:]) + + // Create governance VAA payload + // [32 bytes] Core Module + // [1 byte] Action (3 for set fee) + // [2 bytes] ChainID (0 for universal) + // [32 bytes] Amount + buf := new(bytes.Buffer) + buf.Write(vaa.CoreModule) + vaa.MustWrite(buf, binary.BigEndian, vaa.ActionCoreSetMessageFee) + vaa.MustWrite(buf, binary.BigEndian, uint16(0)) // ChainID 0 for universal + buf.Write(amountBytes[:]) + + // Generate and sign governance VAA + govVaa := helpers.GenerateGovernanceVaa(uint32(guardianSetIndex), guardians, buf.Bytes()) + vaaBz, err := govVaa.Marshal() + require.NoError(t, err) + + // Rest of the function remains the same... + encodedVaa := base64.StdEncoding.EncodeToString(vaaBz) + executeVAAPayload, err := json.Marshal(ExecuteMsg{ + SubmitVaa: &ExecuteMsg_SubmitVAA{ + Vaa: Binary(encodedVaa), + }, + }) + require.NoError(t, err) + + // Submit VAA + txHash, err := wormchain.ExecuteContract(ctx, "faucet", contractAddr, string(executeVAAPayload)) + if err != nil { + return nil, err + } + + // Wait for transaction + err = testutil.WaitForBlocks(ctx, 2, wormchain) + require.NoError(t, err) + + // Replay the transaction + if replay { + _, err = wormchain.ExecuteContract(ctx, "faucet", contractAddr, string(executeVAAPayload)) + require.Error(t, err) + require.Contains(t, err.Error(), "VaaAlreadyExecuted") + } + + // Query transaction result + txResult, _, err := wormchain.Validators[0].ExecQuery(ctx, "tx", txHash) + require.NoError(t, err) + + // Parse response + var txResponse TxResponse + err = json.Unmarshal(txResult, &txResponse) + require.NoError(t, err) + + return &txResponse, nil +} + +// VerifyFee verifies the fee amount in the contract state +func VerifyFee( + t *testing.T, + ctx context.Context, + wormchain *cosmos.CosmosChain, + contractAddr string, + expectedAmount string, +) { + var stateResp GetStateQueryResponse + err := wormchain.QueryContract(ctx, contractAddr, QueryMsg{ + GetState: &QueryMsg_GetState{}, + }, &stateResp) + require.NoError(t, err) + require.Equal(t, "uworm", stateResp.Data.Fee.Denom) + require.Equal(t, Uint128(expectedAmount), stateResp.Data.Fee.Amount) +} + +// VerifyEventAttributes verifies the attributes in a wasm tx response +func VerifyEventAttributes(t *testing.T, txResponse *TxResponse, expectedAttributes map[string]string) { + require.Equal(t, uint32(0), txResponse.Code, "tx should succeed") + + // Find the wasm event + var wasmEvent *sdk.StringEvent + for _, log := range txResponse.Logs { + for _, event := range log.Events { + if event.Type == "wasm" { + wasmEvent = &event + break + } + } + } + require.NotNil(t, wasmEvent, "wasm event not found") + + // Helper to find attribute value + findAttribute := func(key string) string { + for _, attr := range wasmEvent.Attributes { + if attr.Key == key { + return attr.Value + } + } + return "" + } + + // Verify each expected attribute + for key, expectedValue := range expectedAttributes { + actualValue := findAttribute(key) + require.Equal(t, expectedValue, actualValue, + "unexpected value for attribute %s", key) + } +} + +// PostMessageWithFee posts a message to the contract with a fee +func PostMessageWithFee( + t *testing.T, + ctx context.Context, + wormchain *cosmos.CosmosChain, + contractAddr string, + message string, + fee int64, +) error { + messageBase64 := base64.StdEncoding.EncodeToString([]byte(message)) + executeMsg, err := json.Marshal(ExecuteMsg{ + PostMessage: &ExecuteMsg_PostMessage{ + Message: Binary(messageBase64), + Nonce: 1, + }, + }) + require.NoError(t, err) + + funds := sdk.Coins{sdk.NewInt64Coin("uworm", fee)} + _, err = wormchain.ExecuteContractWithAmount(ctx, "faucet", contractAddr, string(executeMsg), funds) + return err +} + +// SubmitTransferFee submits a VAA to transfer fees to an address +func SubmitTransferFee( + t *testing.T, + ctx context.Context, + guardians *guardians.ValSet, + wormchain *cosmos.CosmosChain, + contractAddr string, + addrBytes []byte, + amount string, + replay bool, +) (*TxResponse, error) { + // Created a fixed 32-byte array for the recipient address + var recipientBytes [32]byte + copy(recipientBytes[32-len(addrBytes):], addrBytes) + + // Create a fixed 32-byte array for the fee amount + var amountBytes [32]byte + amountInt := new(big.Int) + amountInt.SetString(amount, 10) + amountInt.FillBytes(amountBytes[:]) + + buf := new(bytes.Buffer) + buf.Write(vaa.CoreModule) + vaa.MustWrite(buf, binary.BigEndian, vaa.ActionCoreTransferFees) + vaa.MustWrite(buf, binary.BigEndian, uint16(0)) + buf.Write(recipientBytes[:]) + buf.Write(amountBytes[:]) + + guardianSetIndex := helpers.QueryConsensusGuardianSetIndex(t, wormchain, ctx) + govVaa := helpers.GenerateGovernanceVaa(uint32(guardianSetIndex), guardians, buf.Bytes()) + vaaBz, err := govVaa.Marshal() + require.NoError(t, err) + + encodedVaa := base64.StdEncoding.EncodeToString(vaaBz) + executeVAAPayload, err := json.Marshal(ExecuteMsg{ + SubmitVaa: &ExecuteMsg_SubmitVAA{ + Vaa: Binary(encodedVaa), + }, + }) + require.NoError(t, err) + + txHash, err := wormchain.ExecuteContract(ctx, "faucet", contractAddr, string(executeVAAPayload)) + if err != nil { + return nil, err + } + + err = testutil.WaitForBlocks(ctx, 2, wormchain) + require.NoError(t, err) + + if replay { + _, err = wormchain.ExecuteContract(ctx, "faucet", contractAddr, string(executeVAAPayload)) + require.Error(t, err) + require.Contains(t, err.Error(), "VaaAlreadyExecuted") + } + + txResult, _, err := wormchain.Validators[0].ExecQuery(ctx, "tx", txHash) + require.NoError(t, err) + + var txResponse TxResponse + err = json.Unmarshal(txResult, &txResponse) + require.NoError(t, err) + + return &txResponse, nil +} + +// GetUwormBalance returns the balance of uworm tokens for an address +func GetUwormBalance(t *testing.T, ctx context.Context, wormchain *cosmos.CosmosChain, addr string) (int64, error) { + coins, err := wormchain.GetBalance(ctx, addr, "uworm") + if err != nil { + return 0, err + } + + return coins, nil +} diff --git a/wormchain/interchaintest/helpers/migrate_contract.go b/wormchain/interchaintest/helpers/migrate_contract.go index b488f462ee..1f57c6a964 100644 --- a/wormchain/interchaintest/helpers/migrate_contract.go +++ b/wormchain/interchaintest/helpers/migrate_contract.go @@ -35,7 +35,7 @@ func MigrateContract( codeId string, message string, guardians *guardians.ValSet, -) { +) error { node := chain.GetFullNode() @@ -48,5 +48,5 @@ func MigrateContract( vHex := hex.EncodeToString(vBz) _, err = node.ExecTx(ctx, keyName, "wormhole", "migrate", contractAddr, codeId, message, vHex, "--gas", "auto") - require.NoError(t, err) + return err } diff --git a/wormchain/interchaintest/helpers/vaa.go b/wormchain/interchaintest/helpers/vaa.go index 093b84e920..d2dfb84ee7 100644 --- a/wormchain/interchaintest/helpers/vaa.go +++ b/wormchain/interchaintest/helpers/vaa.go @@ -1,8 +1,11 @@ package helpers import ( + "encoding/hex" + "testing" "time" + "github.com/stretchr/testify/require" "github.com/wormhole-foundation/wormhole/sdk/vaa" "github.com/wormhole-foundation/wormchain/interchaintest/guardians" @@ -44,3 +47,23 @@ func GenerateGovernanceVaa(index uint32, latestSequence = latestSequence + 1 return signVaa(*v, signers) } + +func GenerateEmptyVAA( + t *testing.T, + guardians *guardians.ValSet, + moduleStr string, + action vaa.GovernanceAction, + chainID vaa.ChainID, +) string { + + payloadBz, err := vaa.EmptyPayloadVaa(moduleStr, action, chainID) + require.NoError(t, err) + v := generateVaa(0, guardians, vaa.GovernanceChain, vaa.GovernanceEmitter, payloadBz) + + v = signVaa(v, guardians) + vBz, err := v.Marshal() + require.NoError(t, err) + vHex := hex.EncodeToString(vBz) + + return vHex +} diff --git a/wormchain/interchaintest/helpers/wormhole_core.go b/wormchain/interchaintest/helpers/wormhole_core.go index 9615d3ab04..d7b3cd7b3e 100644 --- a/wormchain/interchaintest/helpers/wormhole_core.go +++ b/wormchain/interchaintest/helpers/wormhole_core.go @@ -1,9 +1,11 @@ package helpers import ( + "context" "encoding/json" "testing" + "github.com/strangelove-ventures/interchaintest/v4/chain/cosmos" "github.com/strangelove-ventures/interchaintest/v4/ibc" "github.com/stretchr/testify/require" "github.com/wormhole-foundation/wormchain/interchaintest/guardians" @@ -28,7 +30,7 @@ type GuardianAddress struct { Bytes []byte `json:"bytes"` } -func CoreContractInstantiateMsg(t *testing.T, cfg ibc.ChainConfig, guardians *guardians.ValSet) string { +func CoreContractInstantiateMsg(t *testing.T, cfg ibc.ChainConfig, vaaChainId vaa.ChainID, guardians *guardians.ValSet) string { guardianAddresses := []GuardianAddress{} for i := 0; i < guardians.Total; i++ { guardianAddresses = append(guardianAddresses, GuardianAddress{ @@ -44,7 +46,7 @@ func CoreContractInstantiateMsg(t *testing.T, cfg ibc.ChainConfig, guardians *gu ExpirationTime: 0, }, GuardianSetExpirity: 86400, - ChainId: uint16(vaa.ChainIDWormchain), + ChainId: uint16(vaaChainId), FeeDenom: cfg.Denom, } msgBz, err := json.Marshal(msg) @@ -52,3 +54,23 @@ func CoreContractInstantiateMsg(t *testing.T, cfg ibc.ChainConfig, guardians *gu return string(msgBz) } + +// QueryConsensusGuardianSetIndex queries the index of the consensus guardian set +func QueryConsensusGuardianSetIndex(t *testing.T, wormchain *cosmos.CosmosChain, ctx context.Context) uint64 { + stdout, _, err := wormchain.GetFullNode().ExecQuery(ctx, + "wormhole", "show-consensus-guardian-set-index", + ) + require.NoError(t, err) + + res := new(ConsensusGuardianSetIndexResponse) + err = json.Unmarshal(stdout, res) + require.NoError(t, err) + + return res.ConsensusGuardianSetIndex.Index +} + +type ConsensusGuardianSetIndexResponse struct { + ConsensusGuardianSetIndex struct { + Index uint64 `json:"index"` + } `json:"ConsensusGuardianSetIndex"` +} diff --git a/wormchain/interchaintest/ibc_receiver_test.go b/wormchain/interchaintest/ibc_receiver_test.go index 9334465f29..a26fceafdf 100644 --- a/wormchain/interchaintest/ibc_receiver_test.go +++ b/wormchain/interchaintest/ibc_receiver_test.go @@ -338,7 +338,7 @@ func instantiateWormholeIbcContracts(t *testing.T, ctx context.Context, guardians *guardians.ValSet) (helpers.ContractInfoResponse, helpers.ContractInfoResponse) { // Instantiate the Wormchain core contract - coreInstantiateMsg := helpers.CoreContractInstantiateMsg(t, wormchainConfig, guardians) + coreInstantiateMsg := helpers.CoreContractInstantiateMsg(t, wormchainConfig, vaa.ChainIDWormchain, guardians) wormchainCoreContractInfo := helpers.StoreAndInstantiateWormholeContract(t, ctx, wormchain, "faucet", "./contracts/wormhole_core.wasm", "wormhole_core", coreInstantiateMsg, guardians) // Store wormhole-ibc-receiver contract on wormchain @@ -354,7 +354,7 @@ func instantiateWormholeIbcContracts(t *testing.T, ctx context.Context, require.NotEmpty(t, wormchainReceiverContractInfo.ContractInfo.IbcPortID, "wormchain (wormchain-ibc-receiver) contract port id is nil") // Store and instantiate wormhole-ibc contract on osmosis - senderInstantiateMsg := helpers.CoreContractInstantiateMsg(t, wormchainConfig, guardians) + senderInstantiateMsg := helpers.CoreContractInstantiateMsg(t, wormchainConfig, vaa.ChainIDWormchain, guardians) senderCodeId, err := remoteChain.StoreContract(ctx, "faucet", "./contracts/wormhole_ibc.wasm") require.NoError(t, err) senderContractAddr, err := remoteChain.InstantiateContract(ctx, "faucet", senderCodeId, senderInstantiateMsg, true) diff --git a/wormchain/interchaintest/malformed_payload_test.go b/wormchain/interchaintest/malformed_payload_test.go index 871c4c312a..dfed0fc998 100644 --- a/wormchain/interchaintest/malformed_payload_test.go +++ b/wormchain/interchaintest/malformed_payload_test.go @@ -58,7 +58,7 @@ func TestMalformedPayload(t *testing.T) { fmt.Println("Core contract code id: ", coreContractCodeId) // Instantiate wormhole core contract - coreInstantiateMsg := helpers.CoreContractInstantiateMsg(t, wormchainConfig, guardians) + coreInstantiateMsg := helpers.CoreContractInstantiateMsg(t, wormchainConfig, vaa.ChainIDWormchain, guardians) coreContractAddr := helpers.InstantiateContract(t, ctx, wormchain, "faucet", coreContractCodeId, "wormhole_core", coreInstantiateMsg, guardians) fmt.Println("Core contract address: ", coreContractAddr) diff --git a/wormchain/interchaintest/upgrade_test.go b/wormchain/interchaintest/upgrade_test.go index 4e18b3b45e..b5fc25a8c3 100644 --- a/wormchain/interchaintest/upgrade_test.go +++ b/wormchain/interchaintest/upgrade_test.go @@ -186,7 +186,7 @@ func TestUpgrade(t *testing.T) { fmt.Println("Core contract code id: ", coreContractCodeId) // Instantiate wormhole core contract - coreInstantiateMsg := helpers.CoreContractInstantiateMsg(t, wormchainConfig, guardians) + coreInstantiateMsg := helpers.CoreContractInstantiateMsg(t, wormchainConfig, vaa.ChainIDWormchain, guardians) coreContractAddr := helpers.InstantiateContract(t, ctx, wormchain, "faucet", coreContractCodeId, "wormhole_core", coreInstantiateMsg, guardians) fmt.Println("Core contract address: ", coreContractAddr) diff --git a/wormchain/interchaintest/wormchain_test.go b/wormchain/interchaintest/wormchain_test.go index cec5d30cac..587aec0487 100644 --- a/wormchain/interchaintest/wormchain_test.go +++ b/wormchain/interchaintest/wormchain_test.go @@ -104,7 +104,7 @@ func TestWormchain(t *testing.T) { fmt.Println("Core contract code id: ", coreContractCodeId) // Instantiate wormhole core contract - coreInstantiateMsg := helpers.CoreContractInstantiateMsg(t, wormchainConfig, guardians) + coreInstantiateMsg := helpers.CoreContractInstantiateMsg(t, wormchainConfig, vaa.ChainIDWormchain, guardians) coreContractAddr := helpers.InstantiateContract(t, ctx, wormchain, "faucet", coreContractCodeId, "wormhole_core", coreInstantiateMsg, guardians) fmt.Println("Core contract address: ", coreContractAddr)