Compare commits

...

31 Commits

Author SHA1 Message Date
John Saigle ab9b884ee6
Merge 35fd22c0a3 into d44451d7b5 2024-04-26 14:47:26 -04:00
Bruce Riley d44451d7b5 Client/js: Scroll and blast mainnet support 2024-04-26 12:37:18 -04:00
Evan Gray 6adb1e899a deployments: update standardRelayerVAAs.csv to gs4 2024-04-26 11:24:01 -04:00
Bruce Riley 473b095b3f Client/js: Wormholescan URL is wrong 2024-04-26 11:04:38 -04:00
bruce-riley 73cbcabcec
Deploy Scroll and Blast mainnet (#3909)
* Deploy Scroll and Blast mainnet

* Rework
2024-04-26 10:04:29 -05:00
Dirk Brink d63f2ca532 node: Manual initial token list for Blast and Scroll 2024-04-26 09:48:21 -04:00
Evan Gray e6dfb9115e node: shorten hostname for load testing 2024-04-25 16:11:57 -04:00
bruce-riley 034c570b33
Node/Acct: Add parameter checks (#3907) 2024-04-25 15:10:01 -05:00
Dirk Brink a566c3d3bf docs: Update security.md with Cantina NTT audit report 2024-04-24 18:50:49 -04:00
Csongor Kiss 9620fca895
node: generalised governance (#3895)
* node/admin: add generalised EVM call governance handler

Handles governance requests of the form:

```
current_set_index: 4
messages: {
  sequence: 4513077582118919631
  nonce: 2809988562
  evm_call: {
    chain_id: 3
    governance_contract: "0xD8E4C2DbDd2e2bd8F1336EA691dBFF6952B1a6eB"
    target_contract: "0xF890982f9310df57d00f659cf4fd87e65adEd8d7"
    abi_encoded_call: "6497f75a000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000f890982f9310df57d00f659cf4fd87e65aded8d70000000000000000000000000000000000000000000000000000000000000140bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe000000000000000000000000000000000000000000000000000000000000000268690000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004beefface00000000000000000000000000000000000000000000000000000000"
  }
}
```

* node/admin: add admin template for evm governance call

* node/admin: add generalised Solana call governance handler

handles governance requests of the form

```
current_set_index: 4
messages: {
  sequence: 4513077582118919631
  nonce: 2809988562
  solana_call: {
    chain_id: 3
    governance_contract: "3u8hJUVTA4jH1wYAyUur7FFZVQ8H635K3tSHHF4ssjQ5"
    encoded_instruction: "BEEFFACE"
  }
}
```

* node/admin: check address lengths and fix typo in governance handler

* node/admin: better error handling and fix comments

* sdk/vaa: add constants for general purpose governance actions
2024-04-23 11:28:02 -04:00
Bruce Riley 35f0b343ed Client/js: Add new chains 2024-04-22 17:14:23 -04:00
Jeff Schroeder bda43b2ac7 wormchain: update cosmos ledger bindings
Ran automatically via:

    go get github.com/cosmos/cosmos-sdk/crypto/ledger@v0.45.11

Fixes:

	 => ERROR [15/16] RUN make client                                                                                                                                                                                                                                           0.7s
	------
	 > [15/16] RUN make client:
	0.202 building wormchaind-v0.0.1
	0.202 go build -v -ldflags '-X github.com/cosmos/cosmos-sdk/version.Name=wormchain -X github.com/cosmos/cosmos-sdk/version.ServerName=wormchaind -X github.com/cosmos/cosmos-sdk/version.Version=v0.0.1 -X github.com/cosmos/cosmos-sdk/version.Commit=abc123 -X "github.com/cosmos/cosmos-sdk/version.BuildTags=ledger"' -tags ledger -o build/wormchaind cmd/wormchaind/main.go
	0.649 /go/pkg/mod/github.com/wormhole-foundation/cosmos-sdk@v0.45.9-wormhole-2/crypto/ledger/ledger_real.go:6:8: missing go.sum entry for module providing package github.com/cosmos/ledger-cosmos-go (imported by github.com/cosmos/cosmos-sdk/crypto/ledger); to add:
	0.649 	go get github.com/cosmos/cosmos-sdk/crypto/ledger@v0.45.11
	0.650 make: *** [Makefile:26: build/wormchaind] Error 1
	------
	Dockerfile:37
	--------------------
	  35 |     RUN /bin/bash /app/devnet/create-genesis.sh
	  36 |
	  37 | >>> RUN make client
	  38 |     RUN chmod +x /app/build/wormchaind
	  39 |
	--------------------
	ERROR: failed to solve: process "/bin/sh -c make client" did not complete successfully: exit code: 2
2024-04-22 16:31:18 -04:00
Jeff Schroeder 14d73dafe0 node: run go mod tidy
Necessary when updating the go ledger dependencies.
2024-04-22 16:31:18 -04:00
Michael Nguyen ddf5ba159c Fixes transactions when using a Ledger 2024-04-22 16:31:18 -04:00
bruce-riley 9af1fac9e1
Node/EVM: Linea poller (#3872)
* Node/EVM: Linea poller

* Explicitly check finality type in watcher
2024-04-22 10:11:45 -05:00
John Saigle 35fd22c0a3
Remove code mistakenly added during rebase 2024-04-15 15:56:46 -04:00
John Saigle 2aa0f75e8c
Fix governor unit test
Hard-coded value should be 1, not 2, because we are only summing over
the emitter chain's transfers
2024-04-15 15:50:35 -04:00
John Saigle 7b7078dab9
fix casing on hard-coded error strings 2024-04-15 15:50:35 -04:00
John Saigle d3c6ebd2fa
Restore comment 2024-04-15 15:50:35 -04:00
John Saigle 76bc26bcfc
Improve readability and fix spelling and style 2024-04-15 15:50:33 -04:00
John Saigle d91b4c1941
gosimple fixes 2024-04-15 15:48:17 -04:00
John Saigle 8eb96f1bfe
Cleanup and clarity
- Remove most of the unused field from the flow cancel token list to
  make it easier to grok
- Clarify in the source code that the tokens are taken directly from the
  generated mainnet token list
- Move comments around in the governor code to make them easier to read
- Make varible name extra verbose and easier to understand
2024-04-15 15:48:16 -04:00
John Saigle e197979eb7
Fix comment on function 2024-04-15 15:48:16 -04:00
John Saigle 8e483eb574
Add unit test for sum invariant 2024-04-15 15:48:16 -04:00
John Saigle 5ec1594496
formatting with goimports 2024-04-15 15:48:16 -04:00
John Saigle 20a50075f9
fix incorrect comment 2024-04-15 15:48:16 -04:00
John Saigle 704d73c66d
remove TODOs 2024-04-15 15:48:16 -04:00
John Saigle 85780c272b
Remove artifacts from earlier implementation 2024-04-15 15:48:15 -04:00
John Saigle 83c78079a3
Add more unit tests for flow cancelling
1. Add check to ensure that now underflow is possible when the sum of
   flow cancelling transactions is greater than the sum of all transfers
   from the emitter chain
2. Ensure that the sum of all transfers from an emitter chain does not
   exceed the dailyLimit of a Governor. This is done by testing against
   a specific error message and ensuring that it is returned by the
   program when we force it into this illegal state
2024-04-15 15:48:15 -04:00
John Saigle 4252d039dd
Flow cancel implementation
Adds an implementation of 'flow canceling' logic into the Governor:
- There now exists an allow-list of 'flow cancel tokens'
- When calculating the governor usage for some emitting chain, its usage
  is now decrementing by the sum of all transfers from other chains that
  use flow-canceling tokens and have their destination chain equal to
  emitting chain in question
- In effect, TrimAndSumValue now calculates the net Usage of a chain
  when flow canceling is taken into account
- This commit also adds a basic unit test demonstrating flow cancelling
  for a simple case
2024-04-15 15:48:15 -04:00
John Saigle 90ec6c94da
Add allow list of tokens, and tests
- Add an allow list of tokens to be used in the Flow Cancel design
2024-04-15 15:48:02 -04:00
41 changed files with 7224 additions and 553 deletions

View File

@ -44,6 +44,7 @@ As these 3rd party audits are completed and issues are sufficiently addressed, w
- **[Jan 2024 - OtterSec](https://github.com/wormhole-foundation/wormhole-audits/blob/main/2024-01-ottersec-terra.pdf)**: _Terra Classic Contract Upgrades_
- **[Feb 2024 - Cyfrin](https://github.com/wormhole-foundation/wormhole-audits/blob/main/2024-04-09-cyfrin-wormhole-evm-cctp-v2-1.pdf)**: _CCTP EVM Contracts_
- **[Mar 2024 - Cyfrin](https://github.com/wormhole-foundation/wormhole-audits/blob/main/2024-04-11-cyfrin-wormhole-evm-ntt.pdf)**: _NTT EVM Contracts_
- **[Mar 2024 - Cantina](https://github.com/wormhole-foundation/wormhole-audits/blob/main/2024-04-cantina-wormhole-evm-ntt.pdf)**: _NTT EVM Contracts_
- **[Mar 2024 - OtterSec](https://github.com/wormhole-foundation/wormhole-audits/blob/main/2024-03-28-ottersec-solana-ntt.pdf)**: _NTT Solana Contracts_
- **[Mar 2024 - Neodyme](https://github.com/wormhole-foundation/wormhole-audits/blob/main/2024-04-12-neodyme-solana-ntt.pdf)**: _NTT Solana Contracts_

View File

@ -253,9 +253,10 @@ Options:
"avalanche", "oasis", "algorand", "aurora", "fantom", "karura", "acala",
"klaytn", "celo", "near", "moonbeam", "neon", "terra2", "injective",
"osmosis", "sui", "aptos", "arbitrum", "optimism", "gnosis", "pythnet",
"xpla", "btc", "base", "sei", "rootstock", "scroll", "mantle", "wormchain",
"cosmoshub", "evmos", "kujira", "neutron", "celestia", "stargaze", "seda",
"dymension", "sepolia", "arbitrum_sepolia", "base_sepolia",
"xpla", "btc", "base", "sei", "rootstock", "scroll", "mantle", "blast",
"xlayer", "linea", "berachain", "seievm", "wormchain", "cosmoshub", "evmos",
"kujira", "neutron", "celestia", "stargaze", "seda", "dymension",
"provenance", "sepolia", "arbitrum_sepolia", "base_sepolia",
"optimism_sepolia", "holesky", "polygon_sepolia"]
-n, --network Network
[required] [choices: "mainnet", "testnet", "devnet"]
@ -311,18 +312,20 @@ Options:
"avalanche", "oasis", "algorand", "aurora", "fantom", "karura", "acala",
"klaytn", "celo", "near", "moonbeam", "neon", "terra2", "injective",
"osmosis", "sui", "aptos", "arbitrum", "optimism", "gnosis", "pythnet",
"xpla", "btc", "base", "sei", "rootstock", "scroll", "mantle", "wormchain",
"cosmoshub", "evmos", "kujira", "neutron", "celestia", "stargaze", "seda",
"dymension", "sepolia", "arbitrum_sepolia", "base_sepolia",
"xpla", "btc", "base", "sei", "rootstock", "scroll", "mantle", "blast",
"xlayer", "linea", "berachain", "seievm", "wormchain", "cosmoshub", "evmos",
"kujira", "neutron", "celestia", "stargaze", "seda", "dymension",
"provenance", "sepolia", "arbitrum_sepolia", "base_sepolia",
"optimism_sepolia", "holesky", "polygon_sepolia"]
--dst-chain destination chain
[required] [choices: "solana", "ethereum", "terra", "bsc", "polygon",
"avalanche", "oasis", "algorand", "aurora", "fantom", "karura", "acala",
"klaytn", "celo", "near", "moonbeam", "neon", "terra2", "injective",
"osmosis", "sui", "aptos", "arbitrum", "optimism", "gnosis", "pythnet",
"xpla", "btc", "base", "sei", "rootstock", "scroll", "mantle", "wormchain",
"cosmoshub", "evmos", "kujira", "neutron", "celestia", "stargaze", "seda",
"dymension", "sepolia", "arbitrum_sepolia", "base_sepolia",
"xpla", "btc", "base", "sei", "rootstock", "scroll", "mantle", "blast",
"xlayer", "linea", "berachain", "seievm", "wormchain", "cosmoshub", "evmos",
"kujira", "neutron", "celestia", "stargaze", "seda", "dymension",
"provenance", "sepolia", "arbitrum_sepolia", "base_sepolia",
"optimism_sepolia", "holesky", "polygon_sepolia"]
--dst-addr destination address [string] [required]
--token-addr token address [string] [default: native token]
@ -355,9 +358,10 @@ Positionals:
"avalanche", "oasis", "algorand", "aurora", "fantom", "karura", "acala",
"klaytn", "celo", "near", "moonbeam", "neon", "terra2", "injective",
"osmosis", "sui", "aptos", "arbitrum", "optimism", "gnosis", "pythnet",
"xpla", "btc", "base", "sei", "rootstock", "scroll", "mantle", "wormchain",
"cosmoshub", "evmos", "kujira", "neutron", "celestia", "stargaze", "seda",
"dymension", "sepolia", "arbitrum_sepolia", "base_sepolia",
"xpla", "btc", "base", "sei", "rootstock", "scroll", "mantle", "blast",
"xlayer", "linea", "berachain", "seievm", "wormchain", "cosmoshub", "evmos",
"kujira", "neutron", "celestia", "stargaze", "seda", "dymension",
"provenance", "sepolia", "arbitrum_sepolia", "base_sepolia",
"optimism_sepolia", "holesky", "polygon_sepolia"]
tx Source transaction hash [string]

View File

@ -10,7 +10,7 @@
"license": "Apache-2.0",
"dependencies": {
"@celo-tools/celo-ethers-wrapper": "^0.1.0",
"@certusone/wormhole-sdk": "^0.10.13",
"@certusone/wormhole-sdk": "^0.10.15",
"@cosmjs/encoding": "^0.26.2",
"@improbable-eng/grpc-web-node-http-transport": "^0.15.0",
"@injectivelabs/networks": "^1.10.7",
@ -683,9 +683,9 @@
}
},
"node_modules/@certusone/wormhole-sdk": {
"version": "0.10.13",
"resolved": "https://registry.npmjs.org/@certusone/wormhole-sdk/-/wormhole-sdk-0.10.13.tgz",
"integrity": "sha512-04OCGoJUylTFNu4+g96Ax7jvn3M7FwVbTTcPNIjgta8QcC046kZBYAEd/yrK5hkDGqejQyJwO0ieaJfxL/kv1w==",
"version": "0.10.15",
"resolved": "https://registry.npmjs.org/@certusone/wormhole-sdk/-/wormhole-sdk-0.10.15.tgz",
"integrity": "sha512-XECfrvdYjsGPZWyR1bqWCPOiRw7+6upszpSvAXjKIqEnTNXOCYRkt5ae8TVh5oZxPjpts2X3t4Oi9WGcEssHpQ==",
"dependencies": {
"@certusone/wormhole-sdk-proto-web": "0.0.7",
"@certusone/wormhole-sdk-wasm": "^0.0.1",
@ -11917,9 +11917,9 @@
"requires": {}
},
"@certusone/wormhole-sdk": {
"version": "0.10.13",
"resolved": "https://registry.npmjs.org/@certusone/wormhole-sdk/-/wormhole-sdk-0.10.13.tgz",
"integrity": "sha512-04OCGoJUylTFNu4+g96Ax7jvn3M7FwVbTTcPNIjgta8QcC046kZBYAEd/yrK5hkDGqejQyJwO0ieaJfxL/kv1w==",
"version": "0.10.15",
"resolved": "https://registry.npmjs.org/@certusone/wormhole-sdk/-/wormhole-sdk-0.10.15.tgz",
"integrity": "sha512-XECfrvdYjsGPZWyR1bqWCPOiRw7+6upszpSvAXjKIqEnTNXOCYRkt5ae8TVh5oZxPjpts2X3t4Oi9WGcEssHpQ==",
"requires": {
"@certusone/wormhole-sdk-proto-web": "0.0.7",
"@certusone/wormhole-sdk-wasm": "^0.0.1",

View File

@ -1,6 +1,6 @@
{
"name": "@wormhole-foundation/wormhole-cli",
"version": "0.0.3",
"version": "0.0.4",
"sideEffects": [
"src/side-effects.ts"
],
@ -30,7 +30,7 @@
],
"dependencies": {
"@celo-tools/celo-ethers-wrapper": "^0.1.0",
"@certusone/wormhole-sdk": "^0.10.13",
"@certusone/wormhole-sdk": "^0.10.15",
"@cosmjs/encoding": "^0.26.2",
"@improbable-eng/grpc-web-node-http-transport": "^0.15.0",
"@injectivelabs/networks": "^1.10.7",

View File

@ -62,6 +62,11 @@ export const getOriginalAsset = async (
// case "rootstock":
case "scroll":
case "mantle":
case "blast":
case "xlayer":
case "linea":
case "berachain":
case "seievm":
case "sepolia":
case "arbitrum_sepolia":
case "base_sepolia":
@ -125,6 +130,7 @@ export const getOriginalAsset = async (
case "stargaze":
case "seda":
case "dymension":
case "provenance":
case "rootstock":
throw new Error(`${chainName} not supported`);
default:

View File

@ -72,6 +72,11 @@ export const getWrappedAssetAddress = async (
// case "rootstock":
case "scroll":
case "mantle":
case "blast":
case "xlayer":
case "linea":
case "berachain":
case "seievm":
case "sepolia":
case "arbitrum_sepolia":
case "base_sepolia":
@ -172,6 +177,7 @@ export const getWrappedAssetAddress = async (
case "stargaze":
case "seda":
case "dymension":
case "provenance":
throw new Error(`${chainName} not supported`);
default:
impossible(chainName);

View File

@ -99,6 +99,11 @@ export const getProviderForChain = <T extends ChainId | ChainName>(
// case "rootstock":
case "scroll":
case "mantle":
case "blast":
case "xlayer":
case "linea":
case "berachain":
case "seievm":
case "sepolia":
case "arbitrum_sepolia":
case "base_sepolia":
@ -169,6 +174,7 @@ export const getProviderForChain = <T extends ChainId | ChainName>(
case "stargaze":
case "seda":
case "dymension":
case "provenance":
case "rootstock":
throw new Error(`${chainName} not supported`);
default:

View File

@ -172,7 +172,7 @@ export const handler = async (
}));
} else if (argv.wormscan) {
const wormscanurl =
"https://api.wormscan.io/api/v1/observations/" +
"https://api.wormholescan.io/api/v1/observations/" +
vaa.emitterChain.toString() +
"/" +
vaa.emitterAddress.replace(/^(0x)/, "") +

View File

@ -200,6 +200,8 @@ async function executeSubmit(
throw Error("seda is not supported yet");
} else if (chain === "dymension") {
throw Error("dymension is not supported yet");
} else if (chain === "provenance") {
throw Error("provenance is not supported yet");
} else if (chain === "rootstock") {
throw Error("rootstock is not supported yet");
} else {

View File

@ -154,6 +154,8 @@ export const handler = async (
throw Error("seda is not supported yet");
} else if (srcChain === "dymension") {
throw Error("dymension is not supported yet");
} else if (srcChain === "provenance") {
throw Error("provenance is not supported yet");
} else if (srcChain === "rootstock") {
throw Error("rootstock is not supported yet");
} else {

View File

@ -171,6 +171,41 @@ const MAINNET = {
key: getEnvVar("ETH_KEY"),
chain_id: 30,
},
scroll: {
rpc: "https://rpc.ankr.com/scroll",
key: getEnvVar("ETH_KEY"),
chain_id: 534352,
},
mantle: {
rpc: undefined,
key: undefined,
chain_id: undefined,
},
blast: {
rpc: "https://rpc.ankr.com/blast",
key: getEnvVar("ETH_KEY"),
chain_id: 81457,
},
xlayer: {
rpc: undefined,
key: undefined,
chain_id: undefined,
},
linea: {
rpc: undefined,
key: undefined,
chain_id: undefined,
},
berachain: {
rpc: undefined,
key: undefined,
chain_id: undefined,
},
seievm: {
rpc: undefined,
key: undefined,
chain_id: undefined,
},
sepolia: {
rpc: undefined,
key: undefined,
@ -206,16 +241,6 @@ const MAINNET = {
key: undefined,
chain_id: undefined,
},
scroll: {
rpc: undefined,
key: undefined,
chain_id: undefined,
},
mantle: {
rpc: undefined,
key: undefined,
chain_id: undefined,
},
arbitrum_sepolia: {
rpc: undefined,
key: undefined,
@ -251,6 +276,11 @@ const MAINNET = {
key: undefined,
chain_id: undefined,
},
provenance: {
rpc: undefined,
key: undefined,
chain_id: undefined,
},
};
const TESTNET = {
@ -362,6 +392,41 @@ const TESTNET = {
rpc: "https://rpc.atlantic-2.seinetwork.io",
key: getEnvVar("SEI_KEY_TESTNET"),
},
scroll: {
rpc: "https://rpc.ankr.com/scroll_sepolia_testnet",
key: getEnvVar("ETH_KEY_TESTNET"),
chain_id: 534353,
},
mantle: {
rpc: "https://mantle-sepolia.drpc.org",
key: getEnvVar("ETH_KEY_TESTNET"),
chain_id: 5003,
},
blast: {
rpc: "https://blast-sepolia.drpc.org",
key: getEnvVar("ETH_KEY_TESTNET"),
chain_id: 168587773,
},
xlayer: {
rpc: "https://testrpc.xlayer.tech/",
key: getEnvVar("ETH_KEY_TESTNET"),
chain_id: 195,
},
linea: {
rpc: "https://rpc.sepolia.linea.build",
key: getEnvVar("ETH_KEY_TESTNET"),
chain_id: 59141,
},
berachain: {
rpc: "https://artio.rpc.berachain.com/",
key: getEnvVar("ETH_KEY_TESTNET"),
chain_id: 80085,
},
seievm: {
rpc: "https://evm-rpc-arctic-1.sei-apis.com/",
key: getEnvVar("ETH_KEY_TESTNET"),
chain_id: 713715,
},
sepolia: {
rpc: "https://rpc.ankr.com/eth_sepolia",
key: getEnvVar("ETH_KEY_TESTNET"),
@ -445,16 +510,6 @@ const TESTNET = {
key: undefined,
chain_id: undefined,
},
scroll: {
rpc: "https://rpc.ankr.com/scroll_sepolia_testnet",
key: getEnvVar("ETH_KEY_TESTNET"),
chain_id: 534353,
},
mantle: {
rpc: "https://mantle-sepolia.drpc.org",
key: getEnvVar("ETH_KEY_TESTNET"),
chain_id: 5003,
},
arbitrum_sepolia: {
rpc: "https://arbitrum-sepolia.publicnode.com",
key: getEnvVar("ETH_KEY_TESTNET"),
@ -490,6 +545,11 @@ const TESTNET = {
key: undefined,
chain_id: undefined,
},
provenance: {
rpc: undefined,
key: undefined,
chain_id: undefined,
},
};
const DEVNET = {
@ -584,6 +644,41 @@ const DEVNET = {
rpc: undefined,
key: undefined,
},
scroll: {
rpc: undefined,
key: undefined,
chain_id: undefined,
},
mantle: {
rpc: undefined,
key: undefined,
chain_id: undefined,
},
blast: {
rpc: undefined,
key: undefined,
chain_id: undefined,
},
xlayer: {
rpc: undefined,
key: undefined,
chain_id: undefined,
},
linea: {
rpc: undefined,
key: undefined,
chain_id: undefined,
},
berachain: {
rpc: undefined,
key: undefined,
chain_id: undefined,
},
seievm: {
rpc: undefined,
key: undefined,
chain_id: undefined,
},
sepolia: {
rpc: undefined,
key: undefined,
@ -660,16 +755,6 @@ const DEVNET = {
key: undefined,
chain_id: undefined,
},
scroll: {
rpc: undefined,
key: undefined,
chain_id: undefined,
},
mantle: {
rpc: undefined,
key: undefined,
chain_id: undefined,
},
arbitrum_sepolia: {
rpc: undefined,
key: undefined,
@ -705,6 +790,11 @@ const DEVNET = {
key: undefined,
chain_id: undefined,
},
provenance: {
rpc: undefined,
key: undefined,
chain_id: undefined,
},
};
/**

View File

@ -3,8 +3,8 @@ import {
BridgeImplementation__factory,
Implementation__factory,
NFTBridgeImplementation__factory,
WormholeRelayer__factory,
} from "@certusone/wormhole-sdk/lib/esm/ethers-contracts";
import { WormholeRelayer__factory } from "@certusone/wormhole-sdk/lib/esm/ethers-relayer-contracts";
import { getWormholeRelayerAddress } from "@certusone/wormhole-sdk/lib/esm/relayer";
import {
CHAINS,

View File

@ -7,6 +7,7 @@ Algorand
algosdk
alist
Aptos
arbitrum
authorisation
authorise
authorised
@ -25,6 +26,7 @@ callstack
CCTP
celestia
Celestia
celo
certusone
Chainlink
Coinspect
@ -143,6 +145,7 @@ rustup
satoshi
secp
seda
seievm
Sepolia
serde
setcap
@ -192,6 +195,7 @@ wormchaind
Wormholescan
wormscan
wormscanurl
xlayer
xpla
XPLA
Zellic

View File

@ -1,11 +1,11 @@
Ethereum (2) Standard Relayer,01000000030d003f39e29280cb340fdea6e91de35155ce11fac49da591cf7efd61f12f4d3f46663d7c4575ec830c35c1cc19017a79e28eedc1d10fcfff4595b1dbbfc9047d55990103bb91bf8f33762ee6b07abb3119c4ba748d092bfafe87d360db962d99c96462920abb4e6d076e9d54aeafe8dec563b1930a4305e2b3961cd363bc203be0649f270005245ef83e663fbc6e9cb3f2c9eebbe44eac2f6e5844c13610333d64340c7e4407611f4e11d676e9773502f6ca6c070975297cf6f372dce0875de3f8ba80b48f58010696ea72db18de430b5c071bb09d51d53d03197a33b1df0711b5f859149ddcfc7358c84573a7518b3719b67ec01fa07140dda7241b087807c1d4548c1876559d2801086fb2063f49bc33d1f25ee13ac31cbb2a0ba540f419df1cd03c91d0aeb8e97d5e6feae3da4362897531428190a8b458c327e256016ab6ac62cc1b1e931225baee01098bfe9db66d5d50eb6177143e8db1b23200c677266f02ac2d1c04b90ee9a1d1b476a9f4f93752555e86a54e2f5bb666866310f8f587356c594218aaf41d20fbce010ab66121eb5bf8f432e1ae32bb988dd7c33d482fe4d63abe1386d38cdddae0c03964d792f2704309bceaae0c1b322e46aa651c6e2a3c2611903cddbc87363bdc75000cb22b8172a90abf14aaee5a80bb97380275798e1f89479be50b54b4549e2fcbbf285af8ed730998caa93612dac4e80eff36ea82e945672e46128d7abe12c1936a000d4ef0a4d42e2be648eb6bd37d6184c123ab0a31dd804970416972e5be3fbd6a0044d9d2dd64a430cca95110ff36f2f363fa90a0ceb524f229b46caa85f9b18bc4000e0ddb23380953eaba05b8d493f2193860f10079a2ff6ffc00bd11db94e22b5f0e1ab3bf4517972a0aa2d7ed18551231e083e48ccc07e8d64ed20fbb6d57151b8200108a585d5960d95a50f9cd6c8ca4b8ae7a70b4549a052771edff1a0c3a409ea5cd286eae6c53eb280038605384d051e04e8c2c531c0f8713e36a5c4d71a044a40b0011fa3cd95765d64bbdc070008c3111ffaf46ada75e4dc39607c643b547c3f70d423f0f4ee2ae5d7ed4361869896dcb012368a0a9586881c579a877728fd761f53a0112447e5b97e5341c5ff2e91c0aba8b48ca985f369992f00fb17fdc9c0f6576b93c6beaf3a44dfe8972df1f28c4eda7336a7955e6d33a4cc1e1c324ad45de72d56e0000000000fded29f600010000000000000000000000000000000000000000000000000000000000000004338004a37fdccca8200000000000000000000000000000000000576f726d686f6c6552656c61796572010000000200000000000000000000000027428dd2d3dd32a4d7f7c497eaaa23130d894911
BSC (4) Standard Relayer,01000000030d002e0a85cefc9dc34ead9571b45e9a296c58d8c43c4272ef5e50c8d1d0367e828a37bc44055960b5542ec79b5081c2de229ae7a5555d409235792e3cdfac3d495201030941c73fc173d2f1bfa810a141db2343f3d4ff420c56ff09354b2718b5baa4887922208e9097f19f6607d8b79bfc7ad469d4bacd3f60ae9589fdad238aa1d95301051da5b430178acfde6091d4cfd836926097be2862e30b96d89d03f9d6b9bc1a8319c814c9186d30a564db790136e24229be6c21a115518fb2e0a7f3f5053771c4010616dbe51c1f120717f6522d72cf85e42315d65dd049fce9e691658d1a0e3d98c865c71d6fc5cf7682991c476bb5ade4048d71e3ce81ba5fa2632dbd17a352260f0108fbd37725bc32e5e9a872f0477be346ed302afd45d9b0e5724347adc0cd142c020f134770727c9d57fffa249980c3687cc98d62196064c30df7a7147f07ce3af60009f6a21b63b3c8c18f96b5ff71256d5ed0f630de90ee65eebdaf6b5916b4d6fdb276d7dfdae5e05ff52a2f77b8801cbcb1fb988c6b4adcddd9aaef2e78847500f1010abc2784590de571f08bf3003ecd50a564303376c0da7a145118153022be444d940238147ca54bf65f2c312389f568ba80b0c547413a8fb527452f09320f23347f000ce6b17e707f79583df2837cec6cf05f5d3f70b99f04ef6c3a54d55e770f2aca4a78da87446c11bb39ffbaebd324d7b369944049457bbc97256dd7b06a61127263010d42c86ce3294e2cae5304d94aeb30de4c686612d090f41998af8a1473fab4fa605579308201183510ba56602f2dbba3694959e052e0d2ec973f127308517898ba010e113a38c219ebb990c5bf15c9b155bb45bcc773b53dbc2c3fcac866ab00e0f2be61e3962b99e25bbe5fefe2b0af5fde001e35a71e1856b369b5a179d3c0a826b20110ea9e738d883dc8a194c9f180a1123c2496be82678047d6220600657df77b28fd1ec53df79bc47487af116070ed44a58ab86e05030892c2107342dba5f742eb390011759c6d8c25ed3f4a60b7c30473cef12f1652231ee5e2d98efc29ffe3290a6ef37fbee021b0dcddbfbf11104ca1d9451d3ed455816821e2c089538e7d605e0a380012a07c722f449b863d996f15185efa1fb5b056be6d404c8e793492edb5736372f27a9ee67e7b4998e81cee5f45626984d801b81ef7ebc980cde1959a48b1ad57c70000000000fded29f600010000000000000000000000000000000000000000000000000000000000000004338004a37fdccca9200000000000000000000000000000000000576f726d686f6c6552656c61796572010000000400000000000000000000000027428dd2d3dd32a4d7f7c497eaaa23130d894911
Polygon (5) Standard Relayer,01000000030d004e90dfa99044e47b564eecadb2c658583064ac566daf77286761684cc687e9d65173cca86b6188c277847846681ae11bdbf1b966ae65180c7d878ff48135cfa00003f100618c84ff56ea49f563b432bad076350fae7cfcfb3dec92540803d84ea93b5da4c7fa7bd7ec363b9b612dcda7cfec9fbebdbce517dc30903f13c2ec5cb14e0105ce71d2e594f36caf27e8b769261e59b91e9e57fa16205c6d375074615088917e05130f24f1bf948431bcb025aecbf24dcf286297a3002c37ebe72acb5c2430c601068445c65befad456f1cc427c80b2243b23700c152afc60b298ccf5d24261bd9ee1627bc40aa527bc67de91de14cc0dfb2d99b9ec08d31a7ae3e1acef1ff22acbf0008991ec96f347b242770e978a6473da8c82b14dcb9a5ccc05dde4bcf1125e3d9481c25f188d07e1e4e68a916cd79ab21f41a5433d779660d15808e6c172c55accd0009425e5f3f71af0a6ebed1bb037590319bad260e2ebd8b889bc64f782e594792a52874c1973cf69b76f20a33317fa8f16e982afc85fe147ba742be1222d942dcf8000acb1b63f1a4f30702e2b883eecc8048ba91b38a09fffed33299b0e5aeabe09f7809fca5f75fc6a4022b902be7caf793a18d1371aecb3d9bf0d7d27640777b2cd7000cb6f2500ce351272a1d874e2c9516c566cd85702872e2b8b0fa09c54a0f03dbcd27c1ecb367da1dce046b4eeaea922f9ff172886ae4e50799248f58821e543f6d000d2c307443c8329b1c9e456334253c604b5d6c1d7f5dcd4406d9d8c4ed138b72f479ff2f412a41474f3d619a41c8bf216898b8e8a17d3cd7275e6929bcc221b848010e79b575b4795c6d3cccaef379c2f533de626df9a87a52389f38fac3f5d77b57aa317aaefa4386aac86638a9e19cd0dcbd92f9f087fed54c9e28cbb7eb7cc75b8401108d63f8802b17d2ae03a138c123b06a3be5fbed3d478672dc5009a6b6cdb13dea467ac4dcb16784cccd9ca9459ee98ceeafa0c9f444cdbd3654f034f288a24fe90111bd3e4eb9455c06c3aff08836f55add7b1bc5d389a1a02d02abcd5d54e5c1df1c31796b93b0b0e85320f8036a38513bc48008b4acc0890936bd46165f2589d69400127f69a920ebe11ad7b73eb13a8b2729d7a2972ef6b86ec2d9b2ca5f4e3b8b9cb70195f59e62b715724ed2221e32c4f537858d12506ec4d4cbf566982bf63bfb5a0100000000fded29f600010000000000000000000000000000000000000000000000000000000000000004338004a37fdcccaa200000000000000000000000000000000000576f726d686f6c6552656c61796572010000000500000000000000000000000027428dd2d3dd32a4d7f7c497eaaa23130d894911
Avalanche (6) Standard Relayer,01000000030d00bbfe94366547d476cc80ea55d4e62ee810c59951089c89f07d5e6dc088761384178868b90f76f3858fb749573a2eb03a4d05f8f680972d38ce5055385018a7bf010301035d39f88f4d0751269ae4e098bbe47f3591357c1b616b3e34a5c21c4c1f2c6bfd2b19a8078419699405f38d4c30b3d4970c8a7a37729dfc5c319f299883ac010566ec129bfd891f510f4b350743f2ba9c061b0b94d9cc20d0a75c20dd863722d830ad196d3cd9fb5158337e875a7848e8653d50ff7e7e63c41c2995e57e1c0397010604b345098da327b1ce27ee48a6d2bfd26a744090540042dc1d698a458f726b730f39815ab1254cc9b45bf1fb12ca62ea9b5f9f3285974c350fa7e23fe4a9c8bf010881a52213d65d8fcca6c99cea3b2d134518a451a277a0b92fcf0dba0684fc52c37254b8a2ffb450a1e0777bad5097d907cf5a48c7d70c037b3a362f1973b143d2010928b25ec1394bf9caaf9c95ef074babef722c15b0a4edccedac3fdbd6a6bd87d36ac2fb490e4605eb0d53db3eda85527fe5f00171a5a5a81b283c401ef0369794010ab5470061217ac4b94fcc45fc23292d51c04719493a2785a0caf76eb3497a402e13890bde914f07b680b84079f87bd1448ed8e4f2b1d6a60661986a6f51593d66000c28468c40328aca78777e19c2722b37057250178d92a2d66aab52d8b60bdfcb407696bdb1e2df2b002fa8e99647540a00b58c1d1f11e86a274ced8f8d8b268083010d5fa87309ca8cb8ac33c516a3c3ce860c2c69411c4f5abfec0d8ee7f08a917718371fc2e5445d27f9915cfd72396ab0b0f76fdc820f87dedfa6a129a376d39671000e028b814eb1f74fbf10a5fb2c465a254b0002830aad9201555d7f9b5061bf99f41cbeca0fbb2b6dda51fda40dfcf88be08b3c9a9ee1410347a0dff0f70a76fd560010fa217241fb64df96812ba7adea8ff477b4c03a76c25ebb3f8bc817afca2a735c7c8d0c57e02ced4c522dc5c5c02758eee91fd3bbf8f69057e93cce6ed177c9d500115cd9c43d6c791a3ad05cea7cfd97f76a1eefa267e134f0d8144b9fc527f93d2e017c44c427670248954d1d119b712412e032ace9f4879b8c36439c100318d0f000127cb2e52609a2ef2838b24744233ba084f76748d2b553abefc70cef8f05eb16731e013081b28eae042ef40f73104ba2b91760e9369168ed91bb98d985edc025f10100000000fded29f600010000000000000000000000000000000000000000000000000000000000000004338004a37fdcccab200000000000000000000000000000000000576f726d686f6c6552656c61796572010000000600000000000000000000000027428dd2d3dd32a4d7f7c497eaaa23130d894911
Fantom (10) Standard Relayer,01000000030d000afc75cbef72bcf6cc35dafdf4547edb0051789ac0afbd34c7cefa561a1cc2f0199f316ce3bb93d339f86dc44986d41e33677f33d9f9742c624befefbda05a370103d3cf95aa84035358f41d4b0f5dd0c59c2de8b69af4db84e29b5df51781d4a4437cb885054e625a4ad03324573e033bee6e4169fa7fa169c2fb4a5c4c7e69bee001051f843a340ffd3a605fd84480ef14d8595b1fffdd45a7e1c919c686ac1bd234bb4255d6ff88990e33dbeb751c06ff6ba5c63469fef50fb9924c135a2e81db0f91000678e5e902519def669dc1b03d3c9be4b84589a6322bcdf3c8cb056192a13774487a49709566d0cc68fdd9c6d1f368152f1c0728bba71031a867dbf8a170cf694e0008b25df04e7b4147bd3ae3960fe7f181968c084b63a89ca11c28e557d516e6ac3b623b56e9472041a8ce9fab0be14e9f6593caf203242f5a1a8c00c8a23f947183000919c402479e75615c767de34eb463099fc752c82aa9def7bb5dca812dc5d1a14c268f8c8a4c659be8fae0e51d2f0ed120cccac58344ca9b3df9a9cd21fe1919f9000a7c96e0c21eb74310637c8bccfac24bf91190dfca3a7499bae885a4dec541c58f241933b0d567854b6d8c2fcc284e9077ffab16d6c9c0f9b24cdc2f7875e0a8fc010ccdad41a3722e94317d99ec9542e3aa59ea9cf0297f450edc57c037408bdc5d5770df000375a79ae231aff1eb128c657d0965fe8e4fb5efef26720848b6e68a14010d419a91a2299ba3d983171250bfcda19b462c6cecd6c689ab44cd06d77b3c9bc71f532521b1334308bfed01640ab3c8d212f2e69f349c7697fabcf95f43afdce7010e2238dd50fac23d82778680768dc5cf4ffd02bbb351483dd625e034c9dd0be00a1a2c49f95238a7cfd7ec45038b4478a457e9b9c217fff574b7dd9d5663c6534600100fafc125ed044c06597a7563f22a5ed5071cda2e928bf401a71592af7abd6cf45b114d1d69ab5c784cd4adddbbf51b461e85c41f5792c5e309f86787196f9f560011141a93514e4236da671151dfce33f1fd24dd6e9cc88d16ba2fb8e04c664576b122cf795666f5b5df601b2243382b99852cd23840d91c6fd7dfbb33e27753794a0012880041feece8698f81bb66e9817ffeaa30eb58b5ee4f667a24fb05030fa2ffbc347cfc3f30bd9a18ae8e5e9c01ed40d46459d25e96c486cf849d5f4dbea188480000000000fded29f600010000000000000000000000000000000000000000000000000000000000000004338004a37fdcccac200000000000000000000000000000000000576f726d686f6c6552656c61796572010000000a00000000000000000000000027428dd2d3dd32a4d7f7c497eaaa23130d894911
Klaytn (13) Standard Relayer,01000000030d00c9b9d25eaf56c5936f66f147fe45061729bfad0514c1dbc21a6b3e8c41fd669c43f8fc2dd2792ad106d9b23d7d2161374fdb24084e4dc44b246986243177e4e30003a73bdd6b228644bdc483bc8910c39f120b83c315c33764c308d9f73bc2b30c4f26ce6b93e3de1cceab441db14445318075bde8e15e9aa77fa6c311e40bdc068000053e88ee079e28c6ebd2cdd47cee327b7ba9cd985c5b01352efc25689ebeca85844f7bc66da3266dbe5d5bba69ce0f3c217e87a051fb2de74c253c1193e52b171c01064a46327c3abc0f34caa2cef14341903e14a3b84e67d594f45d0105e2e3b4ebac3793967c20da12aa3f38101fae3f071fe870fbe574657c021949d3df3003a6a701082d5c3b48bd744256c9eeab8845402e5a937481c8ae1fc525da22c9987953e3467e19a6a31c66ba8bff7dcd24d7d23b02d44c79a09da9efacb5d9be8f0dce269d0109bc3c217eb4557cbd5b486ce13e577322808eddad286ff56f8c6403de7217a32a102e634be26acadd332b24a05a04068f823a74a6a41c4e2f91ab23f6217d8ac8010a823b3773e8a5c222bf5a28b95d2ebaa992ba4f8522337e8d2aba19bbe1ad72b4222e6a86a97e346ca937464098bf5f649f5f7e6e18e71d5b4aabdc0c19bb5130000cc6d232cfefef4ec108fbef959aa294074eacb83b6c7a8fe5f6b3e76b6d4b3c4679e1e6acb3186651d7fe984c1fa895c4afbb421b18074f917e3224b684d9006e000dd4936f7cbe9cbc64a98a654d4673e66dde3a5ccd52f8f3e16fa69c01f1e63b80362aa8f70c771b04a080bf847b5015914e189c9053e659c996dfb4e1275bd4ea000e8ab19b52ecc453b221bd23b3b437243da76ac0ad88e49e71baeaae300654d8344687f7cb1d69df24426e3d18e90ba39c1267c63725712ab125749642f8742c530110ab99b0e5b37c20f786b296923131c5df829498559e46f1e5c2971fed93ceab1700a61354b60fb640e369755a9978bc57df01a55391cb5fc7400c6caed0121a890111c844b51223b2fe13448366c8cd00edc91e688ec419aeec97bd41ae9776f317f1770c1742825c3cc1bde2c0f8928edc24874abf23d94d3d12f121b661d313913b0012f46057fb23e8b994dfd0168f8dce2f661ee24fb9ffa0be22a8b0ab4424f3ffc6567d9e5c124d2dcee0d3dae8eb786f0c1d4b38fa857e17310bd25e4092c371c20000000000fded29f600010000000000000000000000000000000000000000000000000000000000000004338004a37fdcccaf200000000000000000000000000000000000576f726d686f6c6552656c61796572010000000d00000000000000000000000027428dd2d3dd32a4d7f7c497eaaa23130d894911
Celo (14) Standard Relayer,01000000030d0059eacacdd28f4646e520abfc7ef33cf313a1b8f020a27e1808f0a58df34a5ebd1d8bf0e8aca4fb0db614558b1100c80be7ddb4d8ae50232d93240fc9364887ad01032085d87ad27eaa019d14cdeeea575f926ec1db44180cb1932b6ff54b56f0a9d73bab0e952fabcba8135fad9f187db120ea6fdf260cfb3869d973d3eb725c457a01050c37eebf1a94032b3fb7f53ffabeee25610a804c7f58c7ab7e82b8d103adbe1f3af1ae9967f1045c040aa5f3a4c8e4d8d5a3802ca826483e9a1a15f8e42399050106f88d72d019b83cb9b10309c8146e19769da72bb59a26369249fe39b51d475d570e57f5e19cd864af9835c4809b2668afb6690b24f271d37d9caf7089402a67140108e7ec94efd6c6c06e792c3a7e8885bf305cd652a76876d49697c99ddfc9a98b786bc215521a03151718cd81fc4619c72ffeeb29e6cd968dab9d512f7d2d0eba8800095b6f138e529675fe335e5a72f6bc1a35d20cf518786519c24ab014ceef61eb7133adcb701a7f75ccbacc12ab5e74dbc7c083ea8318d0eede51f486292c901e74010a538c2fbf35b4630f13e694da19fd3e2fa57438622af490fd3bb19a620f88be3678b5d6408c7177575d04a6559bc0bd19538f93e6dd5288d9931511ab8c512d31000c6563e95259a53f854c5441759804111e52ce42e5332df7ca601cb14091d3c6d81a37ffb91829cafc053e14af24a59ffcabc3fd774e1399901154d52d634057fa000dd639c68822ed4f29afbdfe349fb31cc367b065f5a3bfb73587e0aaf8dd0ad5161be5fd99d78628a7bdfa8c07ffaa47d6c4b58e6b470dabecfbe95db39a96496a010eb85a203b18444f5d26beac38279081d618a50a77f0fcb7d7ff3f51fb2705d9a167bf7c7a2506dc4ac90b946ee63d8a9ea6bfad8aa8494f99f2af5d15d190801b011018d5a390d01b98d9762222d97d3cb988573f256a7a3d512bb26db78f2e1284be020a6d5a9660a869dceba199308db403e0708c785e1c2715821f69a091f39d8b01110767d6f4f27f9db7ae9e4256b9a857e78571e92197cbc8218551da332fb4110e07dfcc73438b8473b91f3a93a4bd96be9dbaff86b524eb8dc1639da33f1f79a00012b00387cd213e2e6ec3973bd90d98eb4c500c9c6aa893cb1d607d9842a326b6e75a5644785dd5ff7c2eef012e938b6df215ed4e97b8223c078fc8a8dba92787770100000000fded29f600010000000000000000000000000000000000000000000000000000000000000004338004a37fdcccb0200000000000000000000000000000000000576f726d686f6c6552656c61796572010000000e00000000000000000000000027428dd2d3dd32a4d7f7c497eaaa23130d894911
Moonbeam (16) Standard Relayer,01000000030d00147ce69eaecfb38adcf8f953bf97f1718fa3db81c1609e42ecedefee95f6fb216f20a5e3562e53a8016b4c5ac45c93f749ed3ba9381685037490286a55e5dbc50003aea201f953a34c7b5cbbccbec6c42d474107efa3c1f5f25137f0f7f1f8f3446f53fbf9b1d475f396cd04878e0bf9ef58014beec38c3fb698d38602fbdfb5f18b0105fb93126334289857302eaf327690a0d8457098fac094a6817b49f38841c385295998dfc8d50071f296053d8fc472685fee36dd8990c8230f3e276e1b873a75be0006241945f86c1abef3ee1286b1422c92bafed7b38c3daec22ba602526675b4d35e1938ab844b416b6a803bde5b12648d66e9bae68e34dc87450a69a64bbd2034ba00084ee90ad3baa0ee4ccb987f686246958634fd8834790f8b664f8ff60bf1d83e25636b9e9ccf6323234cdbd8e52c138c98f85d4ad2c40a15b136520adcf36180010109a76104932e8c3a7336ca6cdd33b1b69cbf750eb724e368fae15334ec880921963c9f5e317de2b6d7bfc634c1cf6d26567662dbe90a0f78989c2e09d8671ee004000a4b57433c1f5608e4c0e78fbb597271bdb79060a01126d555db0a00e4160e2a0e6194e6a2c815109b3ca69b14b8995fb8b5123c11e769b65865c0c48d547c15b0000c7be055a164a254ef1a8d423fb8a740f365e384dbfb1df6279ec1aa2f8e8ec33f5359e3dbc50ed0b6a6f81cc28a8df550e0b22f4039197c939fb08bf9af6207a2000dffa23f41b9167fbbcbff97425f015f62d68d4f469f0973bdecb8fab41a44c1f131ac820ee22318ea239a7455e1611c77aa7d26783aa1a11203b72f447519520c010e3ef1157fe2d4df059a0d4d3796783bcd9acbd30b9ba81273841a6f82c56b710417dbe60447e5c1bc362bdae2eb15cdcf2af4d0b76577b1b13925e0ab105b43340010443e60d8ca17b58f77996ddac9525cfaeaf5092ebea04f13fdf0aab8204bbaa23c04b1987b95836d36d706597b2439acddd2539d9f6c0bbeea970de801f9eaa500114a111aeaf1f695515f01fb174e606835292a99a2d953db84753369b7f6aec89a4e9e12db15b76a880b92983f28937e8e2569bd3a7eeddfe710c8fc4fce011ed80112433a42154cbdb6f1b1bdbccff6fdcb90e8b174540e63825af039b8fc43c1bd6211c1cb4849d6ca8cb2aaefedc684717faebe50b111a44f8224debf9aa0bbe5b00100000000fded29f600010000000000000000000000000000000000000000000000000000000000000004338004a37fdcccb1200000000000000000000000000000000000576f726d686f6c6552656c61796572010000001000000000000000000000000027428dd2d3dd32a4d7f7c497eaaa23130d894911
Arbitrum (23) Standard Relayer,01000000030d002a7523753fc4db66ca547f99a7d2f3369ec80ba3694dc80270b7efced21f900454e5968e3d6b3166f98c53dee11aa62d537bca8016eab1371d155de2146fb0790003d60b1a8ec2b4ce27e2b7298bb3cb503008b945480d537546dba2a0b1afdc80e26bc0b07d9ee4f3ef40048e25d72d23de26d22dbbc7c23df6eef0367111ea466d00053542fa8dba6b62072372bf92ef566f1ade2a95f7abe97692d20bec89c9ad220e49718ebccd0697ca592458d79a73c3f489ba7b5bfc51d9cafc9fd3b54e5d82fa0006b1f4dfb7ee4bb3059c0f9fb81c6afd5b7703d7e0b54720067d7ff7c62755aa3f0e806c426c5a7238917f89cfda30b80e7633cff6005a5965cf61356f551964a50008ebe7c99a2e83a7515927246ac0accad976a388245acce1f41ab198d37b32dcd72717e17dd7339e04d0b97a89356fa994e5b1a036ec80eb681a9c3472c26dfa1400090e98acccf12cba83b7bb65b88f532afa0f86bc068e1313e186b49e9850650c7c6ebaccc02e627b5d7470ef9035c08cae8d874dc4b371945b289706deac7d9008010aa0f27bcfc63715902446fdf352554ea699e361b8e3dcbc57b840f8b5f7dc745e02847d83317d2029b73d47daca88852f1beb2a49004c1c1e9ef4b501f417dcc6010c724aa60c084bcc159af35a9d58078d667534cb67bcfca5f959e05eb1b0956d4a02ef98abc9ac677b779b1fbd7505b1621b0935d1a58d7373c36b96b99f8cc0fb000d3139b25069520a4bd9c61905e7fd83ce21eb5786b26b1e5b96772e4933a6eb163dd4031a1bed0cc65e39e00d0a000c917b69015696cb1eed816be864b65abfb2000e794260e5d734ae20e53ff34799b2a9a39f0f792371f8f27e70cd5c14a3d781816b7dc8a3da6ba886f2c21b304648c51c16892da6bacd10776182cb65c9c46b0101100efc7a08cb812ab047bd67e624197e8244adc6a1ce0d9ef30c469bb5918606e55e3aca65054e0f46e6e7eca8f20b9c4128791ba04496ae9713c5242883777a67011137416a6f4a919b2b4dfafb55c38669b93d66810ab0c77cd9285c71fe3a3e38a36b18c4fb1f6e0700b89afb8f74f056dd58846fb8d0444c3b405afb7755faa3990012747f08fba62aa374373a5c36b6fb29a36d4e382efb2b0a54b039aeb8f76fc764683b02c529802297429d0fb5320b1e6e5c63acf309e03e0f15f7a1fe74eff30f0000000000fded29f600010000000000000000000000000000000000000000000000000000000000000004338004a37fdcccb2200000000000000000000000000000000000576f726d686f6c6552656c61796572010000001700000000000000000000000027428dd2d3dd32a4d7f7c497eaaa23130d894911
Optimism (24) Standard Relayer,01000000030d006706123794be8c86c236a0416cc1d7730e1a892ae2f5f83cdce8cadf42d61ff10ced17f17d6e2af4cd2689b8e0ebd903cce7f5643e8d8b76f55411129c575365010311e848aaea7323cddfe9d1f45189acf490d3130b9961855aa00c20e7149395a17f133ce44cd4a16078f2f884806d901eb3c56c7fa11a6c628ae659ba602913ea01059d830b8110639295a06447b4f54ed72585a30256bf600b7f0fca48f71b30b74f02a4e64c1f2c4152a2f3b7e8ac28e8029c0f60fe4c92f00f5cff8e5daf2395210006dd08a89b93920292bafca3ab963d171e884cd3bbb9b857bf6f87ab27ad2792150ed5bf038693e6ccb855d2376fc0a4087747fd1154dcc4c20b75df05a758196f010809d6a0821706b2fda0e73c4ddb551981dad9dc1c2c8e85a902195cebd1d8565e528fd078005dfed95fdb92dcad5971ce68f7b5f897f72544a346a073129ac6a700098f24b7e0e5a26410c66b1b1945494d36b9fff6dacf16c5a6a22f01a9ecc021951fd6f992c0ba7ab688b5a90fcd9f96a7fd28bf044a576d58b1a9b85f6964d430000a0323d4671721c0262265a37ff9e3459196ebb928c3568ef4b15f5812ae411f1e4cf9acf02be0f66d380abdcbd1cede4c35483e680a0c330d4fa04551e7b39a63000c4d0e32decb9285203ec763ed6cab15a1fd91fa8bfaf3bfaf449a08e52b79bdb76a10fe2a67974ca57549811cea6b51f39d8abc47b7cd9969e7d6f3b86c3949a6000df8b8844a14ed09439311cf4588760e80ad2a6c460759a85145ded663c503882a367a8ea4727e147822bb6396102d0ce6b90d1e6b87b6ce727d5fdc202b83579f000eea060f748330d8c31e520b8c3b68873e47a6dabe9bd0889dcd7525700b90134b4892bb973ed3aca95343644e5e87b3615409f2a872be97b9a8aaa3566135465000105f7c654722a67c678528e8d6a64a26f5999c70cf33adacd1cfb64d0f8b0c26f81810ba862ac88aafaa90ab5a0669aad2610dd7ad16b1133f4c0dcd4d491a462f0111b698f2fe7cd834d2bdff5d4e2f0289d9631bb910db3e64b91689b7aee09b273679c4cc40da83f0a579a06c756abb9ad9d2ba150a4d18be34c5e88010c46dce6700120ff19d84f49d84cadf0c27f91955b36980271a571c17ac85daf121bb6d0490857cd79a89eb5e1532b74439887ea0f66a5f9ae804ff063b896b24d5014b8e95ff0000000000fded29f600010000000000000000000000000000000000000000000000000000000000000004338004a37fdcccb3200000000000000000000000000000000000576f726d686f6c6552656c61796572010000001800000000000000000000000027428dd2d3dd32a4d7f7c497eaaa23130d894911
Base (30) Standard Relayer,01000000030d00df8b4dd3d24304810ddbf4cf43fc4507b56728f76e6b1d102a6ba646d0c63b2b4148223e19ae06f40ca072fe16333a4c44748bc37457835966c69f35b4d27501010247e8f4a5a1e5a4f858444a50f419a477866f7ad10af94d62251ff5a7f4a42a9215002d6b5a7939224d6221d743a0107792b4a1efd42619732a34c7c2cdc4401100036fb6ef9f9c50657d7791bb344b948d6c812f1b4070381003a942419b174c4fc94cb8d63cec79e13982a2642d789054d0746498807da03d3c59a39efa29232dbf0104bbf027b263137578ea240576f12e3dc1470ceda63391dfeaaf0f71af0adfa764772a206847aa10646aef2ebdba8ca21b6c08088cb58942f2145c5120e0f94b86000674719843c99e12cd2b9b37f98431f8dd8bd2d74b0794291fd8d7b8b575bcc8964ee2c7982fb4932621996d587eb4ff4861e1d0e6d873ee1ee8b9f684f08426250108f33ed961639ec82c1be05528b8a75f6657bcebec68827e8f295899e41423e22205312e5e7bb6453004df0eadbe11eb79588ee16f5b35fc8db2f7dc7d457bfaa20009e439e5b37dacdec25d12cba1531efceb2f130a812d2d99fcb728282bce06dbe91fab11228716ea1d430ae8a08ecc2482e30b439b912b7b0dcc95cc80e98fe6da010a5224519f03cf83b67ed6d31a5495edcf66ac10da2d94bac542109be2d075f7230b63c1576641ad6d9a54b1fbd5fa7fbe3c08cd08f673318476aaf9fcef48c6e5010ba277e69a71938f8b1197cb6975968f7e4780fda8e6136d23d2c9f5cbbb15d2ae682321eb8b5f683c5825b74492e7a2a4d18ac20cd8c30fe3fa712bd71c8b6033010d06fba68375dfdf6d76c97d3a2e0ea1c9b243d8f7a37114406fc67cb7545c717402faf5175907d1ccd943f20d539b815eb936d430fc3dfb35c3316a2342dba38d010e4ca329b5c61f7faa4223595fe3dd4d14d77506c36013c6ce8e34834d48380f75536d12e3a9cef5446a33766a500a676c3d59b09e984e0f31be780bd736a8150b0010788d6362177378258f98c0a1a5a85b229b2316e43b28a08c68e0303fe2bae4a27cf109f07ed6efa6be02379b07b4ba02c9d81c478263eda7a3c279af2d4987fa0112d5b4f5a87674f8c4a686ac67806a45440d30861a43191ec72e5f75a733a8b51c189659e8ed8ff7be73d3a14780a46cb34a58a5308f7381d668e8db58198f185501000000006b45a1a900010000000000000000000000000000000000000000000000000000000000000004555704dcd5046cc4200000000000000000000000000000000000576f726d686f6c6552656c61796572010000001e000000000000000000000000706f82e9bb5b0813501714ab5974216704980e31
Ethereum (2) Standard Relayer,010000000411011cc9ccac1e8e7926f87bba430c7d44bd74f2d894aff5f254ccc38117ea60dcdd5d5fe8764291740cc0b3bf9a933af8b7d5831a4036fd724cb4c4394ce681149a0102798dd4c1f6ed41f190eaeb8243f08678808cccb7e467d69abb83a88414211c032fba01893f5c408e307ceebd74ceae8d6605f5911e682d566cb66dd501e04f570103bb91bf8f33762ee6b07abb3119c4ba748d092bfafe87d360db962d99c96462920abb4e6d076e9d54aeafe8dec563b1930a4305e2b3961cd363bc203be0649f270004a87c289caf311c65374cbb573fb30b489aff09a66d7a09f9a95ec50f05981bca5266c862bc9bbeafd793debd4cf3eac2ee50f010df931bb6877f1090bad5b9b50105245ef83e663fbc6e9cb3f2c9eebbe44eac2f6e5844c13610333d64340c7e4407611f4e11d676e9773502f6ca6c070975297cf6f372dce0875de3f8ba80b48f58010696ea72db18de430b5c071bb09d51d53d03197a33b1df0711b5f859149ddcfc7358c84573a7518b3719b67ec01fa07140dda7241b087807c1d4548c1876559d280107451380b740bb8688e23e7e0875bfe5a44e511c4a581f81db9a8f097290bb42cc16ca0c609356f692ccedf5d8fc40bb12cdf0ed7af252992da2eac282e3de9fd000086fb2063f49bc33d1f25ee13ac31cbb2a0ba540f419df1cd03c91d0aeb8e97d5e6feae3da4362897531428190a8b458c327e256016ab6ac62cc1b1e931225baee01098bfe9db66d5d50eb6177143e8db1b23200c677266f02ac2d1c04b90ee9a1d1b476a9f4f93752555e86a54e2f5bb666866310f8f587356c594218aaf41d20fbce010ab66121eb5bf8f432e1ae32bb988dd7c33d482fe4d63abe1386d38cdddae0c03964d792f2704309bceaae0c1b322e46aa651c6e2a3c2611903cddbc87363bdc75000b443a31980905ef953c262a9521a815c6c676b84b00d3ae2e8783b212785863da7ca89406b27f9343529ca245552b5ddbcff32b84ff42c62bbad28e5cbd2f874d000d4ef0a4d42e2be648eb6bd37d6184c123ab0a31dd804970416972e5be3fbd6a0044d9d2dd64a430cca95110ff36f2f363fa90a0ceb524f229b46caa85f9b18bc4000e0ddb23380953eaba05b8d493f2193860f10079a2ff6ffc00bd11db94e22b5f0e1ab3bf4517972a0aa2d7ed18551231e083e48ccc07e8d64ed20fbb6d57151b82000f39eebea1eec93d3afc71cb9ce966daafc586d47863cdff25a413470d3cd5ee2d55fb1edbddfa5c7fcc9d5834db2f6f82a380e1e5d6da9112d4497ab28d3c385501108a585d5960d95a50f9cd6c8ca4b8ae7a70b4549a052771edff1a0c3a409ea5cd286eae6c53eb280038605384d051e04e8c2c531c0f8713e36a5c4d71a044a40b0011fa3cd95765d64bbdc070008c3111ffaf46ada75e4dc39607c643b547c3f70d423f0f4ee2ae5d7ed4361869896dcb012368a0a9586881c579a877728fd761f53a0112447e5b97e5341c5ff2e91c0aba8b48ca985f369992f00fb17fdc9c0f6576b93c6beaf3a44dfe8972df1f28c4eda7336a7955e6d33a4cc1e1c324ad45de72d56e0000000000fded29f600010000000000000000000000000000000000000000000000000000000000000004338004a37fdccca8200000000000000000000000000000000000576f726d686f6c6552656c61796572010000000200000000000000000000000027428dd2d3dd32a4d7f7c497eaaa23130d894911
BSC (4) Standard Relayer,010000000412017e9b9065c4e951aa2be60cf6245381abbccb02a3ac6b0f4ef3ad4cf5d20653d3523e21898e03fe391eb12b187da849ffe1126d85f4d11f94c428086e67e3680901026da8015f1f571f50d3a53846ac0f1c75edef71e7207f818605a0096083fa3095144fd514006caca2456c0924e44480115702b733bb10b51f7ae742a4980bd72d01030941c73fc173d2f1bfa810a141db2343f3d4ff420c56ff09354b2718b5baa4887922208e9097f19f6607d8b79bfc7ad469d4bacd3f60ae9589fdad238aa1d95301047e8ab11f6a80c2d09eb9717766af25cd68bcf8dd90385395110094ea4bde30393b1ce9caa4ad41cb254462a9ec56f9838b26ebf72f9034e9bd89a6be3c5d318100051da5b430178acfde6091d4cfd836926097be2862e30b96d89d03f9d6b9bc1a8319c814c9186d30a564db790136e24229be6c21a115518fb2e0a7f3f5053771c4010616dbe51c1f120717f6522d72cf85e42315d65dd049fce9e691658d1a0e3d98c865c71d6fc5cf7682991c476bb5ade4048d71e3ce81ba5fa2632dbd17a352260f0107e1725d04e8ae2dd9a418d04c4cda324c1e0ab23d4dc710e7a962231b5daf083c39e2ece6968a26bbf62f88af603b8191d39d0fcd7d66375e49010de37f5c52030108fbd37725bc32e5e9a872f0477be346ed302afd45d9b0e5724347adc0cd142c020f134770727c9d57fffa249980c3687cc98d62196064c30df7a7147f07ce3af60009f6a21b63b3c8c18f96b5ff71256d5ed0f630de90ee65eebdaf6b5916b4d6fdb276d7dfdae5e05ff52a2f77b8801cbcb1fb988c6b4adcddd9aaef2e78847500f1010abc2784590de571f08bf3003ecd50a564303376c0da7a145118153022be444d940238147ca54bf65f2c312389f568ba80b0c547413a8fb527452f09320f23347f000b09cfc420c968ea26f5ca6f4cffaeca802ad7419b7fd62b616d9d677ece38665712367d18c22deeec861ccc97dbb42b862493426639ae7d77f6594a6ec3a4dabb010ce6b17e707f79583df2837cec6cf05f5d3f70b99f04ef6c3a54d55e770f2aca4a78da87446c11bb39ffbaebd324d7b369944049457bbc97256dd7b06a61127263010d42c86ce3294e2cae5304d94aeb30de4c686612d090f41998af8a1473fab4fa605579308201183510ba56602f2dbba3694959e052e0d2ec973f127308517898ba010e113a38c219ebb990c5bf15c9b155bb45bcc773b53dbc2c3fcac866ab00e0f2be61e3962b99e25bbe5fefe2b0af5fde001e35a71e1856b369b5a179d3c0a826b2010ffddb788ef1f70a205d08d44a8d5762c5f5ae5b236eb2534b55e80193c558a6f460bf89a618cf57530ef32102b2e880fb088c062e0bae28f3386dc65cdd58c19c0110ea9e738d883dc8a194c9f180a1123c2496be82678047d6220600657df77b28fd1ec53df79bc47487af116070ed44a58ab86e05030892c2107342dba5f742eb390011759c6d8c25ed3f4a60b7c30473cef12f1652231ee5e2d98efc29ffe3290a6ef37fbee021b0dcddbfbf11104ca1d9451d3ed455816821e2c089538e7d605e0a380012a07c722f449b863d996f15185efa1fb5b056be6d404c8e793492edb5736372f27a9ee67e7b4998e81cee5f45626984d801b81ef7ebc980cde1959a48b1ad57c70000000000fded29f600010000000000000000000000000000000000000000000000000000000000000004338004a37fdccca9200000000000000000000000000000000000576f726d686f6c6552656c61796572010000000400000000000000000000000027428dd2d3dd32a4d7f7c497eaaa23130d894911
Polygon (5) Standard Relayer,01000000041001f100c23d38d57e97e66009b25adc7ebcaf920f5a1f621d5755d331de61c5f21631a6f0c9fbea8ad75534af4947a4df72cc293944b1aafbbcf0727f31e4071b810003f100618c84ff56ea49f563b432bad076350fae7cfcfb3dec92540803d84ea93b5da4c7fa7bd7ec363b9b612dcda7cfec9fbebdbce517dc30903f13c2ec5cb14e01044a5a94e02266383a11d1c63fdf50b2cf4a4c75fbebf158843865377f01a0cc4710e908e5190abbcabcfef294d7a054eee84a9bb0ead041c09d10f7a9cb2077000105ce71d2e594f36caf27e8b769261e59b91e9e57fa16205c6d375074615088917e05130f24f1bf948431bcb025aecbf24dcf286297a3002c37ebe72acb5c2430c601068445c65befad456f1cc427c80b2243b23700c152afc60b298ccf5d24261bd9ee1627bc40aa527bc67de91de14cc0dfb2d99b9ec08d31a7ae3e1acef1ff22acbf00074569b66d9ee98c4f2ac6f5498c721f3bc66fa9bbb0ec5e783ee381f9f06046ad54042a921a3f7367ddb192ce880ed5794272dedf0a34f791ef4370bc07743ef60008991ec96f347b242770e978a6473da8c82b14dcb9a5ccc05dde4bcf1125e3d9481c25f188d07e1e4e68a916cd79ab21f41a5433d779660d15808e6c172c55accd0009425e5f3f71af0a6ebed1bb037590319bad260e2ebd8b889bc64f782e594792a52874c1973cf69b76f20a33317fa8f16e982afc85fe147ba742be1222d942dcf8000acb1b63f1a4f30702e2b883eecc8048ba91b38a09fffed33299b0e5aeabe09f7809fca5f75fc6a4022b902be7caf793a18d1371aecb3d9bf0d7d27640777b2cd7000bad7121a6512bfe27856dcbd5c1aa96ef1fdb6110b322a0750870b96aed6f06a30678ed78b4e7dc8c57a6171aefc1b9ca7e991ac4a47d2655caf38d22858d0cb6000d2c307443c8329b1c9e456334253c604b5d6c1d7f5dcd4406d9d8c4ed138b72f479ff2f412a41474f3d619a41c8bf216898b8e8a17d3cd7275e6929bcc221b848010e79b575b4795c6d3cccaef379c2f533de626df9a87a52389f38fac3f5d77b57aa317aaefa4386aac86638a9e19cd0dcbd92f9f087fed54c9e28cbb7eb7cc75b84010fa8c983e5931d1276f84540c4005a16d53071e7a65013c5a9812c4e213556739b687a483eb19abb3f1cb73db7d6cd924d212d3c261d4f3018e8dd96c99dc8104500108d63f8802b17d2ae03a138c123b06a3be5fbed3d478672dc5009a6b6cdb13dea467ac4dcb16784cccd9ca9459ee98ceeafa0c9f444cdbd3654f034f288a24fe90111bd3e4eb9455c06c3aff08836f55add7b1bc5d389a1a02d02abcd5d54e5c1df1c31796b93b0b0e85320f8036a38513bc48008b4acc0890936bd46165f2589d69400127f69a920ebe11ad7b73eb13a8b2729d7a2972ef6b86ec2d9b2ca5f4e3b8b9cb70195f59e62b715724ed2221e32c4f537858d12506ec4d4cbf566982bf63bfb5a0100000000fded29f600010000000000000000000000000000000000000000000000000000000000000004338004a37fdcccaa200000000000000000000000000000000000576f726d686f6c6552656c61796572010000000500000000000000000000000027428dd2d3dd32a4d7f7c497eaaa23130d894911
Avalanche (6) Standard Relayer,010000000411018a3011f6bab8f816897c708383adf3f5d49be545bb889f4f63133f373c54f02d62237e540224cfc4378bc2e09ff6127a5e2cb8e49bc5d8d96c9d4209ec772bbc0102c09524e6fa41789b556325a4a893546508e5c730ef7f52e4ea7640c381dd476e125708b397751ee2f344b6e123c044ade712f7f83be418c0ced63a2aecae3968010301035d39f88f4d0751269ae4e098bbe47f3591357c1b616b3e34a5c21c4c1f2c6bfd2b19a8078419699405f38d4c30b3d4970c8a7a37729dfc5c319f299883ac01041f645ef4100c53a244d4963a122657e93e8999baa3f6d1ba4f85377fecb9175a31b6e00635e4d06229892e922e79ce817847476e4f3a0be7d83ff59b472610d6000566ec129bfd891f510f4b350743f2ba9c061b0b94d9cc20d0a75c20dd863722d830ad196d3cd9fb5158337e875a7848e8653d50ff7e7e63c41c2995e57e1c0397010604b345098da327b1ce27ee48a6d2bfd26a744090540042dc1d698a458f726b730f39815ab1254cc9b45bf1fb12ca62ea9b5f9f3285974c350fa7e23fe4a9c8bf0107c9f099ea1e931af596d0def924eccb4b2e64fb77b0afca8b112c1b30ab3aa26e765d0ad8ed0128a31c0fc4048f1cdcefcd4c7678c259d06ea7dabbd720fbc8a8000881a52213d65d8fcca6c99cea3b2d134518a451a277a0b92fcf0dba0684fc52c37254b8a2ffb450a1e0777bad5097d907cf5a48c7d70c037b3a362f1973b143d2010928b25ec1394bf9caaf9c95ef074babef722c15b0a4edccedac3fdbd6a6bd87d36ac2fb490e4605eb0d53db3eda85527fe5f00171a5a5a81b283c401ef0369794010ab5470061217ac4b94fcc45fc23292d51c04719493a2785a0caf76eb3497a402e13890bde914f07b680b84079f87bd1448ed8e4f2b1d6a60661986a6f51593d66000ba84a3b14fd2843dfdc408190f1330539d7db5204cada959b82c9a118ff9c633a1c3ff7abf7b2a0bfd7003fec72303a0f39dacd6bb905b2c721bef7f9250b3f1e000d5fa87309ca8cb8ac33c516a3c3ce860c2c69411c4f5abfec0d8ee7f08a917718371fc2e5445d27f9915cfd72396ab0b0f76fdc820f87dedfa6a129a376d39671000e028b814eb1f74fbf10a5fb2c465a254b0002830aad9201555d7f9b5061bf99f41cbeca0fbb2b6dda51fda40dfcf88be08b3c9a9ee1410347a0dff0f70a76fd56000f1cc4a10a0875fad35c42b795c9357be35a67acace09706af13b4009bc72cfc8d3957a2baeb28bbbf0d22256f0896ed0f6fcd098f688b64b53dd111c4cc3c2ac10010fa217241fb64df96812ba7adea8ff477b4c03a76c25ebb3f8bc817afca2a735c7c8d0c57e02ced4c522dc5c5c02758eee91fd3bbf8f69057e93cce6ed177c9d500115cd9c43d6c791a3ad05cea7cfd97f76a1eefa267e134f0d8144b9fc527f93d2e017c44c427670248954d1d119b712412e032ace9f4879b8c36439c100318d0f000127cb2e52609a2ef2838b24744233ba084f76748d2b553abefc70cef8f05eb16731e013081b28eae042ef40f73104ba2b91760e9369168ed91bb98d985edc025f10100000000fded29f600010000000000000000000000000000000000000000000000000000000000000004338004a37fdcccab200000000000000000000000000000000000576f726d686f6c6552656c61796572010000000600000000000000000000000027428dd2d3dd32a4d7f7c497eaaa23130d894911
Fantom (10) Standard Relayer,010000000412015298eba9662833bebf84896d4950977e2b3a798843724b0f94e6cc593104ad0f3da6a81c3cc2a5de08913eb26290c66fa618e6fac82b6ca253c423994d7d17190002477859073938199baa195303f6c2ba8cae0c858f61bf459a833114e84ab2c6762e798b91db2623a67704c58656caea49c7459afc820f910742125fdef6b6cc270103d3cf95aa84035358f41d4b0f5dd0c59c2de8b69af4db84e29b5df51781d4a4437cb885054e625a4ad03324573e033bee6e4169fa7fa169c2fb4a5c4c7e69bee001042e63b87f925d6d9b48f8b6df815593f8cc41d12af45ca58cef567a2dee37236c734a714cf2ef110dced59b0b019b89fc06b16328d4331e905db3934f21874dbf00051f843a340ffd3a605fd84480ef14d8595b1fffdd45a7e1c919c686ac1bd234bb4255d6ff88990e33dbeb751c06ff6ba5c63469fef50fb9924c135a2e81db0f91000678e5e902519def669dc1b03d3c9be4b84589a6322bcdf3c8cb056192a13774487a49709566d0cc68fdd9c6d1f368152f1c0728bba71031a867dbf8a170cf694e0007738f6d2e42d49ab86137f8e0f1c1bc2b2b95b9f0f28f3698afb11ac5024261ae1b41b5d705a29ee77abbd7ac27d237fa4e37ae1b40df56b9a067024c90ca6d860008b25df04e7b4147bd3ae3960fe7f181968c084b63a89ca11c28e557d516e6ac3b623b56e9472041a8ce9fab0be14e9f6593caf203242f5a1a8c00c8a23f947183000919c402479e75615c767de34eb463099fc752c82aa9def7bb5dca812dc5d1a14c268f8c8a4c659be8fae0e51d2f0ed120cccac58344ca9b3df9a9cd21fe1919f9000a7c96e0c21eb74310637c8bccfac24bf91190dfca3a7499bae885a4dec541c58f241933b0d567854b6d8c2fcc284e9077ffab16d6c9c0f9b24cdc2f7875e0a8fc010b0aa4e824c96cab81bcb799c62076cbcc8c88d81dd8760d2999188704fc18251e35936882eb00ed58656432be6f60fbf144bc337d1aeb146e19d80359764f72dd000ccdad41a3722e94317d99ec9542e3aa59ea9cf0297f450edc57c037408bdc5d5770df000375a79ae231aff1eb128c657d0965fe8e4fb5efef26720848b6e68a14010d419a91a2299ba3d983171250bfcda19b462c6cecd6c689ab44cd06d77b3c9bc71f532521b1334308bfed01640ab3c8d212f2e69f349c7697fabcf95f43afdce7010e2238dd50fac23d82778680768dc5cf4ffd02bbb351483dd625e034c9dd0be00a1a2c49f95238a7cfd7ec45038b4478a457e9b9c217fff574b7dd9d5663c65346000feb07dee3c5ec9c0a74f181f76f2356d34adccd09cc889758fb1afbc180ff52ee6a6d6c04afcfb4b92afdbb79eed5f8c7e67c7c90bc9c7cf289887eacad42c9a601100fafc125ed044c06597a7563f22a5ed5071cda2e928bf401a71592af7abd6cf45b114d1d69ab5c784cd4adddbbf51b461e85c41f5792c5e309f86787196f9f560011141a93514e4236da671151dfce33f1fd24dd6e9cc88d16ba2fb8e04c664576b122cf795666f5b5df601b2243382b99852cd23840d91c6fd7dfbb33e27753794a0012880041feece8698f81bb66e9817ffeaa30eb58b5ee4f667a24fb05030fa2ffbc347cfc3f30bd9a18ae8e5e9c01ed40d46459d25e96c486cf849d5f4dbea188480000000000fded29f600010000000000000000000000000000000000000000000000000000000000000004338004a37fdcccac200000000000000000000000000000000000576f726d686f6c6552656c61796572010000000a00000000000000000000000027428dd2d3dd32a4d7f7c497eaaa23130d894911
Klaytn (13) Standard Relayer,01000000041201202b6807f3b8bf18ad8d3097829f84c89430a2c342e71f839bb426b8285aa0bd2cc96c07baf96a4e72c90d4c00e402847482d2bd1829e8fe6ce70a9cd2a2583301028e48df820ca4eab9737aa1d5efe784d061e11062944b5035f9c24500e644b1b747752dcdb2d58dd9ffb4b08db098121c884897df42b704fc9914f79e11072fde0103a73bdd6b228644bdc483bc8910c39f120b83c315c33764c308d9f73bc2b30c4f26ce6b93e3de1cceab441db14445318075bde8e15e9aa77fa6c311e40bdc0680000426c3fe6bd835c32b64c567d246b7efe5b4b76319beb8bdc8e02583d921dca6105ed671393ab77a71aa0bae34cc3873a747eac3baf004b2e77a571220d3329b0301053e88ee079e28c6ebd2cdd47cee327b7ba9cd985c5b01352efc25689ebeca85844f7bc66da3266dbe5d5bba69ce0f3c217e87a051fb2de74c253c1193e52b171c01064a46327c3abc0f34caa2cef14341903e14a3b84e67d594f45d0105e2e3b4ebac3793967c20da12aa3f38101fae3f071fe870fbe574657c021949d3df3003a6a70107e61150b95b83e7d8a86f817751fd75e9c8b1c3819cedce83ffe95b656f2a46605aad1a5d78ebb394ede8fd56df0caea9ca865de55205caa35e85b63f60a5fa4801082d5c3b48bd744256c9eeab8845402e5a937481c8ae1fc525da22c9987953e3467e19a6a31c66ba8bff7dcd24d7d23b02d44c79a09da9efacb5d9be8f0dce269d0109bc3c217eb4557cbd5b486ce13e577322808eddad286ff56f8c6403de7217a32a102e634be26acadd332b24a05a04068f823a74a6a41c4e2f91ab23f6217d8ac8010a823b3773e8a5c222bf5a28b95d2ebaa992ba4f8522337e8d2aba19bbe1ad72b4222e6a86a97e346ca937464098bf5f649f5f7e6e18e71d5b4aabdc0c19bb5130000bf67da3d9002c91e9aa913687980a22692ce1ade3995eaad46525928990bef07f0e87ef7709fc2fa77437978b105cc7be084f134ff992f69002f4165e0a60cbfa010cc6d232cfefef4ec108fbef959aa294074eacb83b6c7a8fe5f6b3e76b6d4b3c4679e1e6acb3186651d7fe984c1fa895c4afbb421b18074f917e3224b684d9006e000dd4936f7cbe9cbc64a98a654d4673e66dde3a5ccd52f8f3e16fa69c01f1e63b80362aa8f70c771b04a080bf847b5015914e189c9053e659c996dfb4e1275bd4ea000e8ab19b52ecc453b221bd23b3b437243da76ac0ad88e49e71baeaae300654d8344687f7cb1d69df24426e3d18e90ba39c1267c63725712ab125749642f8742c53010f0e201b577e11fa0c0f85642a40352951615226295e7c9ad18218e00d3994d31d67632a6bd6445a6ba2eb02172c09ff293e4f06ba8498a9e360281de535cbd0760110ab99b0e5b37c20f786b296923131c5df829498559e46f1e5c2971fed93ceab1700a61354b60fb640e369755a9978bc57df01a55391cb5fc7400c6caed0121a890111c844b51223b2fe13448366c8cd00edc91e688ec419aeec97bd41ae9776f317f1770c1742825c3cc1bde2c0f8928edc24874abf23d94d3d12f121b661d313913b0012f46057fb23e8b994dfd0168f8dce2f661ee24fb9ffa0be22a8b0ab4424f3ffc6567d9e5c124d2dcee0d3dae8eb786f0c1d4b38fa857e17310bd25e4092c371c20000000000fded29f600010000000000000000000000000000000000000000000000000000000000000004338004a37fdcccaf200000000000000000000000000000000000576f726d686f6c6552656c61796572010000000d00000000000000000000000027428dd2d3dd32a4d7f7c497eaaa23130d894911
Celo (14) Standard Relayer,0100000004120121285f733587727520973bf05a22418d34f6b5aa27504c4053d5ee5ce23a02c31153495f3c533ca16f71107af7a54b88bb8fc7d64d20206ed0eb26ffc6cfe5a70002d17c60f1fa5a84d2ae69fba2cf46edd03e3283ae74991abaaaa017ddb3d9fb4e239a82eebe14e89f794ca32a421f2516d9fe57c97133f20bd4a34da78a50102e00032085d87ad27eaa019d14cdeeea575f926ec1db44180cb1932b6ff54b56f0a9d73bab0e952fabcba8135fad9f187db120ea6fdf260cfb3869d973d3eb725c457a0104c7af4c135eee9cfb346bb97350f4c0ca5832cc36485d3fa11603f05d42cf9c9f65e4518bc5483dbde664518abc30d2e4741d18649689fb5c9f47dc288a22b1c101050c37eebf1a94032b3fb7f53ffabeee25610a804c7f58c7ab7e82b8d103adbe1f3af1ae9967f1045c040aa5f3a4c8e4d8d5a3802ca826483e9a1a15f8e42399050106f88d72d019b83cb9b10309c8146e19769da72bb59a26369249fe39b51d475d570e57f5e19cd864af9835c4809b2668afb6690b24f271d37d9caf7089402a67140107ad463df69a2591bbb892fdd1b28009802ce29b3d8c98c58248178c927ef514245e2c4d99968a30bf642e750d5345aeb85bcc2f23fca01e0cbeff8e2b3be32a930108e7ec94efd6c6c06e792c3a7e8885bf305cd652a76876d49697c99ddfc9a98b786bc215521a03151718cd81fc4619c72ffeeb29e6cd968dab9d512f7d2d0eba8800095b6f138e529675fe335e5a72f6bc1a35d20cf518786519c24ab014ceef61eb7133adcb701a7f75ccbacc12ab5e74dbc7c083ea8318d0eede51f486292c901e74010a538c2fbf35b4630f13e694da19fd3e2fa57438622af490fd3bb19a620f88be3678b5d6408c7177575d04a6559bc0bd19538f93e6dd5288d9931511ab8c512d31000b4b193a05edc48b51eeaa302473168dba70821a22541a0ef2cfad161b2aa3bc82066a56f9f0f222116f2904701b05201d619fb3f486fefd08876c7a5bebd67c09000c6563e95259a53f854c5441759804111e52ce42e5332df7ca601cb14091d3c6d81a37ffb91829cafc053e14af24a59ffcabc3fd774e1399901154d52d634057fa000dd639c68822ed4f29afbdfe349fb31cc367b065f5a3bfb73587e0aaf8dd0ad5161be5fd99d78628a7bdfa8c07ffaa47d6c4b58e6b470dabecfbe95db39a96496a010eb85a203b18444f5d26beac38279081d618a50a77f0fcb7d7ff3f51fb2705d9a167bf7c7a2506dc4ac90b946ee63d8a9ea6bfad8aa8494f99f2af5d15d190801b010fc87ba5e8a9caff6cfd7e83376dfd97a6840906ebec31e299d2fd0940f936061d605b244bf2427cb36114d39cff7fba122d6baa6d6207257d42e4fa43473f0887001018d5a390d01b98d9762222d97d3cb988573f256a7a3d512bb26db78f2e1284be020a6d5a9660a869dceba199308db403e0708c785e1c2715821f69a091f39d8b01110767d6f4f27f9db7ae9e4256b9a857e78571e92197cbc8218551da332fb4110e07dfcc73438b8473b91f3a93a4bd96be9dbaff86b524eb8dc1639da33f1f79a00012b00387cd213e2e6ec3973bd90d98eb4c500c9c6aa893cb1d607d9842a326b6e75a5644785dd5ff7c2eef012e938b6df215ed4e97b8223c078fc8a8dba92787770100000000fded29f600010000000000000000000000000000000000000000000000000000000000000004338004a37fdcccb0200000000000000000000000000000000000576f726d686f6c6552656c61796572010000000e00000000000000000000000027428dd2d3dd32a4d7f7c497eaaa23130d894911
Moonbeam (16) Standard Relayer,0100000004120179716c0fb88b8859d07f660f1732af0f8e239dc21a69958235d1dbef7572588c6ad3669b231555bfae49e6a81dc27160026b1a86f2ec813a650967741475b9a2010211fa62ed1fb2e4ac5762da890ae39f0542522987555ce69ce8336a189f138f7100ff0999d9cc68dbcb74078e8b2e64e32513414dadf6873018a5e0245795acc70003aea201f953a34c7b5cbbccbec6c42d474107efa3c1f5f25137f0f7f1f8f3446f53fbf9b1d475f396cd04878e0bf9ef58014beec38c3fb698d38602fbdfb5f18b0104e355004e39c7042982a07a50d0e7995180f3336f6c72fe0edb17f1d0acefb13302799ad1b84d4bd4d5f11b2633a02b3ad7f955cd30387ba46d20546dc109ac010105fb93126334289857302eaf327690a0d8457098fac094a6817b49f38841c385295998dfc8d50071f296053d8fc472685fee36dd8990c8230f3e276e1b873a75be0006241945f86c1abef3ee1286b1422c92bafed7b38c3daec22ba602526675b4d35e1938ab844b416b6a803bde5b12648d66e9bae68e34dc87450a69a64bbd2034ba000728253f463ea16bf1c509575955a47d2a88020fec9db1f5e779a66875be054176795bdad1c04ba3b7ca6aee98d2fd05cacb06aeef0d6bf693c59f14da5d60c0df01084ee90ad3baa0ee4ccb987f686246958634fd8834790f8b664f8ff60bf1d83e25636b9e9ccf6323234cdbd8e52c138c98f85d4ad2c40a15b136520adcf36180010109a76104932e8c3a7336ca6cdd33b1b69cbf750eb724e368fae15334ec880921963c9f5e317de2b6d7bfc634c1cf6d26567662dbe90a0f78989c2e09d8671ee004000a4b57433c1f5608e4c0e78fbb597271bdb79060a01126d555db0a00e4160e2a0e6194e6a2c815109b3ca69b14b8995fb8b5123c11e769b65865c0c48d547c15b0000b76add1069fd8d6ac522acec5153b0aefcad592d9e7a5fcaa8b0b1c42306fb18e746cf5eedb4e9279f4021aa0c6e189447d4e1d6529fdabe5659ed348a98dc64c010c7be055a164a254ef1a8d423fb8a740f365e384dbfb1df6279ec1aa2f8e8ec33f5359e3dbc50ed0b6a6f81cc28a8df550e0b22f4039197c939fb08bf9af6207a2000dffa23f41b9167fbbcbff97425f015f62d68d4f469f0973bdecb8fab41a44c1f131ac820ee22318ea239a7455e1611c77aa7d26783aa1a11203b72f447519520c010e3ef1157fe2d4df059a0d4d3796783bcd9acbd30b9ba81273841a6f82c56b710417dbe60447e5c1bc362bdae2eb15cdcf2af4d0b76577b1b13925e0ab105b4334000f9a5bab2b554ce1cbb63d47a3be885fde9b7d5afc82ef3abc6341b79f182de5b65170b70ef3b015ea5f18aea87546f1abbb35f8fb6a2748d1e6f5bf55907d03fa0010443e60d8ca17b58f77996ddac9525cfaeaf5092ebea04f13fdf0aab8204bbaa23c04b1987b95836d36d706597b2439acddd2539d9f6c0bbeea970de801f9eaa500114a111aeaf1f695515f01fb174e606835292a99a2d953db84753369b7f6aec89a4e9e12db15b76a880b92983f28937e8e2569bd3a7eeddfe710c8fc4fce011ed80112433a42154cbdb6f1b1bdbccff6fdcb90e8b174540e63825af039b8fc43c1bd6211c1cb4849d6ca8cb2aaefedc684717faebe50b111a44f8224debf9aa0bbe5b00100000000fded29f600010000000000000000000000000000000000000000000000000000000000000004338004a37fdcccb1200000000000000000000000000000000000576f726d686f6c6552656c61796572010000001000000000000000000000000027428dd2d3dd32a4d7f7c497eaaa23130d894911
Arbitrum (23) Standard Relayer,010000000412010ec78f0da9032eda3bf39f793f612a1f91a40ba7b2791726b5d78b8669d63c2d53ced3e8daf9ad7c7a9eed68b9e4fc7c418403c0e76bade1cefa5d08e9ded7a60102254161d961c9f8e4f84cb48c12e45cb40dddd43a3c7215c480e3d295d7018e5163cf27ad2d53f692eaf5461fe60ff0b0edd33e6989f313df802ed5ffa0a664780003d60b1a8ec2b4ce27e2b7298bb3cb503008b945480d537546dba2a0b1afdc80e26bc0b07d9ee4f3ef40048e25d72d23de26d22dbbc7c23df6eef0367111ea466d0004990843481a1f07312418d822eb817d24ca80d7a53464af9b1f4bf81772dca47e33eb46dd579703c4ae31fb9164e5508f474b4055aa703b0a7c8eebe6f60be04b00053542fa8dba6b62072372bf92ef566f1ade2a95f7abe97692d20bec89c9ad220e49718ebccd0697ca592458d79a73c3f489ba7b5bfc51d9cafc9fd3b54e5d82fa0006b1f4dfb7ee4bb3059c0f9fb81c6afd5b7703d7e0b54720067d7ff7c62755aa3f0e806c426c5a7238917f89cfda30b80e7633cff6005a5965cf61356f551964a500075883d0f908800f54a9feb4211810e14a0a0d65827c051f3793d1511048deef8b7b687003455f2ff07a3395f1297936de1785fea7568fdb62d347ef1b6a1502d30108ebe7c99a2e83a7515927246ac0accad976a388245acce1f41ab198d37b32dcd72717e17dd7339e04d0b97a89356fa994e5b1a036ec80eb681a9c3472c26dfa1400090e98acccf12cba83b7bb65b88f532afa0f86bc068e1313e186b49e9850650c7c6ebaccc02e627b5d7470ef9035c08cae8d874dc4b371945b289706deac7d9008010aa0f27bcfc63715902446fdf352554ea699e361b8e3dcbc57b840f8b5f7dc745e02847d83317d2029b73d47daca88852f1beb2a49004c1c1e9ef4b501f417dcc6010b08ca6babf828e69e3b5fdd0db9c34dca35ff6fd2a2bb261a01216abfd31cb95239af719cf2ba294a2c1b45dfd3d901f68bca3a44d1cc71a180ec6ddc6172282f010c724aa60c084bcc159af35a9d58078d667534cb67bcfca5f959e05eb1b0956d4a02ef98abc9ac677b779b1fbd7505b1621b0935d1a58d7373c36b96b99f8cc0fb000d3139b25069520a4bd9c61905e7fd83ce21eb5786b26b1e5b96772e4933a6eb163dd4031a1bed0cc65e39e00d0a000c917b69015696cb1eed816be864b65abfb2000e794260e5d734ae20e53ff34799b2a9a39f0f792371f8f27e70cd5c14a3d781816b7dc8a3da6ba886f2c21b304648c51c16892da6bacd10776182cb65c9c46b01010ff9bd86279193140979c846052ba99d6f9e8411da7f7004a8e02728579f2283a9510c090466ef71922a58184b5be558a790866125bd76211f308aaa70f080becb00100efc7a08cb812ab047bd67e624197e8244adc6a1ce0d9ef30c469bb5918606e55e3aca65054e0f46e6e7eca8f20b9c4128791ba04496ae9713c5242883777a67011137416a6f4a919b2b4dfafb55c38669b93d66810ab0c77cd9285c71fe3a3e38a36b18c4fb1f6e0700b89afb8f74f056dd58846fb8d0444c3b405afb7755faa3990012747f08fba62aa374373a5c36b6fb29a36d4e382efb2b0a54b039aeb8f76fc764683b02c529802297429d0fb5320b1e6e5c63acf309e03e0f15f7a1fe74eff30f0000000000fded29f600010000000000000000000000000000000000000000000000000000000000000004338004a37fdcccb2200000000000000000000000000000000000576f726d686f6c6552656c61796572010000001700000000000000000000000027428dd2d3dd32a4d7f7c497eaaa23130d894911
Optimism (24) Standard Relayer,0100000004110188474b81330c0fa2db74ea40139146de4c3f62fa3eb23df25125a26142845d011de1aa9d844605a8d113bd1142e45434f1690812686d7161aade3588e94ac698010311e848aaea7323cddfe9d1f45189acf490d3130b9961855aa00c20e7149395a17f133ce44cd4a16078f2f884806d901eb3c56c7fa11a6c628ae659ba602913ea01046a87b3416c3569a2c41fcab24fff66b07701a5fd6df72a3e6d044398054e048742febab5b5f8903703c6c73ea32902dc94c7ee1c4f31dcfb04c52e0f27d93b2100059d830b8110639295a06447b4f54ed72585a30256bf600b7f0fca48f71b30b74f02a4e64c1f2c4152a2f3b7e8ac28e8029c0f60fe4c92f00f5cff8e5daf2395210006dd08a89b93920292bafca3ab963d171e884cd3bbb9b857bf6f87ab27ad2792150ed5bf038693e6ccb855d2376fc0a4087747fd1154dcc4c20b75df05a758196f010771a162500b2783c74223ab5d28e04f1269e49254630a440bb9f0eacd8b59586f01adf5ecbc7c9abe0bd83235a813b41026b19f571e0af31bbf799fc54e54bd3f010809d6a0821706b2fda0e73c4ddb551981dad9dc1c2c8e85a902195cebd1d8565e528fd078005dfed95fdb92dcad5971ce68f7b5f897f72544a346a073129ac6a700098f24b7e0e5a26410c66b1b1945494d36b9fff6dacf16c5a6a22f01a9ecc021951fd6f992c0ba7ab688b5a90fcd9f96a7fd28bf044a576d58b1a9b85f6964d430000a0323d4671721c0262265a37ff9e3459196ebb928c3568ef4b15f5812ae411f1e4cf9acf02be0f66d380abdcbd1cede4c35483e680a0c330d4fa04551e7b39a63000bd03df44627e6cc431261553953511106c1d451b12cf50c977e0280117a75067340a671de2b755cc23dd6097e5f7f922bc2cbc2b78c499256e04ec75e8f6bcc3e000c4d0e32decb9285203ec763ed6cab15a1fd91fa8bfaf3bfaf449a08e52b79bdb76a10fe2a67974ca57549811cea6b51f39d8abc47b7cd9969e7d6f3b86c3949a6000df8b8844a14ed09439311cf4588760e80ad2a6c460759a85145ded663c503882a367a8ea4727e147822bb6396102d0ce6b90d1e6b87b6ce727d5fdc202b83579f000eea060f748330d8c31e520b8c3b68873e47a6dabe9bd0889dcd7525700b90134b4892bb973ed3aca95343644e5e87b3615409f2a872be97b9a8aaa35661354650000fd64d914031f191e0d748817eb8f682daf8157c46c101d65edb6cda8a23bcc13d10118200042b3335834a02e0c265422d2cffe6ad430d16b12016aa82266f92e001105f7c654722a67c678528e8d6a64a26f5999c70cf33adacd1cfb64d0f8b0c26f81810ba862ac88aafaa90ab5a0669aad2610dd7ad16b1133f4c0dcd4d491a462f0111b698f2fe7cd834d2bdff5d4e2f0289d9631bb910db3e64b91689b7aee09b273679c4cc40da83f0a579a06c756abb9ad9d2ba150a4d18be34c5e88010c46dce6700120ff19d84f49d84cadf0c27f91955b36980271a571c17ac85daf121bb6d0490857cd79a89eb5e1532b74439887ea0f66a5f9ae804ff063b896b24d5014b8e95ff0000000000fded29f600010000000000000000000000000000000000000000000000000000000000000004338004a37fdcccb3200000000000000000000000000000000000576f726d686f6c6552656c61796572010000001800000000000000000000000027428dd2d3dd32a4d7f7c497eaaa23130d894911
Base (30) Standard Relayer,01000000040f0247e8f4a5a1e5a4f858444a50f419a477866f7ad10af94d62251ff5a7f4a42a9215002d6b5a7939224d6221d743a0107792b4a1efd42619732a34c7c2cdc4401100036fb6ef9f9c50657d7791bb344b948d6c812f1b4070381003a942419b174c4fc94cb8d63cec79e13982a2642d789054d0746498807da03d3c59a39efa29232dbf0104bbf027b263137578ea240576f12e3dc1470ceda63391dfeaaf0f71af0adfa764772a206847aa10646aef2ebdba8ca21b6c08088cb58942f2145c5120e0f94b86000674719843c99e12cd2b9b37f98431f8dd8bd2d74b0794291fd8d7b8b575bcc8964ee2c7982fb4932621996d587eb4ff4861e1d0e6d873ee1ee8b9f684f084262501071243774552bd7af6f1325b86965546b960955e2c594b225ab2df51bd58b7ec5331f17d71b00298536281977290ed6d5d1534cc6693137988aba25c19be3295020008f33ed961639ec82c1be05528b8a75f6657bcebec68827e8f295899e41423e22205312e5e7bb6453004df0eadbe11eb79588ee16f5b35fc8db2f7dc7d457bfaa20009e439e5b37dacdec25d12cba1531efceb2f130a812d2d99fcb728282bce06dbe91fab11228716ea1d430ae8a08ecc2482e30b439b912b7b0dcc95cc80e98fe6da010a5224519f03cf83b67ed6d31a5495edcf66ac10da2d94bac542109be2d075f7230b63c1576641ad6d9a54b1fbd5fa7fbe3c08cd08f673318476aaf9fcef48c6e5010ba277e69a71938f8b1197cb6975968f7e4780fda8e6136d23d2c9f5cbbb15d2ae682321eb8b5f683c5825b74492e7a2a4d18ac20cd8c30fe3fa712bd71c8b6033010d06fba68375dfdf6d76c97d3a2e0ea1c9b243d8f7a37114406fc67cb7545c717402faf5175907d1ccd943f20d539b815eb936d430fc3dfb35c3316a2342dba38d010e4ca329b5c61f7faa4223595fe3dd4d14d77506c36013c6ce8e34834d48380f75536d12e3a9cef5446a33766a500a676c3d59b09e984e0f31be780bd736a8150b000f151a6b2de331631ccdda12cf215868b93b12d6bca992832ce5531d2c57b290b72c323c3bff1150f1606e738a0c5165aefff6489d8d1c6194566ca91fdc882bf30010788d6362177378258f98c0a1a5a85b229b2316e43b28a08c68e0303fe2bae4a27cf109f07ed6efa6be02379b07b4ba02c9d81c478263eda7a3c279af2d4987fa01119031dcaf73436185f8853ae273ba23e44f8fbb6ed31b750684ffe45dac34f11813c37916f0bd6c7282b1caf49206e6df9004e0450010f9f93c9e0e20107c235f0012d5b4f5a87674f8c4a686ac67806a45440d30861a43191ec72e5f75a733a8b51c189659e8ed8ff7be73d3a14780a46cb34a58a5308f7381d668e8db58198f185501000000006b45a1a900010000000000000000000000000000000000000000000000000000000000000004555704dcd5046cc4200000000000000000000000000000000000576f726d686f6c6552656c61796572010000001e000000000000000000000000706f82e9bb5b0813501714ab5974216704980e31

1 Ethereum (2) Standard Relayer 01000000030d003f39e29280cb340fdea6e91de35155ce11fac49da591cf7efd61f12f4d3f46663d7c4575ec830c35c1cc19017a79e28eedc1d10fcfff4595b1dbbfc9047d55990103bb91bf8f33762ee6b07abb3119c4ba748d092bfafe87d360db962d99c96462920abb4e6d076e9d54aeafe8dec563b1930a4305e2b3961cd363bc203be0649f270005245ef83e663fbc6e9cb3f2c9eebbe44eac2f6e5844c13610333d64340c7e4407611f4e11d676e9773502f6ca6c070975297cf6f372dce0875de3f8ba80b48f58010696ea72db18de430b5c071bb09d51d53d03197a33b1df0711b5f859149ddcfc7358c84573a7518b3719b67ec01fa07140dda7241b087807c1d4548c1876559d2801086fb2063f49bc33d1f25ee13ac31cbb2a0ba540f419df1cd03c91d0aeb8e97d5e6feae3da4362897531428190a8b458c327e256016ab6ac62cc1b1e931225baee01098bfe9db66d5d50eb6177143e8db1b23200c677266f02ac2d1c04b90ee9a1d1b476a9f4f93752555e86a54e2f5bb666866310f8f587356c594218aaf41d20fbce010ab66121eb5bf8f432e1ae32bb988dd7c33d482fe4d63abe1386d38cdddae0c03964d792f2704309bceaae0c1b322e46aa651c6e2a3c2611903cddbc87363bdc75000cb22b8172a90abf14aaee5a80bb97380275798e1f89479be50b54b4549e2fcbbf285af8ed730998caa93612dac4e80eff36ea82e945672e46128d7abe12c1936a000d4ef0a4d42e2be648eb6bd37d6184c123ab0a31dd804970416972e5be3fbd6a0044d9d2dd64a430cca95110ff36f2f363fa90a0ceb524f229b46caa85f9b18bc4000e0ddb23380953eaba05b8d493f2193860f10079a2ff6ffc00bd11db94e22b5f0e1ab3bf4517972a0aa2d7ed18551231e083e48ccc07e8d64ed20fbb6d57151b8200108a585d5960d95a50f9cd6c8ca4b8ae7a70b4549a052771edff1a0c3a409ea5cd286eae6c53eb280038605384d051e04e8c2c531c0f8713e36a5c4d71a044a40b0011fa3cd95765d64bbdc070008c3111ffaf46ada75e4dc39607c643b547c3f70d423f0f4ee2ae5d7ed4361869896dcb012368a0a9586881c579a877728fd761f53a0112447e5b97e5341c5ff2e91c0aba8b48ca985f369992f00fb17fdc9c0f6576b93c6beaf3a44dfe8972df1f28c4eda7336a7955e6d33a4cc1e1c324ad45de72d56e0000000000fded29f600010000000000000000000000000000000000000000000000000000000000000004338004a37fdccca8200000000000000000000000000000000000576f726d686f6c6552656c61796572010000000200000000000000000000000027428dd2d3dd32a4d7f7c497eaaa23130d894911 010000000411011cc9ccac1e8e7926f87bba430c7d44bd74f2d894aff5f254ccc38117ea60dcdd5d5fe8764291740cc0b3bf9a933af8b7d5831a4036fd724cb4c4394ce681149a0102798dd4c1f6ed41f190eaeb8243f08678808cccb7e467d69abb83a88414211c032fba01893f5c408e307ceebd74ceae8d6605f5911e682d566cb66dd501e04f570103bb91bf8f33762ee6b07abb3119c4ba748d092bfafe87d360db962d99c96462920abb4e6d076e9d54aeafe8dec563b1930a4305e2b3961cd363bc203be0649f270004a87c289caf311c65374cbb573fb30b489aff09a66d7a09f9a95ec50f05981bca5266c862bc9bbeafd793debd4cf3eac2ee50f010df931bb6877f1090bad5b9b50105245ef83e663fbc6e9cb3f2c9eebbe44eac2f6e5844c13610333d64340c7e4407611f4e11d676e9773502f6ca6c070975297cf6f372dce0875de3f8ba80b48f58010696ea72db18de430b5c071bb09d51d53d03197a33b1df0711b5f859149ddcfc7358c84573a7518b3719b67ec01fa07140dda7241b087807c1d4548c1876559d280107451380b740bb8688e23e7e0875bfe5a44e511c4a581f81db9a8f097290bb42cc16ca0c609356f692ccedf5d8fc40bb12cdf0ed7af252992da2eac282e3de9fd000086fb2063f49bc33d1f25ee13ac31cbb2a0ba540f419df1cd03c91d0aeb8e97d5e6feae3da4362897531428190a8b458c327e256016ab6ac62cc1b1e931225baee01098bfe9db66d5d50eb6177143e8db1b23200c677266f02ac2d1c04b90ee9a1d1b476a9f4f93752555e86a54e2f5bb666866310f8f587356c594218aaf41d20fbce010ab66121eb5bf8f432e1ae32bb988dd7c33d482fe4d63abe1386d38cdddae0c03964d792f2704309bceaae0c1b322e46aa651c6e2a3c2611903cddbc87363bdc75000b443a31980905ef953c262a9521a815c6c676b84b00d3ae2e8783b212785863da7ca89406b27f9343529ca245552b5ddbcff32b84ff42c62bbad28e5cbd2f874d000d4ef0a4d42e2be648eb6bd37d6184c123ab0a31dd804970416972e5be3fbd6a0044d9d2dd64a430cca95110ff36f2f363fa90a0ceb524f229b46caa85f9b18bc4000e0ddb23380953eaba05b8d493f2193860f10079a2ff6ffc00bd11db94e22b5f0e1ab3bf4517972a0aa2d7ed18551231e083e48ccc07e8d64ed20fbb6d57151b82000f39eebea1eec93d3afc71cb9ce966daafc586d47863cdff25a413470d3cd5ee2d55fb1edbddfa5c7fcc9d5834db2f6f82a380e1e5d6da9112d4497ab28d3c385501108a585d5960d95a50f9cd6c8ca4b8ae7a70b4549a052771edff1a0c3a409ea5cd286eae6c53eb280038605384d051e04e8c2c531c0f8713e36a5c4d71a044a40b0011fa3cd95765d64bbdc070008c3111ffaf46ada75e4dc39607c643b547c3f70d423f0f4ee2ae5d7ed4361869896dcb012368a0a9586881c579a877728fd761f53a0112447e5b97e5341c5ff2e91c0aba8b48ca985f369992f00fb17fdc9c0f6576b93c6beaf3a44dfe8972df1f28c4eda7336a7955e6d33a4cc1e1c324ad45de72d56e0000000000fded29f600010000000000000000000000000000000000000000000000000000000000000004338004a37fdccca8200000000000000000000000000000000000576f726d686f6c6552656c61796572010000000200000000000000000000000027428dd2d3dd32a4d7f7c497eaaa23130d894911
2 BSC (4) Standard Relayer 01000000030d002e0a85cefc9dc34ead9571b45e9a296c58d8c43c4272ef5e50c8d1d0367e828a37bc44055960b5542ec79b5081c2de229ae7a5555d409235792e3cdfac3d495201030941c73fc173d2f1bfa810a141db2343f3d4ff420c56ff09354b2718b5baa4887922208e9097f19f6607d8b79bfc7ad469d4bacd3f60ae9589fdad238aa1d95301051da5b430178acfde6091d4cfd836926097be2862e30b96d89d03f9d6b9bc1a8319c814c9186d30a564db790136e24229be6c21a115518fb2e0a7f3f5053771c4010616dbe51c1f120717f6522d72cf85e42315d65dd049fce9e691658d1a0e3d98c865c71d6fc5cf7682991c476bb5ade4048d71e3ce81ba5fa2632dbd17a352260f0108fbd37725bc32e5e9a872f0477be346ed302afd45d9b0e5724347adc0cd142c020f134770727c9d57fffa249980c3687cc98d62196064c30df7a7147f07ce3af60009f6a21b63b3c8c18f96b5ff71256d5ed0f630de90ee65eebdaf6b5916b4d6fdb276d7dfdae5e05ff52a2f77b8801cbcb1fb988c6b4adcddd9aaef2e78847500f1010abc2784590de571f08bf3003ecd50a564303376c0da7a145118153022be444d940238147ca54bf65f2c312389f568ba80b0c547413a8fb527452f09320f23347f000ce6b17e707f79583df2837cec6cf05f5d3f70b99f04ef6c3a54d55e770f2aca4a78da87446c11bb39ffbaebd324d7b369944049457bbc97256dd7b06a61127263010d42c86ce3294e2cae5304d94aeb30de4c686612d090f41998af8a1473fab4fa605579308201183510ba56602f2dbba3694959e052e0d2ec973f127308517898ba010e113a38c219ebb990c5bf15c9b155bb45bcc773b53dbc2c3fcac866ab00e0f2be61e3962b99e25bbe5fefe2b0af5fde001e35a71e1856b369b5a179d3c0a826b20110ea9e738d883dc8a194c9f180a1123c2496be82678047d6220600657df77b28fd1ec53df79bc47487af116070ed44a58ab86e05030892c2107342dba5f742eb390011759c6d8c25ed3f4a60b7c30473cef12f1652231ee5e2d98efc29ffe3290a6ef37fbee021b0dcddbfbf11104ca1d9451d3ed455816821e2c089538e7d605e0a380012a07c722f449b863d996f15185efa1fb5b056be6d404c8e793492edb5736372f27a9ee67e7b4998e81cee5f45626984d801b81ef7ebc980cde1959a48b1ad57c70000000000fded29f600010000000000000000000000000000000000000000000000000000000000000004338004a37fdccca9200000000000000000000000000000000000576f726d686f6c6552656c61796572010000000400000000000000000000000027428dd2d3dd32a4d7f7c497eaaa23130d894911 010000000412017e9b9065c4e951aa2be60cf6245381abbccb02a3ac6b0f4ef3ad4cf5d20653d3523e21898e03fe391eb12b187da849ffe1126d85f4d11f94c428086e67e3680901026da8015f1f571f50d3a53846ac0f1c75edef71e7207f818605a0096083fa3095144fd514006caca2456c0924e44480115702b733bb10b51f7ae742a4980bd72d01030941c73fc173d2f1bfa810a141db2343f3d4ff420c56ff09354b2718b5baa4887922208e9097f19f6607d8b79bfc7ad469d4bacd3f60ae9589fdad238aa1d95301047e8ab11f6a80c2d09eb9717766af25cd68bcf8dd90385395110094ea4bde30393b1ce9caa4ad41cb254462a9ec56f9838b26ebf72f9034e9bd89a6be3c5d318100051da5b430178acfde6091d4cfd836926097be2862e30b96d89d03f9d6b9bc1a8319c814c9186d30a564db790136e24229be6c21a115518fb2e0a7f3f5053771c4010616dbe51c1f120717f6522d72cf85e42315d65dd049fce9e691658d1a0e3d98c865c71d6fc5cf7682991c476bb5ade4048d71e3ce81ba5fa2632dbd17a352260f0107e1725d04e8ae2dd9a418d04c4cda324c1e0ab23d4dc710e7a962231b5daf083c39e2ece6968a26bbf62f88af603b8191d39d0fcd7d66375e49010de37f5c52030108fbd37725bc32e5e9a872f0477be346ed302afd45d9b0e5724347adc0cd142c020f134770727c9d57fffa249980c3687cc98d62196064c30df7a7147f07ce3af60009f6a21b63b3c8c18f96b5ff71256d5ed0f630de90ee65eebdaf6b5916b4d6fdb276d7dfdae5e05ff52a2f77b8801cbcb1fb988c6b4adcddd9aaef2e78847500f1010abc2784590de571f08bf3003ecd50a564303376c0da7a145118153022be444d940238147ca54bf65f2c312389f568ba80b0c547413a8fb527452f09320f23347f000b09cfc420c968ea26f5ca6f4cffaeca802ad7419b7fd62b616d9d677ece38665712367d18c22deeec861ccc97dbb42b862493426639ae7d77f6594a6ec3a4dabb010ce6b17e707f79583df2837cec6cf05f5d3f70b99f04ef6c3a54d55e770f2aca4a78da87446c11bb39ffbaebd324d7b369944049457bbc97256dd7b06a61127263010d42c86ce3294e2cae5304d94aeb30de4c686612d090f41998af8a1473fab4fa605579308201183510ba56602f2dbba3694959e052e0d2ec973f127308517898ba010e113a38c219ebb990c5bf15c9b155bb45bcc773b53dbc2c3fcac866ab00e0f2be61e3962b99e25bbe5fefe2b0af5fde001e35a71e1856b369b5a179d3c0a826b2010ffddb788ef1f70a205d08d44a8d5762c5f5ae5b236eb2534b55e80193c558a6f460bf89a618cf57530ef32102b2e880fb088c062e0bae28f3386dc65cdd58c19c0110ea9e738d883dc8a194c9f180a1123c2496be82678047d6220600657df77b28fd1ec53df79bc47487af116070ed44a58ab86e05030892c2107342dba5f742eb390011759c6d8c25ed3f4a60b7c30473cef12f1652231ee5e2d98efc29ffe3290a6ef37fbee021b0dcddbfbf11104ca1d9451d3ed455816821e2c089538e7d605e0a380012a07c722f449b863d996f15185efa1fb5b056be6d404c8e793492edb5736372f27a9ee67e7b4998e81cee5f45626984d801b81ef7ebc980cde1959a48b1ad57c70000000000fded29f600010000000000000000000000000000000000000000000000000000000000000004338004a37fdccca9200000000000000000000000000000000000576f726d686f6c6552656c61796572010000000400000000000000000000000027428dd2d3dd32a4d7f7c497eaaa23130d894911
3 Polygon (5) Standard Relayer 01000000030d004e90dfa99044e47b564eecadb2c658583064ac566daf77286761684cc687e9d65173cca86b6188c277847846681ae11bdbf1b966ae65180c7d878ff48135cfa00003f100618c84ff56ea49f563b432bad076350fae7cfcfb3dec92540803d84ea93b5da4c7fa7bd7ec363b9b612dcda7cfec9fbebdbce517dc30903f13c2ec5cb14e0105ce71d2e594f36caf27e8b769261e59b91e9e57fa16205c6d375074615088917e05130f24f1bf948431bcb025aecbf24dcf286297a3002c37ebe72acb5c2430c601068445c65befad456f1cc427c80b2243b23700c152afc60b298ccf5d24261bd9ee1627bc40aa527bc67de91de14cc0dfb2d99b9ec08d31a7ae3e1acef1ff22acbf0008991ec96f347b242770e978a6473da8c82b14dcb9a5ccc05dde4bcf1125e3d9481c25f188d07e1e4e68a916cd79ab21f41a5433d779660d15808e6c172c55accd0009425e5f3f71af0a6ebed1bb037590319bad260e2ebd8b889bc64f782e594792a52874c1973cf69b76f20a33317fa8f16e982afc85fe147ba742be1222d942dcf8000acb1b63f1a4f30702e2b883eecc8048ba91b38a09fffed33299b0e5aeabe09f7809fca5f75fc6a4022b902be7caf793a18d1371aecb3d9bf0d7d27640777b2cd7000cb6f2500ce351272a1d874e2c9516c566cd85702872e2b8b0fa09c54a0f03dbcd27c1ecb367da1dce046b4eeaea922f9ff172886ae4e50799248f58821e543f6d000d2c307443c8329b1c9e456334253c604b5d6c1d7f5dcd4406d9d8c4ed138b72f479ff2f412a41474f3d619a41c8bf216898b8e8a17d3cd7275e6929bcc221b848010e79b575b4795c6d3cccaef379c2f533de626df9a87a52389f38fac3f5d77b57aa317aaefa4386aac86638a9e19cd0dcbd92f9f087fed54c9e28cbb7eb7cc75b8401108d63f8802b17d2ae03a138c123b06a3be5fbed3d478672dc5009a6b6cdb13dea467ac4dcb16784cccd9ca9459ee98ceeafa0c9f444cdbd3654f034f288a24fe90111bd3e4eb9455c06c3aff08836f55add7b1bc5d389a1a02d02abcd5d54e5c1df1c31796b93b0b0e85320f8036a38513bc48008b4acc0890936bd46165f2589d69400127f69a920ebe11ad7b73eb13a8b2729d7a2972ef6b86ec2d9b2ca5f4e3b8b9cb70195f59e62b715724ed2221e32c4f537858d12506ec4d4cbf566982bf63bfb5a0100000000fded29f600010000000000000000000000000000000000000000000000000000000000000004338004a37fdcccaa200000000000000000000000000000000000576f726d686f6c6552656c61796572010000000500000000000000000000000027428dd2d3dd32a4d7f7c497eaaa23130d894911 01000000041001f100c23d38d57e97e66009b25adc7ebcaf920f5a1f621d5755d331de61c5f21631a6f0c9fbea8ad75534af4947a4df72cc293944b1aafbbcf0727f31e4071b810003f100618c84ff56ea49f563b432bad076350fae7cfcfb3dec92540803d84ea93b5da4c7fa7bd7ec363b9b612dcda7cfec9fbebdbce517dc30903f13c2ec5cb14e01044a5a94e02266383a11d1c63fdf50b2cf4a4c75fbebf158843865377f01a0cc4710e908e5190abbcabcfef294d7a054eee84a9bb0ead041c09d10f7a9cb2077000105ce71d2e594f36caf27e8b769261e59b91e9e57fa16205c6d375074615088917e05130f24f1bf948431bcb025aecbf24dcf286297a3002c37ebe72acb5c2430c601068445c65befad456f1cc427c80b2243b23700c152afc60b298ccf5d24261bd9ee1627bc40aa527bc67de91de14cc0dfb2d99b9ec08d31a7ae3e1acef1ff22acbf00074569b66d9ee98c4f2ac6f5498c721f3bc66fa9bbb0ec5e783ee381f9f06046ad54042a921a3f7367ddb192ce880ed5794272dedf0a34f791ef4370bc07743ef60008991ec96f347b242770e978a6473da8c82b14dcb9a5ccc05dde4bcf1125e3d9481c25f188d07e1e4e68a916cd79ab21f41a5433d779660d15808e6c172c55accd0009425e5f3f71af0a6ebed1bb037590319bad260e2ebd8b889bc64f782e594792a52874c1973cf69b76f20a33317fa8f16e982afc85fe147ba742be1222d942dcf8000acb1b63f1a4f30702e2b883eecc8048ba91b38a09fffed33299b0e5aeabe09f7809fca5f75fc6a4022b902be7caf793a18d1371aecb3d9bf0d7d27640777b2cd7000bad7121a6512bfe27856dcbd5c1aa96ef1fdb6110b322a0750870b96aed6f06a30678ed78b4e7dc8c57a6171aefc1b9ca7e991ac4a47d2655caf38d22858d0cb6000d2c307443c8329b1c9e456334253c604b5d6c1d7f5dcd4406d9d8c4ed138b72f479ff2f412a41474f3d619a41c8bf216898b8e8a17d3cd7275e6929bcc221b848010e79b575b4795c6d3cccaef379c2f533de626df9a87a52389f38fac3f5d77b57aa317aaefa4386aac86638a9e19cd0dcbd92f9f087fed54c9e28cbb7eb7cc75b84010fa8c983e5931d1276f84540c4005a16d53071e7a65013c5a9812c4e213556739b687a483eb19abb3f1cb73db7d6cd924d212d3c261d4f3018e8dd96c99dc8104500108d63f8802b17d2ae03a138c123b06a3be5fbed3d478672dc5009a6b6cdb13dea467ac4dcb16784cccd9ca9459ee98ceeafa0c9f444cdbd3654f034f288a24fe90111bd3e4eb9455c06c3aff08836f55add7b1bc5d389a1a02d02abcd5d54e5c1df1c31796b93b0b0e85320f8036a38513bc48008b4acc0890936bd46165f2589d69400127f69a920ebe11ad7b73eb13a8b2729d7a2972ef6b86ec2d9b2ca5f4e3b8b9cb70195f59e62b715724ed2221e32c4f537858d12506ec4d4cbf566982bf63bfb5a0100000000fded29f600010000000000000000000000000000000000000000000000000000000000000004338004a37fdcccaa200000000000000000000000000000000000576f726d686f6c6552656c61796572010000000500000000000000000000000027428dd2d3dd32a4d7f7c497eaaa23130d894911
4 Avalanche (6) Standard Relayer 01000000030d00bbfe94366547d476cc80ea55d4e62ee810c59951089c89f07d5e6dc088761384178868b90f76f3858fb749573a2eb03a4d05f8f680972d38ce5055385018a7bf010301035d39f88f4d0751269ae4e098bbe47f3591357c1b616b3e34a5c21c4c1f2c6bfd2b19a8078419699405f38d4c30b3d4970c8a7a37729dfc5c319f299883ac010566ec129bfd891f510f4b350743f2ba9c061b0b94d9cc20d0a75c20dd863722d830ad196d3cd9fb5158337e875a7848e8653d50ff7e7e63c41c2995e57e1c0397010604b345098da327b1ce27ee48a6d2bfd26a744090540042dc1d698a458f726b730f39815ab1254cc9b45bf1fb12ca62ea9b5f9f3285974c350fa7e23fe4a9c8bf010881a52213d65d8fcca6c99cea3b2d134518a451a277a0b92fcf0dba0684fc52c37254b8a2ffb450a1e0777bad5097d907cf5a48c7d70c037b3a362f1973b143d2010928b25ec1394bf9caaf9c95ef074babef722c15b0a4edccedac3fdbd6a6bd87d36ac2fb490e4605eb0d53db3eda85527fe5f00171a5a5a81b283c401ef0369794010ab5470061217ac4b94fcc45fc23292d51c04719493a2785a0caf76eb3497a402e13890bde914f07b680b84079f87bd1448ed8e4f2b1d6a60661986a6f51593d66000c28468c40328aca78777e19c2722b37057250178d92a2d66aab52d8b60bdfcb407696bdb1e2df2b002fa8e99647540a00b58c1d1f11e86a274ced8f8d8b268083010d5fa87309ca8cb8ac33c516a3c3ce860c2c69411c4f5abfec0d8ee7f08a917718371fc2e5445d27f9915cfd72396ab0b0f76fdc820f87dedfa6a129a376d39671000e028b814eb1f74fbf10a5fb2c465a254b0002830aad9201555d7f9b5061bf99f41cbeca0fbb2b6dda51fda40dfcf88be08b3c9a9ee1410347a0dff0f70a76fd560010fa217241fb64df96812ba7adea8ff477b4c03a76c25ebb3f8bc817afca2a735c7c8d0c57e02ced4c522dc5c5c02758eee91fd3bbf8f69057e93cce6ed177c9d500115cd9c43d6c791a3ad05cea7cfd97f76a1eefa267e134f0d8144b9fc527f93d2e017c44c427670248954d1d119b712412e032ace9f4879b8c36439c100318d0f000127cb2e52609a2ef2838b24744233ba084f76748d2b553abefc70cef8f05eb16731e013081b28eae042ef40f73104ba2b91760e9369168ed91bb98d985edc025f10100000000fded29f600010000000000000000000000000000000000000000000000000000000000000004338004a37fdcccab200000000000000000000000000000000000576f726d686f6c6552656c61796572010000000600000000000000000000000027428dd2d3dd32a4d7f7c497eaaa23130d894911 010000000411018a3011f6bab8f816897c708383adf3f5d49be545bb889f4f63133f373c54f02d62237e540224cfc4378bc2e09ff6127a5e2cb8e49bc5d8d96c9d4209ec772bbc0102c09524e6fa41789b556325a4a893546508e5c730ef7f52e4ea7640c381dd476e125708b397751ee2f344b6e123c044ade712f7f83be418c0ced63a2aecae3968010301035d39f88f4d0751269ae4e098bbe47f3591357c1b616b3e34a5c21c4c1f2c6bfd2b19a8078419699405f38d4c30b3d4970c8a7a37729dfc5c319f299883ac01041f645ef4100c53a244d4963a122657e93e8999baa3f6d1ba4f85377fecb9175a31b6e00635e4d06229892e922e79ce817847476e4f3a0be7d83ff59b472610d6000566ec129bfd891f510f4b350743f2ba9c061b0b94d9cc20d0a75c20dd863722d830ad196d3cd9fb5158337e875a7848e8653d50ff7e7e63c41c2995e57e1c0397010604b345098da327b1ce27ee48a6d2bfd26a744090540042dc1d698a458f726b730f39815ab1254cc9b45bf1fb12ca62ea9b5f9f3285974c350fa7e23fe4a9c8bf0107c9f099ea1e931af596d0def924eccb4b2e64fb77b0afca8b112c1b30ab3aa26e765d0ad8ed0128a31c0fc4048f1cdcefcd4c7678c259d06ea7dabbd720fbc8a8000881a52213d65d8fcca6c99cea3b2d134518a451a277a0b92fcf0dba0684fc52c37254b8a2ffb450a1e0777bad5097d907cf5a48c7d70c037b3a362f1973b143d2010928b25ec1394bf9caaf9c95ef074babef722c15b0a4edccedac3fdbd6a6bd87d36ac2fb490e4605eb0d53db3eda85527fe5f00171a5a5a81b283c401ef0369794010ab5470061217ac4b94fcc45fc23292d51c04719493a2785a0caf76eb3497a402e13890bde914f07b680b84079f87bd1448ed8e4f2b1d6a60661986a6f51593d66000ba84a3b14fd2843dfdc408190f1330539d7db5204cada959b82c9a118ff9c633a1c3ff7abf7b2a0bfd7003fec72303a0f39dacd6bb905b2c721bef7f9250b3f1e000d5fa87309ca8cb8ac33c516a3c3ce860c2c69411c4f5abfec0d8ee7f08a917718371fc2e5445d27f9915cfd72396ab0b0f76fdc820f87dedfa6a129a376d39671000e028b814eb1f74fbf10a5fb2c465a254b0002830aad9201555d7f9b5061bf99f41cbeca0fbb2b6dda51fda40dfcf88be08b3c9a9ee1410347a0dff0f70a76fd56000f1cc4a10a0875fad35c42b795c9357be35a67acace09706af13b4009bc72cfc8d3957a2baeb28bbbf0d22256f0896ed0f6fcd098f688b64b53dd111c4cc3c2ac10010fa217241fb64df96812ba7adea8ff477b4c03a76c25ebb3f8bc817afca2a735c7c8d0c57e02ced4c522dc5c5c02758eee91fd3bbf8f69057e93cce6ed177c9d500115cd9c43d6c791a3ad05cea7cfd97f76a1eefa267e134f0d8144b9fc527f93d2e017c44c427670248954d1d119b712412e032ace9f4879b8c36439c100318d0f000127cb2e52609a2ef2838b24744233ba084f76748d2b553abefc70cef8f05eb16731e013081b28eae042ef40f73104ba2b91760e9369168ed91bb98d985edc025f10100000000fded29f600010000000000000000000000000000000000000000000000000000000000000004338004a37fdcccab200000000000000000000000000000000000576f726d686f6c6552656c61796572010000000600000000000000000000000027428dd2d3dd32a4d7f7c497eaaa23130d894911
5 Fantom (10) Standard Relayer 01000000030d000afc75cbef72bcf6cc35dafdf4547edb0051789ac0afbd34c7cefa561a1cc2f0199f316ce3bb93d339f86dc44986d41e33677f33d9f9742c624befefbda05a370103d3cf95aa84035358f41d4b0f5dd0c59c2de8b69af4db84e29b5df51781d4a4437cb885054e625a4ad03324573e033bee6e4169fa7fa169c2fb4a5c4c7e69bee001051f843a340ffd3a605fd84480ef14d8595b1fffdd45a7e1c919c686ac1bd234bb4255d6ff88990e33dbeb751c06ff6ba5c63469fef50fb9924c135a2e81db0f91000678e5e902519def669dc1b03d3c9be4b84589a6322bcdf3c8cb056192a13774487a49709566d0cc68fdd9c6d1f368152f1c0728bba71031a867dbf8a170cf694e0008b25df04e7b4147bd3ae3960fe7f181968c084b63a89ca11c28e557d516e6ac3b623b56e9472041a8ce9fab0be14e9f6593caf203242f5a1a8c00c8a23f947183000919c402479e75615c767de34eb463099fc752c82aa9def7bb5dca812dc5d1a14c268f8c8a4c659be8fae0e51d2f0ed120cccac58344ca9b3df9a9cd21fe1919f9000a7c96e0c21eb74310637c8bccfac24bf91190dfca3a7499bae885a4dec541c58f241933b0d567854b6d8c2fcc284e9077ffab16d6c9c0f9b24cdc2f7875e0a8fc010ccdad41a3722e94317d99ec9542e3aa59ea9cf0297f450edc57c037408bdc5d5770df000375a79ae231aff1eb128c657d0965fe8e4fb5efef26720848b6e68a14010d419a91a2299ba3d983171250bfcda19b462c6cecd6c689ab44cd06d77b3c9bc71f532521b1334308bfed01640ab3c8d212f2e69f349c7697fabcf95f43afdce7010e2238dd50fac23d82778680768dc5cf4ffd02bbb351483dd625e034c9dd0be00a1a2c49f95238a7cfd7ec45038b4478a457e9b9c217fff574b7dd9d5663c6534600100fafc125ed044c06597a7563f22a5ed5071cda2e928bf401a71592af7abd6cf45b114d1d69ab5c784cd4adddbbf51b461e85c41f5792c5e309f86787196f9f560011141a93514e4236da671151dfce33f1fd24dd6e9cc88d16ba2fb8e04c664576b122cf795666f5b5df601b2243382b99852cd23840d91c6fd7dfbb33e27753794a0012880041feece8698f81bb66e9817ffeaa30eb58b5ee4f667a24fb05030fa2ffbc347cfc3f30bd9a18ae8e5e9c01ed40d46459d25e96c486cf849d5f4dbea188480000000000fded29f600010000000000000000000000000000000000000000000000000000000000000004338004a37fdcccac200000000000000000000000000000000000576f726d686f6c6552656c61796572010000000a00000000000000000000000027428dd2d3dd32a4d7f7c497eaaa23130d894911 010000000412015298eba9662833bebf84896d4950977e2b3a798843724b0f94e6cc593104ad0f3da6a81c3cc2a5de08913eb26290c66fa618e6fac82b6ca253c423994d7d17190002477859073938199baa195303f6c2ba8cae0c858f61bf459a833114e84ab2c6762e798b91db2623a67704c58656caea49c7459afc820f910742125fdef6b6cc270103d3cf95aa84035358f41d4b0f5dd0c59c2de8b69af4db84e29b5df51781d4a4437cb885054e625a4ad03324573e033bee6e4169fa7fa169c2fb4a5c4c7e69bee001042e63b87f925d6d9b48f8b6df815593f8cc41d12af45ca58cef567a2dee37236c734a714cf2ef110dced59b0b019b89fc06b16328d4331e905db3934f21874dbf00051f843a340ffd3a605fd84480ef14d8595b1fffdd45a7e1c919c686ac1bd234bb4255d6ff88990e33dbeb751c06ff6ba5c63469fef50fb9924c135a2e81db0f91000678e5e902519def669dc1b03d3c9be4b84589a6322bcdf3c8cb056192a13774487a49709566d0cc68fdd9c6d1f368152f1c0728bba71031a867dbf8a170cf694e0007738f6d2e42d49ab86137f8e0f1c1bc2b2b95b9f0f28f3698afb11ac5024261ae1b41b5d705a29ee77abbd7ac27d237fa4e37ae1b40df56b9a067024c90ca6d860008b25df04e7b4147bd3ae3960fe7f181968c084b63a89ca11c28e557d516e6ac3b623b56e9472041a8ce9fab0be14e9f6593caf203242f5a1a8c00c8a23f947183000919c402479e75615c767de34eb463099fc752c82aa9def7bb5dca812dc5d1a14c268f8c8a4c659be8fae0e51d2f0ed120cccac58344ca9b3df9a9cd21fe1919f9000a7c96e0c21eb74310637c8bccfac24bf91190dfca3a7499bae885a4dec541c58f241933b0d567854b6d8c2fcc284e9077ffab16d6c9c0f9b24cdc2f7875e0a8fc010b0aa4e824c96cab81bcb799c62076cbcc8c88d81dd8760d2999188704fc18251e35936882eb00ed58656432be6f60fbf144bc337d1aeb146e19d80359764f72dd000ccdad41a3722e94317d99ec9542e3aa59ea9cf0297f450edc57c037408bdc5d5770df000375a79ae231aff1eb128c657d0965fe8e4fb5efef26720848b6e68a14010d419a91a2299ba3d983171250bfcda19b462c6cecd6c689ab44cd06d77b3c9bc71f532521b1334308bfed01640ab3c8d212f2e69f349c7697fabcf95f43afdce7010e2238dd50fac23d82778680768dc5cf4ffd02bbb351483dd625e034c9dd0be00a1a2c49f95238a7cfd7ec45038b4478a457e9b9c217fff574b7dd9d5663c65346000feb07dee3c5ec9c0a74f181f76f2356d34adccd09cc889758fb1afbc180ff52ee6a6d6c04afcfb4b92afdbb79eed5f8c7e67c7c90bc9c7cf289887eacad42c9a601100fafc125ed044c06597a7563f22a5ed5071cda2e928bf401a71592af7abd6cf45b114d1d69ab5c784cd4adddbbf51b461e85c41f5792c5e309f86787196f9f560011141a93514e4236da671151dfce33f1fd24dd6e9cc88d16ba2fb8e04c664576b122cf795666f5b5df601b2243382b99852cd23840d91c6fd7dfbb33e27753794a0012880041feece8698f81bb66e9817ffeaa30eb58b5ee4f667a24fb05030fa2ffbc347cfc3f30bd9a18ae8e5e9c01ed40d46459d25e96c486cf849d5f4dbea188480000000000fded29f600010000000000000000000000000000000000000000000000000000000000000004338004a37fdcccac200000000000000000000000000000000000576f726d686f6c6552656c61796572010000000a00000000000000000000000027428dd2d3dd32a4d7f7c497eaaa23130d894911
6 Klaytn (13) Standard Relayer 01000000030d00c9b9d25eaf56c5936f66f147fe45061729bfad0514c1dbc21a6b3e8c41fd669c43f8fc2dd2792ad106d9b23d7d2161374fdb24084e4dc44b246986243177e4e30003a73bdd6b228644bdc483bc8910c39f120b83c315c33764c308d9f73bc2b30c4f26ce6b93e3de1cceab441db14445318075bde8e15e9aa77fa6c311e40bdc068000053e88ee079e28c6ebd2cdd47cee327b7ba9cd985c5b01352efc25689ebeca85844f7bc66da3266dbe5d5bba69ce0f3c217e87a051fb2de74c253c1193e52b171c01064a46327c3abc0f34caa2cef14341903e14a3b84e67d594f45d0105e2e3b4ebac3793967c20da12aa3f38101fae3f071fe870fbe574657c021949d3df3003a6a701082d5c3b48bd744256c9eeab8845402e5a937481c8ae1fc525da22c9987953e3467e19a6a31c66ba8bff7dcd24d7d23b02d44c79a09da9efacb5d9be8f0dce269d0109bc3c217eb4557cbd5b486ce13e577322808eddad286ff56f8c6403de7217a32a102e634be26acadd332b24a05a04068f823a74a6a41c4e2f91ab23f6217d8ac8010a823b3773e8a5c222bf5a28b95d2ebaa992ba4f8522337e8d2aba19bbe1ad72b4222e6a86a97e346ca937464098bf5f649f5f7e6e18e71d5b4aabdc0c19bb5130000cc6d232cfefef4ec108fbef959aa294074eacb83b6c7a8fe5f6b3e76b6d4b3c4679e1e6acb3186651d7fe984c1fa895c4afbb421b18074f917e3224b684d9006e000dd4936f7cbe9cbc64a98a654d4673e66dde3a5ccd52f8f3e16fa69c01f1e63b80362aa8f70c771b04a080bf847b5015914e189c9053e659c996dfb4e1275bd4ea000e8ab19b52ecc453b221bd23b3b437243da76ac0ad88e49e71baeaae300654d8344687f7cb1d69df24426e3d18e90ba39c1267c63725712ab125749642f8742c530110ab99b0e5b37c20f786b296923131c5df829498559e46f1e5c2971fed93ceab1700a61354b60fb640e369755a9978bc57df01a55391cb5fc7400c6caed0121a890111c844b51223b2fe13448366c8cd00edc91e688ec419aeec97bd41ae9776f317f1770c1742825c3cc1bde2c0f8928edc24874abf23d94d3d12f121b661d313913b0012f46057fb23e8b994dfd0168f8dce2f661ee24fb9ffa0be22a8b0ab4424f3ffc6567d9e5c124d2dcee0d3dae8eb786f0c1d4b38fa857e17310bd25e4092c371c20000000000fded29f600010000000000000000000000000000000000000000000000000000000000000004338004a37fdcccaf200000000000000000000000000000000000576f726d686f6c6552656c61796572010000000d00000000000000000000000027428dd2d3dd32a4d7f7c497eaaa23130d894911 01000000041201202b6807f3b8bf18ad8d3097829f84c89430a2c342e71f839bb426b8285aa0bd2cc96c07baf96a4e72c90d4c00e402847482d2bd1829e8fe6ce70a9cd2a2583301028e48df820ca4eab9737aa1d5efe784d061e11062944b5035f9c24500e644b1b747752dcdb2d58dd9ffb4b08db098121c884897df42b704fc9914f79e11072fde0103a73bdd6b228644bdc483bc8910c39f120b83c315c33764c308d9f73bc2b30c4f26ce6b93e3de1cceab441db14445318075bde8e15e9aa77fa6c311e40bdc0680000426c3fe6bd835c32b64c567d246b7efe5b4b76319beb8bdc8e02583d921dca6105ed671393ab77a71aa0bae34cc3873a747eac3baf004b2e77a571220d3329b0301053e88ee079e28c6ebd2cdd47cee327b7ba9cd985c5b01352efc25689ebeca85844f7bc66da3266dbe5d5bba69ce0f3c217e87a051fb2de74c253c1193e52b171c01064a46327c3abc0f34caa2cef14341903e14a3b84e67d594f45d0105e2e3b4ebac3793967c20da12aa3f38101fae3f071fe870fbe574657c021949d3df3003a6a70107e61150b95b83e7d8a86f817751fd75e9c8b1c3819cedce83ffe95b656f2a46605aad1a5d78ebb394ede8fd56df0caea9ca865de55205caa35e85b63f60a5fa4801082d5c3b48bd744256c9eeab8845402e5a937481c8ae1fc525da22c9987953e3467e19a6a31c66ba8bff7dcd24d7d23b02d44c79a09da9efacb5d9be8f0dce269d0109bc3c217eb4557cbd5b486ce13e577322808eddad286ff56f8c6403de7217a32a102e634be26acadd332b24a05a04068f823a74a6a41c4e2f91ab23f6217d8ac8010a823b3773e8a5c222bf5a28b95d2ebaa992ba4f8522337e8d2aba19bbe1ad72b4222e6a86a97e346ca937464098bf5f649f5f7e6e18e71d5b4aabdc0c19bb5130000bf67da3d9002c91e9aa913687980a22692ce1ade3995eaad46525928990bef07f0e87ef7709fc2fa77437978b105cc7be084f134ff992f69002f4165e0a60cbfa010cc6d232cfefef4ec108fbef959aa294074eacb83b6c7a8fe5f6b3e76b6d4b3c4679e1e6acb3186651d7fe984c1fa895c4afbb421b18074f917e3224b684d9006e000dd4936f7cbe9cbc64a98a654d4673e66dde3a5ccd52f8f3e16fa69c01f1e63b80362aa8f70c771b04a080bf847b5015914e189c9053e659c996dfb4e1275bd4ea000e8ab19b52ecc453b221bd23b3b437243da76ac0ad88e49e71baeaae300654d8344687f7cb1d69df24426e3d18e90ba39c1267c63725712ab125749642f8742c53010f0e201b577e11fa0c0f85642a40352951615226295e7c9ad18218e00d3994d31d67632a6bd6445a6ba2eb02172c09ff293e4f06ba8498a9e360281de535cbd0760110ab99b0e5b37c20f786b296923131c5df829498559e46f1e5c2971fed93ceab1700a61354b60fb640e369755a9978bc57df01a55391cb5fc7400c6caed0121a890111c844b51223b2fe13448366c8cd00edc91e688ec419aeec97bd41ae9776f317f1770c1742825c3cc1bde2c0f8928edc24874abf23d94d3d12f121b661d313913b0012f46057fb23e8b994dfd0168f8dce2f661ee24fb9ffa0be22a8b0ab4424f3ffc6567d9e5c124d2dcee0d3dae8eb786f0c1d4b38fa857e17310bd25e4092c371c20000000000fded29f600010000000000000000000000000000000000000000000000000000000000000004338004a37fdcccaf200000000000000000000000000000000000576f726d686f6c6552656c61796572010000000d00000000000000000000000027428dd2d3dd32a4d7f7c497eaaa23130d894911
7 Celo (14) Standard Relayer 01000000030d0059eacacdd28f4646e520abfc7ef33cf313a1b8f020a27e1808f0a58df34a5ebd1d8bf0e8aca4fb0db614558b1100c80be7ddb4d8ae50232d93240fc9364887ad01032085d87ad27eaa019d14cdeeea575f926ec1db44180cb1932b6ff54b56f0a9d73bab0e952fabcba8135fad9f187db120ea6fdf260cfb3869d973d3eb725c457a01050c37eebf1a94032b3fb7f53ffabeee25610a804c7f58c7ab7e82b8d103adbe1f3af1ae9967f1045c040aa5f3a4c8e4d8d5a3802ca826483e9a1a15f8e42399050106f88d72d019b83cb9b10309c8146e19769da72bb59a26369249fe39b51d475d570e57f5e19cd864af9835c4809b2668afb6690b24f271d37d9caf7089402a67140108e7ec94efd6c6c06e792c3a7e8885bf305cd652a76876d49697c99ddfc9a98b786bc215521a03151718cd81fc4619c72ffeeb29e6cd968dab9d512f7d2d0eba8800095b6f138e529675fe335e5a72f6bc1a35d20cf518786519c24ab014ceef61eb7133adcb701a7f75ccbacc12ab5e74dbc7c083ea8318d0eede51f486292c901e74010a538c2fbf35b4630f13e694da19fd3e2fa57438622af490fd3bb19a620f88be3678b5d6408c7177575d04a6559bc0bd19538f93e6dd5288d9931511ab8c512d31000c6563e95259a53f854c5441759804111e52ce42e5332df7ca601cb14091d3c6d81a37ffb91829cafc053e14af24a59ffcabc3fd774e1399901154d52d634057fa000dd639c68822ed4f29afbdfe349fb31cc367b065f5a3bfb73587e0aaf8dd0ad5161be5fd99d78628a7bdfa8c07ffaa47d6c4b58e6b470dabecfbe95db39a96496a010eb85a203b18444f5d26beac38279081d618a50a77f0fcb7d7ff3f51fb2705d9a167bf7c7a2506dc4ac90b946ee63d8a9ea6bfad8aa8494f99f2af5d15d190801b011018d5a390d01b98d9762222d97d3cb988573f256a7a3d512bb26db78f2e1284be020a6d5a9660a869dceba199308db403e0708c785e1c2715821f69a091f39d8b01110767d6f4f27f9db7ae9e4256b9a857e78571e92197cbc8218551da332fb4110e07dfcc73438b8473b91f3a93a4bd96be9dbaff86b524eb8dc1639da33f1f79a00012b00387cd213e2e6ec3973bd90d98eb4c500c9c6aa893cb1d607d9842a326b6e75a5644785dd5ff7c2eef012e938b6df215ed4e97b8223c078fc8a8dba92787770100000000fded29f600010000000000000000000000000000000000000000000000000000000000000004338004a37fdcccb0200000000000000000000000000000000000576f726d686f6c6552656c61796572010000000e00000000000000000000000027428dd2d3dd32a4d7f7c497eaaa23130d894911 0100000004120121285f733587727520973bf05a22418d34f6b5aa27504c4053d5ee5ce23a02c31153495f3c533ca16f71107af7a54b88bb8fc7d64d20206ed0eb26ffc6cfe5a70002d17c60f1fa5a84d2ae69fba2cf46edd03e3283ae74991abaaaa017ddb3d9fb4e239a82eebe14e89f794ca32a421f2516d9fe57c97133f20bd4a34da78a50102e00032085d87ad27eaa019d14cdeeea575f926ec1db44180cb1932b6ff54b56f0a9d73bab0e952fabcba8135fad9f187db120ea6fdf260cfb3869d973d3eb725c457a0104c7af4c135eee9cfb346bb97350f4c0ca5832cc36485d3fa11603f05d42cf9c9f65e4518bc5483dbde664518abc30d2e4741d18649689fb5c9f47dc288a22b1c101050c37eebf1a94032b3fb7f53ffabeee25610a804c7f58c7ab7e82b8d103adbe1f3af1ae9967f1045c040aa5f3a4c8e4d8d5a3802ca826483e9a1a15f8e42399050106f88d72d019b83cb9b10309c8146e19769da72bb59a26369249fe39b51d475d570e57f5e19cd864af9835c4809b2668afb6690b24f271d37d9caf7089402a67140107ad463df69a2591bbb892fdd1b28009802ce29b3d8c98c58248178c927ef514245e2c4d99968a30bf642e750d5345aeb85bcc2f23fca01e0cbeff8e2b3be32a930108e7ec94efd6c6c06e792c3a7e8885bf305cd652a76876d49697c99ddfc9a98b786bc215521a03151718cd81fc4619c72ffeeb29e6cd968dab9d512f7d2d0eba8800095b6f138e529675fe335e5a72f6bc1a35d20cf518786519c24ab014ceef61eb7133adcb701a7f75ccbacc12ab5e74dbc7c083ea8318d0eede51f486292c901e74010a538c2fbf35b4630f13e694da19fd3e2fa57438622af490fd3bb19a620f88be3678b5d6408c7177575d04a6559bc0bd19538f93e6dd5288d9931511ab8c512d31000b4b193a05edc48b51eeaa302473168dba70821a22541a0ef2cfad161b2aa3bc82066a56f9f0f222116f2904701b05201d619fb3f486fefd08876c7a5bebd67c09000c6563e95259a53f854c5441759804111e52ce42e5332df7ca601cb14091d3c6d81a37ffb91829cafc053e14af24a59ffcabc3fd774e1399901154d52d634057fa000dd639c68822ed4f29afbdfe349fb31cc367b065f5a3bfb73587e0aaf8dd0ad5161be5fd99d78628a7bdfa8c07ffaa47d6c4b58e6b470dabecfbe95db39a96496a010eb85a203b18444f5d26beac38279081d618a50a77f0fcb7d7ff3f51fb2705d9a167bf7c7a2506dc4ac90b946ee63d8a9ea6bfad8aa8494f99f2af5d15d190801b010fc87ba5e8a9caff6cfd7e83376dfd97a6840906ebec31e299d2fd0940f936061d605b244bf2427cb36114d39cff7fba122d6baa6d6207257d42e4fa43473f0887001018d5a390d01b98d9762222d97d3cb988573f256a7a3d512bb26db78f2e1284be020a6d5a9660a869dceba199308db403e0708c785e1c2715821f69a091f39d8b01110767d6f4f27f9db7ae9e4256b9a857e78571e92197cbc8218551da332fb4110e07dfcc73438b8473b91f3a93a4bd96be9dbaff86b524eb8dc1639da33f1f79a00012b00387cd213e2e6ec3973bd90d98eb4c500c9c6aa893cb1d607d9842a326b6e75a5644785dd5ff7c2eef012e938b6df215ed4e97b8223c078fc8a8dba92787770100000000fded29f600010000000000000000000000000000000000000000000000000000000000000004338004a37fdcccb0200000000000000000000000000000000000576f726d686f6c6552656c61796572010000000e00000000000000000000000027428dd2d3dd32a4d7f7c497eaaa23130d894911
8 Moonbeam (16) Standard Relayer 01000000030d00147ce69eaecfb38adcf8f953bf97f1718fa3db81c1609e42ecedefee95f6fb216f20a5e3562e53a8016b4c5ac45c93f749ed3ba9381685037490286a55e5dbc50003aea201f953a34c7b5cbbccbec6c42d474107efa3c1f5f25137f0f7f1f8f3446f53fbf9b1d475f396cd04878e0bf9ef58014beec38c3fb698d38602fbdfb5f18b0105fb93126334289857302eaf327690a0d8457098fac094a6817b49f38841c385295998dfc8d50071f296053d8fc472685fee36dd8990c8230f3e276e1b873a75be0006241945f86c1abef3ee1286b1422c92bafed7b38c3daec22ba602526675b4d35e1938ab844b416b6a803bde5b12648d66e9bae68e34dc87450a69a64bbd2034ba00084ee90ad3baa0ee4ccb987f686246958634fd8834790f8b664f8ff60bf1d83e25636b9e9ccf6323234cdbd8e52c138c98f85d4ad2c40a15b136520adcf36180010109a76104932e8c3a7336ca6cdd33b1b69cbf750eb724e368fae15334ec880921963c9f5e317de2b6d7bfc634c1cf6d26567662dbe90a0f78989c2e09d8671ee004000a4b57433c1f5608e4c0e78fbb597271bdb79060a01126d555db0a00e4160e2a0e6194e6a2c815109b3ca69b14b8995fb8b5123c11e769b65865c0c48d547c15b0000c7be055a164a254ef1a8d423fb8a740f365e384dbfb1df6279ec1aa2f8e8ec33f5359e3dbc50ed0b6a6f81cc28a8df550e0b22f4039197c939fb08bf9af6207a2000dffa23f41b9167fbbcbff97425f015f62d68d4f469f0973bdecb8fab41a44c1f131ac820ee22318ea239a7455e1611c77aa7d26783aa1a11203b72f447519520c010e3ef1157fe2d4df059a0d4d3796783bcd9acbd30b9ba81273841a6f82c56b710417dbe60447e5c1bc362bdae2eb15cdcf2af4d0b76577b1b13925e0ab105b43340010443e60d8ca17b58f77996ddac9525cfaeaf5092ebea04f13fdf0aab8204bbaa23c04b1987b95836d36d706597b2439acddd2539d9f6c0bbeea970de801f9eaa500114a111aeaf1f695515f01fb174e606835292a99a2d953db84753369b7f6aec89a4e9e12db15b76a880b92983f28937e8e2569bd3a7eeddfe710c8fc4fce011ed80112433a42154cbdb6f1b1bdbccff6fdcb90e8b174540e63825af039b8fc43c1bd6211c1cb4849d6ca8cb2aaefedc684717faebe50b111a44f8224debf9aa0bbe5b00100000000fded29f600010000000000000000000000000000000000000000000000000000000000000004338004a37fdcccb1200000000000000000000000000000000000576f726d686f6c6552656c61796572010000001000000000000000000000000027428dd2d3dd32a4d7f7c497eaaa23130d894911 0100000004120179716c0fb88b8859d07f660f1732af0f8e239dc21a69958235d1dbef7572588c6ad3669b231555bfae49e6a81dc27160026b1a86f2ec813a650967741475b9a2010211fa62ed1fb2e4ac5762da890ae39f0542522987555ce69ce8336a189f138f7100ff0999d9cc68dbcb74078e8b2e64e32513414dadf6873018a5e0245795acc70003aea201f953a34c7b5cbbccbec6c42d474107efa3c1f5f25137f0f7f1f8f3446f53fbf9b1d475f396cd04878e0bf9ef58014beec38c3fb698d38602fbdfb5f18b0104e355004e39c7042982a07a50d0e7995180f3336f6c72fe0edb17f1d0acefb13302799ad1b84d4bd4d5f11b2633a02b3ad7f955cd30387ba46d20546dc109ac010105fb93126334289857302eaf327690a0d8457098fac094a6817b49f38841c385295998dfc8d50071f296053d8fc472685fee36dd8990c8230f3e276e1b873a75be0006241945f86c1abef3ee1286b1422c92bafed7b38c3daec22ba602526675b4d35e1938ab844b416b6a803bde5b12648d66e9bae68e34dc87450a69a64bbd2034ba000728253f463ea16bf1c509575955a47d2a88020fec9db1f5e779a66875be054176795bdad1c04ba3b7ca6aee98d2fd05cacb06aeef0d6bf693c59f14da5d60c0df01084ee90ad3baa0ee4ccb987f686246958634fd8834790f8b664f8ff60bf1d83e25636b9e9ccf6323234cdbd8e52c138c98f85d4ad2c40a15b136520adcf36180010109a76104932e8c3a7336ca6cdd33b1b69cbf750eb724e368fae15334ec880921963c9f5e317de2b6d7bfc634c1cf6d26567662dbe90a0f78989c2e09d8671ee004000a4b57433c1f5608e4c0e78fbb597271bdb79060a01126d555db0a00e4160e2a0e6194e6a2c815109b3ca69b14b8995fb8b5123c11e769b65865c0c48d547c15b0000b76add1069fd8d6ac522acec5153b0aefcad592d9e7a5fcaa8b0b1c42306fb18e746cf5eedb4e9279f4021aa0c6e189447d4e1d6529fdabe5659ed348a98dc64c010c7be055a164a254ef1a8d423fb8a740f365e384dbfb1df6279ec1aa2f8e8ec33f5359e3dbc50ed0b6a6f81cc28a8df550e0b22f4039197c939fb08bf9af6207a2000dffa23f41b9167fbbcbff97425f015f62d68d4f469f0973bdecb8fab41a44c1f131ac820ee22318ea239a7455e1611c77aa7d26783aa1a11203b72f447519520c010e3ef1157fe2d4df059a0d4d3796783bcd9acbd30b9ba81273841a6f82c56b710417dbe60447e5c1bc362bdae2eb15cdcf2af4d0b76577b1b13925e0ab105b4334000f9a5bab2b554ce1cbb63d47a3be885fde9b7d5afc82ef3abc6341b79f182de5b65170b70ef3b015ea5f18aea87546f1abbb35f8fb6a2748d1e6f5bf55907d03fa0010443e60d8ca17b58f77996ddac9525cfaeaf5092ebea04f13fdf0aab8204bbaa23c04b1987b95836d36d706597b2439acddd2539d9f6c0bbeea970de801f9eaa500114a111aeaf1f695515f01fb174e606835292a99a2d953db84753369b7f6aec89a4e9e12db15b76a880b92983f28937e8e2569bd3a7eeddfe710c8fc4fce011ed80112433a42154cbdb6f1b1bdbccff6fdcb90e8b174540e63825af039b8fc43c1bd6211c1cb4849d6ca8cb2aaefedc684717faebe50b111a44f8224debf9aa0bbe5b00100000000fded29f600010000000000000000000000000000000000000000000000000000000000000004338004a37fdcccb1200000000000000000000000000000000000576f726d686f6c6552656c61796572010000001000000000000000000000000027428dd2d3dd32a4d7f7c497eaaa23130d894911
9 Arbitrum (23) Standard Relayer 01000000030d002a7523753fc4db66ca547f99a7d2f3369ec80ba3694dc80270b7efced21f900454e5968e3d6b3166f98c53dee11aa62d537bca8016eab1371d155de2146fb0790003d60b1a8ec2b4ce27e2b7298bb3cb503008b945480d537546dba2a0b1afdc80e26bc0b07d9ee4f3ef40048e25d72d23de26d22dbbc7c23df6eef0367111ea466d00053542fa8dba6b62072372bf92ef566f1ade2a95f7abe97692d20bec89c9ad220e49718ebccd0697ca592458d79a73c3f489ba7b5bfc51d9cafc9fd3b54e5d82fa0006b1f4dfb7ee4bb3059c0f9fb81c6afd5b7703d7e0b54720067d7ff7c62755aa3f0e806c426c5a7238917f89cfda30b80e7633cff6005a5965cf61356f551964a50008ebe7c99a2e83a7515927246ac0accad976a388245acce1f41ab198d37b32dcd72717e17dd7339e04d0b97a89356fa994e5b1a036ec80eb681a9c3472c26dfa1400090e98acccf12cba83b7bb65b88f532afa0f86bc068e1313e186b49e9850650c7c6ebaccc02e627b5d7470ef9035c08cae8d874dc4b371945b289706deac7d9008010aa0f27bcfc63715902446fdf352554ea699e361b8e3dcbc57b840f8b5f7dc745e02847d83317d2029b73d47daca88852f1beb2a49004c1c1e9ef4b501f417dcc6010c724aa60c084bcc159af35a9d58078d667534cb67bcfca5f959e05eb1b0956d4a02ef98abc9ac677b779b1fbd7505b1621b0935d1a58d7373c36b96b99f8cc0fb000d3139b25069520a4bd9c61905e7fd83ce21eb5786b26b1e5b96772e4933a6eb163dd4031a1bed0cc65e39e00d0a000c917b69015696cb1eed816be864b65abfb2000e794260e5d734ae20e53ff34799b2a9a39f0f792371f8f27e70cd5c14a3d781816b7dc8a3da6ba886f2c21b304648c51c16892da6bacd10776182cb65c9c46b0101100efc7a08cb812ab047bd67e624197e8244adc6a1ce0d9ef30c469bb5918606e55e3aca65054e0f46e6e7eca8f20b9c4128791ba04496ae9713c5242883777a67011137416a6f4a919b2b4dfafb55c38669b93d66810ab0c77cd9285c71fe3a3e38a36b18c4fb1f6e0700b89afb8f74f056dd58846fb8d0444c3b405afb7755faa3990012747f08fba62aa374373a5c36b6fb29a36d4e382efb2b0a54b039aeb8f76fc764683b02c529802297429d0fb5320b1e6e5c63acf309e03e0f15f7a1fe74eff30f0000000000fded29f600010000000000000000000000000000000000000000000000000000000000000004338004a37fdcccb2200000000000000000000000000000000000576f726d686f6c6552656c61796572010000001700000000000000000000000027428dd2d3dd32a4d7f7c497eaaa23130d894911 010000000412010ec78f0da9032eda3bf39f793f612a1f91a40ba7b2791726b5d78b8669d63c2d53ced3e8daf9ad7c7a9eed68b9e4fc7c418403c0e76bade1cefa5d08e9ded7a60102254161d961c9f8e4f84cb48c12e45cb40dddd43a3c7215c480e3d295d7018e5163cf27ad2d53f692eaf5461fe60ff0b0edd33e6989f313df802ed5ffa0a664780003d60b1a8ec2b4ce27e2b7298bb3cb503008b945480d537546dba2a0b1afdc80e26bc0b07d9ee4f3ef40048e25d72d23de26d22dbbc7c23df6eef0367111ea466d0004990843481a1f07312418d822eb817d24ca80d7a53464af9b1f4bf81772dca47e33eb46dd579703c4ae31fb9164e5508f474b4055aa703b0a7c8eebe6f60be04b00053542fa8dba6b62072372bf92ef566f1ade2a95f7abe97692d20bec89c9ad220e49718ebccd0697ca592458d79a73c3f489ba7b5bfc51d9cafc9fd3b54e5d82fa0006b1f4dfb7ee4bb3059c0f9fb81c6afd5b7703d7e0b54720067d7ff7c62755aa3f0e806c426c5a7238917f89cfda30b80e7633cff6005a5965cf61356f551964a500075883d0f908800f54a9feb4211810e14a0a0d65827c051f3793d1511048deef8b7b687003455f2ff07a3395f1297936de1785fea7568fdb62d347ef1b6a1502d30108ebe7c99a2e83a7515927246ac0accad976a388245acce1f41ab198d37b32dcd72717e17dd7339e04d0b97a89356fa994e5b1a036ec80eb681a9c3472c26dfa1400090e98acccf12cba83b7bb65b88f532afa0f86bc068e1313e186b49e9850650c7c6ebaccc02e627b5d7470ef9035c08cae8d874dc4b371945b289706deac7d9008010aa0f27bcfc63715902446fdf352554ea699e361b8e3dcbc57b840f8b5f7dc745e02847d83317d2029b73d47daca88852f1beb2a49004c1c1e9ef4b501f417dcc6010b08ca6babf828e69e3b5fdd0db9c34dca35ff6fd2a2bb261a01216abfd31cb95239af719cf2ba294a2c1b45dfd3d901f68bca3a44d1cc71a180ec6ddc6172282f010c724aa60c084bcc159af35a9d58078d667534cb67bcfca5f959e05eb1b0956d4a02ef98abc9ac677b779b1fbd7505b1621b0935d1a58d7373c36b96b99f8cc0fb000d3139b25069520a4bd9c61905e7fd83ce21eb5786b26b1e5b96772e4933a6eb163dd4031a1bed0cc65e39e00d0a000c917b69015696cb1eed816be864b65abfb2000e794260e5d734ae20e53ff34799b2a9a39f0f792371f8f27e70cd5c14a3d781816b7dc8a3da6ba886f2c21b304648c51c16892da6bacd10776182cb65c9c46b01010ff9bd86279193140979c846052ba99d6f9e8411da7f7004a8e02728579f2283a9510c090466ef71922a58184b5be558a790866125bd76211f308aaa70f080becb00100efc7a08cb812ab047bd67e624197e8244adc6a1ce0d9ef30c469bb5918606e55e3aca65054e0f46e6e7eca8f20b9c4128791ba04496ae9713c5242883777a67011137416a6f4a919b2b4dfafb55c38669b93d66810ab0c77cd9285c71fe3a3e38a36b18c4fb1f6e0700b89afb8f74f056dd58846fb8d0444c3b405afb7755faa3990012747f08fba62aa374373a5c36b6fb29a36d4e382efb2b0a54b039aeb8f76fc764683b02c529802297429d0fb5320b1e6e5c63acf309e03e0f15f7a1fe74eff30f0000000000fded29f600010000000000000000000000000000000000000000000000000000000000000004338004a37fdcccb2200000000000000000000000000000000000576f726d686f6c6552656c61796572010000001700000000000000000000000027428dd2d3dd32a4d7f7c497eaaa23130d894911
10 Optimism (24) Standard Relayer 01000000030d006706123794be8c86c236a0416cc1d7730e1a892ae2f5f83cdce8cadf42d61ff10ced17f17d6e2af4cd2689b8e0ebd903cce7f5643e8d8b76f55411129c575365010311e848aaea7323cddfe9d1f45189acf490d3130b9961855aa00c20e7149395a17f133ce44cd4a16078f2f884806d901eb3c56c7fa11a6c628ae659ba602913ea01059d830b8110639295a06447b4f54ed72585a30256bf600b7f0fca48f71b30b74f02a4e64c1f2c4152a2f3b7e8ac28e8029c0f60fe4c92f00f5cff8e5daf2395210006dd08a89b93920292bafca3ab963d171e884cd3bbb9b857bf6f87ab27ad2792150ed5bf038693e6ccb855d2376fc0a4087747fd1154dcc4c20b75df05a758196f010809d6a0821706b2fda0e73c4ddb551981dad9dc1c2c8e85a902195cebd1d8565e528fd078005dfed95fdb92dcad5971ce68f7b5f897f72544a346a073129ac6a700098f24b7e0e5a26410c66b1b1945494d36b9fff6dacf16c5a6a22f01a9ecc021951fd6f992c0ba7ab688b5a90fcd9f96a7fd28bf044a576d58b1a9b85f6964d430000a0323d4671721c0262265a37ff9e3459196ebb928c3568ef4b15f5812ae411f1e4cf9acf02be0f66d380abdcbd1cede4c35483e680a0c330d4fa04551e7b39a63000c4d0e32decb9285203ec763ed6cab15a1fd91fa8bfaf3bfaf449a08e52b79bdb76a10fe2a67974ca57549811cea6b51f39d8abc47b7cd9969e7d6f3b86c3949a6000df8b8844a14ed09439311cf4588760e80ad2a6c460759a85145ded663c503882a367a8ea4727e147822bb6396102d0ce6b90d1e6b87b6ce727d5fdc202b83579f000eea060f748330d8c31e520b8c3b68873e47a6dabe9bd0889dcd7525700b90134b4892bb973ed3aca95343644e5e87b3615409f2a872be97b9a8aaa3566135465000105f7c654722a67c678528e8d6a64a26f5999c70cf33adacd1cfb64d0f8b0c26f81810ba862ac88aafaa90ab5a0669aad2610dd7ad16b1133f4c0dcd4d491a462f0111b698f2fe7cd834d2bdff5d4e2f0289d9631bb910db3e64b91689b7aee09b273679c4cc40da83f0a579a06c756abb9ad9d2ba150a4d18be34c5e88010c46dce6700120ff19d84f49d84cadf0c27f91955b36980271a571c17ac85daf121bb6d0490857cd79a89eb5e1532b74439887ea0f66a5f9ae804ff063b896b24d5014b8e95ff0000000000fded29f600010000000000000000000000000000000000000000000000000000000000000004338004a37fdcccb3200000000000000000000000000000000000576f726d686f6c6552656c61796572010000001800000000000000000000000027428dd2d3dd32a4d7f7c497eaaa23130d894911 0100000004110188474b81330c0fa2db74ea40139146de4c3f62fa3eb23df25125a26142845d011de1aa9d844605a8d113bd1142e45434f1690812686d7161aade3588e94ac698010311e848aaea7323cddfe9d1f45189acf490d3130b9961855aa00c20e7149395a17f133ce44cd4a16078f2f884806d901eb3c56c7fa11a6c628ae659ba602913ea01046a87b3416c3569a2c41fcab24fff66b07701a5fd6df72a3e6d044398054e048742febab5b5f8903703c6c73ea32902dc94c7ee1c4f31dcfb04c52e0f27d93b2100059d830b8110639295a06447b4f54ed72585a30256bf600b7f0fca48f71b30b74f02a4e64c1f2c4152a2f3b7e8ac28e8029c0f60fe4c92f00f5cff8e5daf2395210006dd08a89b93920292bafca3ab963d171e884cd3bbb9b857bf6f87ab27ad2792150ed5bf038693e6ccb855d2376fc0a4087747fd1154dcc4c20b75df05a758196f010771a162500b2783c74223ab5d28e04f1269e49254630a440bb9f0eacd8b59586f01adf5ecbc7c9abe0bd83235a813b41026b19f571e0af31bbf799fc54e54bd3f010809d6a0821706b2fda0e73c4ddb551981dad9dc1c2c8e85a902195cebd1d8565e528fd078005dfed95fdb92dcad5971ce68f7b5f897f72544a346a073129ac6a700098f24b7e0e5a26410c66b1b1945494d36b9fff6dacf16c5a6a22f01a9ecc021951fd6f992c0ba7ab688b5a90fcd9f96a7fd28bf044a576d58b1a9b85f6964d430000a0323d4671721c0262265a37ff9e3459196ebb928c3568ef4b15f5812ae411f1e4cf9acf02be0f66d380abdcbd1cede4c35483e680a0c330d4fa04551e7b39a63000bd03df44627e6cc431261553953511106c1d451b12cf50c977e0280117a75067340a671de2b755cc23dd6097e5f7f922bc2cbc2b78c499256e04ec75e8f6bcc3e000c4d0e32decb9285203ec763ed6cab15a1fd91fa8bfaf3bfaf449a08e52b79bdb76a10fe2a67974ca57549811cea6b51f39d8abc47b7cd9969e7d6f3b86c3949a6000df8b8844a14ed09439311cf4588760e80ad2a6c460759a85145ded663c503882a367a8ea4727e147822bb6396102d0ce6b90d1e6b87b6ce727d5fdc202b83579f000eea060f748330d8c31e520b8c3b68873e47a6dabe9bd0889dcd7525700b90134b4892bb973ed3aca95343644e5e87b3615409f2a872be97b9a8aaa35661354650000fd64d914031f191e0d748817eb8f682daf8157c46c101d65edb6cda8a23bcc13d10118200042b3335834a02e0c265422d2cffe6ad430d16b12016aa82266f92e001105f7c654722a67c678528e8d6a64a26f5999c70cf33adacd1cfb64d0f8b0c26f81810ba862ac88aafaa90ab5a0669aad2610dd7ad16b1133f4c0dcd4d491a462f0111b698f2fe7cd834d2bdff5d4e2f0289d9631bb910db3e64b91689b7aee09b273679c4cc40da83f0a579a06c756abb9ad9d2ba150a4d18be34c5e88010c46dce6700120ff19d84f49d84cadf0c27f91955b36980271a571c17ac85daf121bb6d0490857cd79a89eb5e1532b74439887ea0f66a5f9ae804ff063b896b24d5014b8e95ff0000000000fded29f600010000000000000000000000000000000000000000000000000000000000000004338004a37fdcccb3200000000000000000000000000000000000576f726d686f6c6552656c61796572010000001800000000000000000000000027428dd2d3dd32a4d7f7c497eaaa23130d894911
11 Base (30) Standard Relayer 01000000030d00df8b4dd3d24304810ddbf4cf43fc4507b56728f76e6b1d102a6ba646d0c63b2b4148223e19ae06f40ca072fe16333a4c44748bc37457835966c69f35b4d27501010247e8f4a5a1e5a4f858444a50f419a477866f7ad10af94d62251ff5a7f4a42a9215002d6b5a7939224d6221d743a0107792b4a1efd42619732a34c7c2cdc4401100036fb6ef9f9c50657d7791bb344b948d6c812f1b4070381003a942419b174c4fc94cb8d63cec79e13982a2642d789054d0746498807da03d3c59a39efa29232dbf0104bbf027b263137578ea240576f12e3dc1470ceda63391dfeaaf0f71af0adfa764772a206847aa10646aef2ebdba8ca21b6c08088cb58942f2145c5120e0f94b86000674719843c99e12cd2b9b37f98431f8dd8bd2d74b0794291fd8d7b8b575bcc8964ee2c7982fb4932621996d587eb4ff4861e1d0e6d873ee1ee8b9f684f08426250108f33ed961639ec82c1be05528b8a75f6657bcebec68827e8f295899e41423e22205312e5e7bb6453004df0eadbe11eb79588ee16f5b35fc8db2f7dc7d457bfaa20009e439e5b37dacdec25d12cba1531efceb2f130a812d2d99fcb728282bce06dbe91fab11228716ea1d430ae8a08ecc2482e30b439b912b7b0dcc95cc80e98fe6da010a5224519f03cf83b67ed6d31a5495edcf66ac10da2d94bac542109be2d075f7230b63c1576641ad6d9a54b1fbd5fa7fbe3c08cd08f673318476aaf9fcef48c6e5010ba277e69a71938f8b1197cb6975968f7e4780fda8e6136d23d2c9f5cbbb15d2ae682321eb8b5f683c5825b74492e7a2a4d18ac20cd8c30fe3fa712bd71c8b6033010d06fba68375dfdf6d76c97d3a2e0ea1c9b243d8f7a37114406fc67cb7545c717402faf5175907d1ccd943f20d539b815eb936d430fc3dfb35c3316a2342dba38d010e4ca329b5c61f7faa4223595fe3dd4d14d77506c36013c6ce8e34834d48380f75536d12e3a9cef5446a33766a500a676c3d59b09e984e0f31be780bd736a8150b0010788d6362177378258f98c0a1a5a85b229b2316e43b28a08c68e0303fe2bae4a27cf109f07ed6efa6be02379b07b4ba02c9d81c478263eda7a3c279af2d4987fa0112d5b4f5a87674f8c4a686ac67806a45440d30861a43191ec72e5f75a733a8b51c189659e8ed8ff7be73d3a14780a46cb34a58a5308f7381d668e8db58198f185501000000006b45a1a900010000000000000000000000000000000000000000000000000000000000000004555704dcd5046cc4200000000000000000000000000000000000576f726d686f6c6552656c61796572010000001e000000000000000000000000706f82e9bb5b0813501714ab5974216704980e31 01000000040f0247e8f4a5a1e5a4f858444a50f419a477866f7ad10af94d62251ff5a7f4a42a9215002d6b5a7939224d6221d743a0107792b4a1efd42619732a34c7c2cdc4401100036fb6ef9f9c50657d7791bb344b948d6c812f1b4070381003a942419b174c4fc94cb8d63cec79e13982a2642d789054d0746498807da03d3c59a39efa29232dbf0104bbf027b263137578ea240576f12e3dc1470ceda63391dfeaaf0f71af0adfa764772a206847aa10646aef2ebdba8ca21b6c08088cb58942f2145c5120e0f94b86000674719843c99e12cd2b9b37f98431f8dd8bd2d74b0794291fd8d7b8b575bcc8964ee2c7982fb4932621996d587eb4ff4861e1d0e6d873ee1ee8b9f684f084262501071243774552bd7af6f1325b86965546b960955e2c594b225ab2df51bd58b7ec5331f17d71b00298536281977290ed6d5d1534cc6693137988aba25c19be3295020008f33ed961639ec82c1be05528b8a75f6657bcebec68827e8f295899e41423e22205312e5e7bb6453004df0eadbe11eb79588ee16f5b35fc8db2f7dc7d457bfaa20009e439e5b37dacdec25d12cba1531efceb2f130a812d2d99fcb728282bce06dbe91fab11228716ea1d430ae8a08ecc2482e30b439b912b7b0dcc95cc80e98fe6da010a5224519f03cf83b67ed6d31a5495edcf66ac10da2d94bac542109be2d075f7230b63c1576641ad6d9a54b1fbd5fa7fbe3c08cd08f673318476aaf9fcef48c6e5010ba277e69a71938f8b1197cb6975968f7e4780fda8e6136d23d2c9f5cbbb15d2ae682321eb8b5f683c5825b74492e7a2a4d18ac20cd8c30fe3fa712bd71c8b6033010d06fba68375dfdf6d76c97d3a2e0ea1c9b243d8f7a37114406fc67cb7545c717402faf5175907d1ccd943f20d539b815eb936d430fc3dfb35c3316a2342dba38d010e4ca329b5c61f7faa4223595fe3dd4d14d77506c36013c6ce8e34834d48380f75536d12e3a9cef5446a33766a500a676c3d59b09e984e0f31be780bd736a8150b000f151a6b2de331631ccdda12cf215868b93b12d6bca992832ce5531d2c57b290b72c323c3bff1150f1606e738a0c5165aefff6489d8d1c6194566ca91fdc882bf30010788d6362177378258f98c0a1a5a85b229b2316e43b28a08c68e0303fe2bae4a27cf109f07ed6efa6be02379b07b4ba02c9d81c478263eda7a3c279af2d4987fa01119031dcaf73436185f8853ae273ba23e44f8fbb6ed31b750684ffe45dac34f11813c37916f0bd6c7282b1caf49206e6df9004e0450010f9f93c9e0e20107c235f0012d5b4f5a87674f8c4a686ac67806a45440d30861a43191ec72e5f75a733a8b51c189659e8ed8ff7be73d3a14780a46cb34a58a5308f7381d668e8db58198f185501000000006b45a1a900010000000000000000000000000000000000000000000000000000000000000004555704dcd5046cc4200000000000000000000000000000000000576f726d686f6c6552656c61796572010000001e000000000000000000000000706f82e9bb5b0813501714ab5974216704980e31

19
ethereum/env/.env.blast.mainnet vendored Normal file
View File

@ -0,0 +1,19 @@
# Blast mainnet env
# Rename to .env to use with truffle migrations
# Common config for forge deployment
RPC_URL=https://rpc.ankr.com/blast
FORGE_ARGS="--slow --priority-gas-price 1 --gas-estimate-multiplier 130"
# Wormhole Core Migrations
INIT_SIGNERS=["0x58CC3AE5C097b213cE3c81979e1B9f9570746AA5"]
INIT_CHAIN_ID=36
INIT_GOV_CHAIN_ID=0x1
INIT_GOV_CONTRACT=0x0000000000000000000000000000000000000000000000000000000000000004
INIT_EVM_CHAIN_ID=81457
# Bridge Migrations
BRIDGE_INIT_CHAIN_ID=36
BRIDGE_INIT_GOV_CHAIN_ID=0x1
BRIDGE_INIT_GOV_CONTRACT=0x0000000000000000000000000000000000000000000000000000000000000004
# Using "Non-rebasing WETH"
# See https://docs.blast.io/building/contracts#l2-contract-addresses
BRIDGE_INIT_WETH=0x9D020B1697035d9d54f115194c9e04a1e4Eb9aF7
BRIDGE_INIT_FINALITY=1

18
ethereum/env/.env.scroll.mainnet vendored Normal file
View File

@ -0,0 +1,18 @@
# Scroll mainnet env
# Rename to .env to use with truffle migrations
# Common config for forge deployment
RPC_URL=https://rpc.ankr.com/scroll
FORGE_ARGS="--slow --priority-gas-price 0 --gas-estimate-multiplier 130"
# Wormhole Core Migrations
INIT_SIGNERS=["0x58CC3AE5C097b213cE3c81979e1B9f9570746AA5"]
INIT_CHAIN_ID=34
INIT_GOV_CHAIN_ID=0x1
INIT_GOV_CONTRACT=0x0000000000000000000000000000000000000000000000000000000000000004
INIT_EVM_CHAIN_ID=534352
# Bridge Migrations
BRIDGE_INIT_CHAIN_ID=34
BRIDGE_INIT_GOV_CHAIN_ID=0x1
BRIDGE_INIT_GOV_CONTRACT=0x0000000000000000000000000000000000000000000000000000000000000004
# See https://docs.scroll.io/en/developers/scroll-contracts/#l2-predeploys
BRIDGE_INIT_WETH=0x5300000000000000000000000000000000000004
BRIDGE_INIT_FINALITY=1

View File

@ -60,6 +60,11 @@ var ibcUpdateChannelChainChainId *string
var recoverChainIdEvmChainId *string
var recoverChainIdNewChainId *string
var governanceContractAddress *string
var governanceTargetAddress *string
var governanceTargetChain *string
var governanceCallData *string
func init() {
governanceFlagSet := pflag.NewFlagSet("governance", pflag.ExitOnError)
chainID = governanceFlagSet.String("chain-id", "", "Chain ID")
@ -171,6 +176,19 @@ func init() {
AdminClientRecoverChainIdCmd.Flags().AddFlagSet(recoverChainIdFlagSet)
AdminClientRecoverChainIdCmd.Flags().AddFlagSet(moduleFlagSet)
TemplateCmd.AddCommand(AdminClientRecoverChainIdCmd)
// flags for general-purpose governance call command
generalPurposeGovernanceFlagSet := pflag.NewFlagSet("general-purpose-governance", pflag.ExitOnError)
governanceContractAddress = generalPurposeGovernanceFlagSet.String("governance-contract", "", "Governance contract address")
governanceTargetAddress = generalPurposeGovernanceFlagSet.String("target-address", "", "Address of the governed contract")
governanceCallData = generalPurposeGovernanceFlagSet.String("call-data", "", "calldata")
governanceTargetChain = generalPurposeGovernanceFlagSet.String("chain-id", "", "Chain ID")
// evm call command
AdminClientGeneralPurposeGovernanceEvmCallCmd.Flags().AddFlagSet(generalPurposeGovernanceFlagSet)
TemplateCmd.AddCommand(AdminClientGeneralPurposeGovernanceEvmCallCmd)
// solana call command
AdminClientGeneralPurposeGovernanceSolanaCallCmd.Flags().AddFlagSet(generalPurposeGovernanceFlagSet)
TemplateCmd.AddCommand(AdminClientGeneralPurposeGovernanceSolanaCallCmd)
}
var TemplateCmd = &cobra.Command{
@ -292,6 +310,18 @@ var AdminClientWormholeRelayerSetDefaultDeliveryProviderCmd = &cobra.Command{
Run: runWormholeRelayerSetDefaultDeliveryProviderTemplate,
}
var AdminClientGeneralPurposeGovernanceEvmCallCmd = &cobra.Command{
Use: "governance-evm-call",
Short: "Generate a 'general purpose evm governance call' template for specified chain and address",
Run: runGeneralPurposeGovernanceEvmCallTemplate,
}
var AdminClientGeneralPurposeGovernanceSolanaCallCmd = &cobra.Command{
Use: "governance-solana-call",
Short: "Generate a 'general purpose solana governance call' template for specified chain and address",
Run: runGeneralPurposeGovernanceSolanaCallTemplate,
}
func runGuardianSetTemplate(cmd *cobra.Command, args []string) {
// Use deterministic devnet addresses as examples in the template, such that this doubles as a test fixture.
guardians := make([]*nodev1.GuardianSetUpdate_Guardian, *setUpdateNumGuardians)
@ -932,6 +962,100 @@ func runWormholeRelayerSetDefaultDeliveryProviderTemplate(cmd *cobra.Command, ar
fmt.Print(string(b))
}
func runGeneralPurposeGovernanceEvmCallTemplate(cmd *cobra.Command, args []string) {
if *governanceTargetAddress == "" {
log.Fatal("--target-address must be specified")
}
if !common.IsHexAddress(*governanceTargetAddress) {
log.Fatal("invalid target address")
}
governanceTargetAddress := common.HexToAddress(*governanceTargetAddress).Hex()
if *governanceCallData == "" {
log.Fatal("--call-data must be specified")
}
if *governanceContractAddress == "" {
log.Fatal("--governance-contract must be specified")
}
if !common.IsHexAddress(*governanceContractAddress) {
log.Fatal("invalid governance contract address")
}
governanceContractAddress := common.HexToAddress(*governanceContractAddress).Hex()
if *governanceTargetChain == "" {
log.Fatal("--chain-id must be specified")
}
chainID, err := parseChainID(*governanceTargetChain)
if err != nil {
log.Fatal("failed to parse chain id: ", err)
}
m := &nodev1.InjectGovernanceVAARequest{
CurrentSetIndex: uint32(*templateGuardianIndex),
Messages: []*nodev1.GovernanceMessage{
{
Sequence: rand.Uint64(),
Nonce: rand.Uint32(),
Payload: &nodev1.GovernanceMessage_EvmCall{
EvmCall: &nodev1.EvmCall{
ChainId: uint32(chainID),
GovernanceContract: governanceContractAddress,
TargetContract: governanceTargetAddress,
AbiEncodedCall: *governanceCallData,
},
},
},
},
}
b, err := prototext.MarshalOptions{Multiline: true}.Marshal(m)
if err != nil {
panic(err)
}
fmt.Print(string(b))
}
func runGeneralPurposeGovernanceSolanaCallTemplate(cmd *cobra.Command, args []string) {
if *governanceCallData == "" {
log.Fatal("--call-data must be specified")
}
if *governanceContractAddress == "" {
log.Fatal("--governance-contract must be specified")
}
_, err := base58.Decode(*governanceContractAddress)
if err != nil {
log.Fatal("invalid base58 governance contract address")
}
if *governanceTargetChain == "" {
log.Fatal("--chain-id must be specified")
}
chainID, err := parseChainID(*governanceTargetChain)
if err != nil {
log.Fatal("failed to parse chain id: ", err)
}
m := &nodev1.InjectGovernanceVAARequest{
CurrentSetIndex: uint32(*templateGuardianIndex),
Messages: []*nodev1.GovernanceMessage{
{
Sequence: rand.Uint64(),
Nonce: rand.Uint32(),
Payload: &nodev1.GovernanceMessage_SolanaCall{
SolanaCall: &nodev1.SolanaCall{
ChainId: uint32(chainID),
GovernanceContract: *governanceContractAddress,
EncodedInstruction: *governanceCallData,
},
},
},
},
}
b, err := prototext.MarshalOptions{Multiline: true}.Marshal(m)
if err != nil {
panic(err)
}
fmt.Print(string(b))
}
// parseAddress parses either a hex-encoded address and returns
// a left-padded 32 byte hex string.
func parseAddress(s string) (string, error) {

View File

@ -182,8 +182,10 @@ var (
xlayerRPC *string
xlayerContract *string
lineaRPC *string
lineaContract *string
lineaRPC *string
lineaContract *string
lineaRollUpUrl *string
lineaRollUpContract *string
berachainRPC *string
berachainContract *string
@ -386,6 +388,8 @@ func init() {
lineaRPC = node.RegisterFlagWithValidationOrFail(NodeCmd, "lineaRPC", "Linea RPC URL", "ws://eth-devnet:8545", []string{"ws", "wss"})
lineaContract = NodeCmd.Flags().String("lineaContract", "", "Linea contract address")
lineaRollUpUrl = NodeCmd.Flags().String("lineaRollUpUrl", "", "Linea roll up URL")
lineaRollUpContract = NodeCmd.Flags().String("lineaRollUpContract", "", "Linea roll up contract address")
berachainRPC = node.RegisterFlagWithValidationOrFail(NodeCmd, "berachainRPC", "Berachain RPC URL", "ws://eth-devnet:8545", []string{"ws", "wss"})
berachainContract = NodeCmd.Flags().String("berachainContract", "", "Berachain contract address")
@ -762,11 +766,6 @@ func runNode(cmd *cobra.Command, args []string) {
logger.Fatal("Both --baseContract and --baseRPC must be set together or both unset")
}
// Scroll should not be allowed in mainnet until its finality policy is understood and implemented in the watcher.
if *scrollRPC != "" && !*testnetMode && !*unsafeDevMode {
logger.Fatal("scroll is currently only supported in devnet and testnet")
}
if (*scrollRPC == "") != (*scrollContract == "") {
logger.Fatal("Both --scrollContract and --scrollRPC must be set together or both unset")
}
@ -779,10 +778,6 @@ func runNode(cmd *cobra.Command, args []string) {
logger.Fatal("Both --mantleContract and --mantleRPC must be set together or both unset")
}
if *blastRPC != "" && !*testnetMode && !*unsafeDevMode {
logger.Fatal("blast is currently only supported in devnet and testnet")
}
if (*blastRPC == "") != (*blastContract == "") {
logger.Fatal("Both --blastContract and --blastRPC must be set together or both unset")
}
@ -802,6 +797,9 @@ func runNode(cmd *cobra.Command, args []string) {
if (*lineaRPC == "") != (*lineaContract == "") {
logger.Fatal("Both --lineaContract and --lineaRPC must be set together or both unset")
}
if (*lineaRPC != "") && (*lineaRollUpUrl == "" || *lineaRollUpContract == "") && !*unsafeDevMode {
logger.Fatal("If --lineaRPC is specified, --lineaRollUpUrl and --lineaRollUpContract must also be specified")
}
if *berachainRPC != "" && !*testnetMode && !*unsafeDevMode {
logger.Fatal("berachain is currently only supported in devnet and testnet")
@ -996,10 +994,16 @@ func runNode(cmd *cobra.Command, args []string) {
if idx != 0 {
// try to connect to guardian-0
for {
// tilt uses this hostname format
_, err := net.LookupIP("guardian-0.guardian")
if err == nil {
break
}
// load tests use this hostname format
_, err = net.LookupIP("guardian-0")
if err == nil {
break
}
logger.Info("Error resolving guardian-0.guardian. Trying again...")
time.Sleep(time.Second)
}
@ -1144,6 +1148,10 @@ func runNode(cmd *cobra.Command, args []string) {
var accountantWormchainConn, accountantNttWormchainConn *wormconn.ClientConn
if *accountantContract != "" {
if *wormchainURL == "" {
logger.Fatal("if accountantContract is specified, wormchainURL is required", zap.String("component", "gacct"))
}
if *accountantKeyPath == "" {
logger.Fatal("if accountantContract is specified, accountantKeyPath is required", zap.String("component", "gacct"))
}
@ -1176,6 +1184,10 @@ func runNode(cmd *cobra.Command, args []string) {
// If the NTT accountant is enabled, create a wormchain connection for it.
if *accountantNttContract != "" {
if *wormchainURL == "" {
logger.Fatal("if accountantNttContract is specified, wormchainURL is required", zap.String("component", "gacct"))
}
if *accountantNttKeyPath == "" {
logger.Fatal("if accountantNttContract is specified, accountantNttKeyPath is required", zap.String("component", "gacct"))
}
@ -1506,11 +1518,13 @@ func runNode(cmd *cobra.Command, args []string) {
if shouldStart(lineaRPC) {
wc := &evm.WatcherConfig{
NetworkID: "linea",
ChainID: vaa.ChainIDLinea,
Rpc: *lineaRPC,
Contract: *lineaContract,
CcqBackfillCache: *ccqBackfillCache,
NetworkID: "linea",
ChainID: vaa.ChainIDLinea,
Rpc: *lineaRPC,
Contract: *lineaContract,
CcqBackfillCache: *ccqBackfillCache,
LineaRollUpUrl: *lineaRollUpUrl,
LineaRollUpContract: *lineaRollUpContract,
}
watcherConfigs = append(watcherConfigs, wc)

View File

@ -106,7 +106,7 @@ require (
github.com/cosmos/gorocksdb v1.2.0 // indirect
github.com/cosmos/iavl v0.19.4 // indirect
github.com/cosmos/ibc-go/v4 v4.2.2 // indirect
github.com/cosmos/ledger-cosmos-go v0.12.1 // indirect
github.com/cosmos/ledger-cosmos-go v0.12.4 // indirect
github.com/creachadair/taskgroup v0.3.2 // indirect
github.com/danieljoos/wincred v1.1.2 // indirect
github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c // indirect
@ -314,8 +314,8 @@ require (
github.com/weaveworks/common v0.0.0-20230531151736-e2613bee6b73 // indirect
github.com/weaveworks/promrus v1.2.0 // indirect
github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 // indirect
github.com/zondax/hid v0.9.1 // indirect
github.com/zondax/ledger-go v0.14.0 // indirect
github.com/zondax/hid v0.9.2 // indirect
github.com/zondax/ledger-go v0.14.3 // indirect
go.etcd.io/bbolt v1.3.6 // indirect
go.etcd.io/etcd/api/v3 v3.5.5 // indirect
go.etcd.io/etcd/client/pkg/v3 v3.5.5 // indirect

View File

@ -1036,8 +1036,8 @@ github.com/cosmos/ibc-go/v4 v4.2.2/go.mod h1:EFFqkrJHQPHWUlw155QUxGuis4Ett4lvewA
github.com/cosmos/interchain-accounts v0.2.4 h1:7UrroFQsCRSp17980mk6anx4YteveIJVkU+a0wlsHQI=
github.com/cosmos/interchain-accounts v0.2.4/go.mod h1:jeiJEb0zg609G0oCrCG0r6Guhb7YbA1uFiwww/1YgZE=
github.com/cosmos/ledger-cosmos-go v0.11.1/go.mod h1:J8//BsAGTo3OC/vDLjMRFLW6q0WAaXvHnVc7ZmE8iUY=
github.com/cosmos/ledger-cosmos-go v0.12.1 h1:sMBxza5p/rNK/06nBSNmsI/WDqI0pVJFVNihy1Y984w=
github.com/cosmos/ledger-cosmos-go v0.12.1/go.mod h1:dhO6kj+Y+AHIOgAe4L9HL/6NDdyyth4q238I9yFpD2g=
github.com/cosmos/ledger-cosmos-go v0.12.4 h1:drvWt+GJP7Aiw550yeb3ON/zsrgW0jgh5saFCr7pDnw=
github.com/cosmos/ledger-cosmos-go v0.12.4/go.mod h1:fjfVWRf++Xkygt9wzCsjEBdjcf7wiiY35fv3ctT+k4M=
github.com/cosmos/ledger-go v0.9.2/go.mod h1:oZJ2hHAZROdlHiwTg4t7kP+GKIIkBT+o6c9QWFanOyI=
github.com/cpuguy83/go-md2man v1.0.10 h1:BSKMNlYxDvnunlTymqtgONjNnaRV1sTpcovwwjF22jk=
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
@ -3153,10 +3153,10 @@ github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43/go.mod h1:aX
github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50/go.mod h1:NUSPSUX/bi6SeDMUh6brw0nXpxHnc96TguQh0+r/ssA=
github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f/go.mod h1:GlGEuHIJweS1mbCqG+7vt2nvWLzLLnRHbXz5JKd/Qbg=
github.com/zondax/hid v0.9.0/go.mod h1:l5wttcP0jwtdLjqjMMWFVEE7d1zO0jvSPA9OPZxWpEM=
github.com/zondax/hid v0.9.1 h1:gQe66rtmyZ8VeGFcOpbuH3r7erYtNEAezCAYu8LdkJo=
github.com/zondax/hid v0.9.1/go.mod h1:l5wttcP0jwtdLjqjMMWFVEE7d1zO0jvSPA9OPZxWpEM=
github.com/zondax/ledger-go v0.14.0 h1:dlMC7aO8Wss1CxBq2I96kZ69Nh1ligzbs8UWOtq/AsA=
github.com/zondax/ledger-go v0.14.0/go.mod h1:fZ3Dqg6qcdXWSOJFKMG8GCTnD7slO/RL2feOQv8K320=
github.com/zondax/hid v0.9.2 h1:WCJFnEDMiqGF64nlZz28E9qLVZ0KSJ7xpc5DLEyma2U=
github.com/zondax/hid v0.9.2/go.mod h1:l5wttcP0jwtdLjqjMMWFVEE7d1zO0jvSPA9OPZxWpEM=
github.com/zondax/ledger-go v0.14.3 h1:wEpJt2CEcBJ428md/5MgSLsXLBos98sBOyxNmCjfUCw=
github.com/zondax/ledger-go v0.14.3/go.mod h1:IKKaoxupuB43g4NxeQmbLXv7T9AlQyie1UpHb342ycI=
gitlab.com/bosi/decorder v0.2.1/go.mod h1:6C/nhLSbF6qZbYD8bRmISBwc6vcWdNsiIBkRvjJFrH0=
gitlab.com/bosi/decorder v0.2.3/go.mod h1:9K1RB5+VPNQYtXtTDAzd2OEftsZb1oV0IrJrzChSdGE=
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=

View File

@ -46,6 +46,8 @@ var etherscanAPIMap = map[vaa.ChainID]string{
vaa.ChainIDArbitrum: "https://api.arbiscan.io",
vaa.ChainIDOptimism: "https://api-optimistic.etherscan.io",
vaa.ChainIDBase: "https://api.basescan.org",
vaa.ChainIDScroll: "https://api.scrollscan.com",
vaa.ChainIDBlast: "https://api.blastscan.io",
}
var coreContractMap = map[vaa.ChainID]string{
@ -64,6 +66,8 @@ var coreContractMap = map[vaa.ChainID]string{
vaa.ChainIDArbitrum: strings.ToLower("0xa5f208e072434bC67592E4C49C1B991BA79BCA46"),
vaa.ChainIDOptimism: strings.ToLower("0xEe91C335eab126dF5fDB3797EA9d6aD93aeC9722"),
vaa.ChainIDBase: strings.ToLower("0xbebdb6C8ddC678FfA9f8748f85C815C556Dd8ac6"),
vaa.ChainIDScroll: strings.ToLower("0xbebdb6C8ddC678FfA9f8748f85C815C556Dd8ac6"),
vaa.ChainIDBlast: strings.ToLower("0xbebdb6C8ddC678FfA9f8748f85C815C556Dd8ac6 "),
}
var (

View File

@ -577,6 +577,58 @@ func wormholeRelayerSetDefaultDeliveryProvider(req *nodev1.WormholeRelayerSetDef
return v, nil
}
func evmCallToVaa(evmCall *nodev1.EvmCall, timestamp time.Time, guardianSetIndex, nonce uint32, sequence uint64) (*vaa.VAA, error) {
governanceContract := ethcommon.HexToAddress(evmCall.GovernanceContract)
targetContract := ethcommon.HexToAddress(evmCall.TargetContract)
payload, err := hex.DecodeString(evmCall.AbiEncodedCall)
if err != nil {
return nil, fmt.Errorf("failed to decode ABI encoded call: %w", err)
}
body, err := vaa.BodyGeneralPurposeGovernanceEvm{
ChainID: vaa.ChainID(evmCall.ChainId),
GovernanceContract: governanceContract,
TargetContract: targetContract,
Payload: payload,
}.Serialize()
if err != nil {
return nil, fmt.Errorf("failed to serialize governance body: %w", err)
}
v := vaa.CreateGovernanceVAA(timestamp, nonce, sequence, guardianSetIndex, body)
return v, nil
}
func solanaCallToVaa(solanaCall *nodev1.SolanaCall, timestamp time.Time, guardianSetIndex, nonce uint32, sequence uint64) (*vaa.VAA, error) {
address, err := base58.Decode(solanaCall.GovernanceContract)
if err != nil {
return nil, fmt.Errorf("failed to decode base58 governance contract address: %w", err)
}
if len(address) != 32 {
return nil, errors.New("invalid governance contract address length (expected 32 bytes)")
}
var governanceContract [32]byte
copy(governanceContract[:], address)
instruction, err := hex.DecodeString(solanaCall.EncodedInstruction)
if err != nil {
return nil, fmt.Errorf("failed to decode instruction: %w", err)
}
v := vaa.CreateGovernanceVAA(timestamp, nonce, sequence, guardianSetIndex,
vaa.BodyGeneralPurposeGovernanceSolana{
ChainID: vaa.ChainID(solanaCall.ChainId),
GovernanceContract: governanceContract,
Instruction: instruction,
}.Serialize())
return v, nil
}
func GovMsgToVaa(message *nodev1.GovernanceMessage, currentSetIndex uint32, timestamp time.Time) (*vaa.VAA, error) {
var (
v *vaa.VAA
@ -620,6 +672,10 @@ func GovMsgToVaa(message *nodev1.GovernanceMessage, currentSetIndex uint32, time
v, err = ibcUpdateChannelChain(payload.IbcUpdateChannelChain, timestamp, currentSetIndex, message.Nonce, message.Sequence)
case *nodev1.GovernanceMessage_WormholeRelayerSetDefaultDeliveryProvider:
v, err = wormholeRelayerSetDefaultDeliveryProvider(payload.WormholeRelayerSetDefaultDeliveryProvider, timestamp, currentSetIndex, message.Nonce, message.Sequence)
case *nodev1.GovernanceMessage_EvmCall:
v, err = evmCallToVaa(payload.EvmCall, timestamp, currentSetIndex, message.Nonce, message.Sequence)
case *nodev1.GovernanceMessage_SolanaCall:
v, err = solanaCallToVaa(payload.SolanaCall, timestamp, currentSetIndex, message.Nonce, message.Sequence)
default:
panic(fmt.Sprintf("unsupported VAA type: %T", payload))
}

View File

@ -0,0 +1,57 @@
package governor
// FlowCancelTokenList Returns a list of `tokenConfigEntry`s representing tokens that can 'Flow Cancel'. This means that incoming transfers
// that use these tokens can reduce the 'daily limit' of the Governor configured for the destination chain.
// The list of tokens was generated by grepping the file `generated_mainnet_tokens.go` for "USDC", "USDT", and "DAI".
//
// Note that the field `symbol` is unused. It is retained in this file only for convenience.
func FlowCancelTokenList() []tokenConfigEntry {
return []tokenConfigEntry{
// USDC variants
{chain: 2, addr: "000000000000000000000000bcca60bb61934080951369a648fb03df4f96263c", symbol: "aUSDC"},
{chain: 4, addr: "0000000000000000000000004268b8f0b87b6eae5d897996e6b845ddbd99adf3", symbol: "axlUSDC"},
{chain: 5, addr: "0000000000000000000000001a13f4ca1d028320a707d99520abfefca3998b7f", symbol: "amUSDC"},
{chain: 5, addr: "000000000000000000000000750e4c4984a9e0f12978ea6742bc1c5d248f40ed", symbol: "axlUSDC"},
{chain: 6, addr: "000000000000000000000000fab550568c688d5d8a52c7d794cb93edc26ec0ec", symbol: "axlUSDC"},
{chain: 6, addr: "000000000000000000000000a7d7079b0fead91f3e65f86e8915cb59c1a4c664", symbol: "USDC.e"},
{chain: 10, addr: "0000000000000000000000001b6382dbdea11d97f24495c9a90b7c88469134a4", symbol: "axlUSDC"},
{chain: 10, addr: "00000000000000000000000028a92dde19d9989f39a49905d7c9c2fac7799bdf", symbol: "USDC"},
{chain: 10, addr: "00000000000000000000000027e611fd27b276acbd5ffd632e5eaebec9761e40", symbol: "DAI+USDC"},
{chain: 13, addr: "000000000000000000000000754288077d0ff82af7a5317c7cb8c444d421d103", symbol: "oUSDC"},
{chain: 14, addr: "000000000000000000000000eb466342c4d449bc9f53a865d5cb90586f405215", symbol: "axlUSDC"},
{chain: 16, addr: "000000000000000000000000ca01a1d0993565291051daff390892518acfad3a", symbol: "axlUSDC"},
{chain: 23, addr: "000000000000000000000000625e7708f30ca75bfd92586e17077590c60eb4cd", symbol: "aArbUSDC"},
{chain: 24, addr: "000000000000000000000000625e7708f30ca75bfd92586e17077590c60eb4cd", symbol: "aOptUSDC"},
{chain: 30, addr: "000000000000000000000000eb466342c4d449bc9f53a865d5cb90586f405215", symbol: "axlUSDC"},
// USDT variants
{chain: 1, addr: "b7db4e83eb727f1187bd7a50303f5b4e4e943503da8571ad6564a51131504792", symbol: ""},
{chain: 1, addr: "ce010e60afedb22717bd63192f54145a3f965a33bb82d2c7029eb2ce1e208264", symbol: "USDT"},
{chain: 2, addr: "000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec7", symbol: "USDT"},
{chain: 4, addr: "00000000000000000000000055d398326f99059ff775485246999027b3197955", symbol: "USDT"},
{chain: 5, addr: "000000000000000000000000c2132d05d31c914a87c6611c10748aeb04b58e8f", symbol: "USDT"},
{chain: 6, addr: "0000000000000000000000009702230a8ea53601f5cd2dc00fdbc13d4df4a8c7", symbol: "USDt"},
{chain: 6, addr: "000000000000000000000000c7198437980c041c805a1edcba50c1ce5db95118", symbol: "USDT.e"},
{chain: 8, addr: "000000000000000000000000000000000000000000000000000000000004c5c1", symbol: "USDt"},
{chain: 9, addr: "0000000000000000000000004988a896b1227218e4a686fde5eabdcabd91571f", symbol: "USDT"},
{chain: 10, addr: "000000000000000000000000cc1b99ddac1a33c201a742a1851662e87bc7f22c", symbol: "USDT"},
{chain: 10, addr: "000000000000000000000000049d68029688eabf473097a2fc38ef61633a3c7a", symbol: "fUSDT"},
{chain: 13, addr: "000000000000000000000000cee8faf64bb97a73bb51e115aa89c17ffa8dd167", symbol: "oUSDT"},
{chain: 16, addr: "000000000000000000000000efaeee334f0fd1712f9a8cc375f427d9cdd40d73", symbol: "USDT"},
{chain: 16, addr: "000000000000000000000000ffffffffea09fb06d082fd1275cd48b191cbcd1d", symbol: "xcUSDT"},
{chain: 23, addr: "000000000000000000000000fd086bc7cd5c481dcc9c85ebe478a1c0b69fcbb9", symbol: "USDT"},
{chain: 24, addr: "00000000000000000000000094b008aa00579c1307b0ef2c499ad98a8ce58e58", symbol: "USDT"},
// DAI variants (DAI+USDC is included under the USDC list above)
{chain: 2, addr: "0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f", symbol: "DAI"},
{chain: 4, addr: "0000000000000000000000001af3f329e8be154074d8769d1ffa4ee058b1dbc3", symbol: "DAI"},
{chain: 5, addr: "0000000000000000000000008f3cf7ad23cd3cadbd9735aff958023239c6a063", symbol: "DAI"},
{chain: 6, addr: "000000000000000000000000d586e7f844cea2f87f50152665bcbc2c279d8d70", symbol: "DAI.e"},
{chain: 10, addr: "0000000000000000000000008d11ec38a3eb5e956b052f67da8bdc9bef8abf3e", symbol: "DAI"},
{chain: 13, addr: "0000000000000000000000005c74070fdea071359b86082bd9f9b3deaafbe32b", symbol: "KDAI"},
{chain: 16, addr: "000000000000000000000000765277eebeca2e31912c9946eae1021199b39c61", symbol: "DAI"},
{chain: 23, addr: "000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1", symbol: "DAI"},
{chain: 24, addr: "000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1", symbol: "DAI"},
{chain: 30, addr: "00000000000000000000000050c5725949a6f0c72e6c4a641f24049a917db0cb", symbol: "DAI"},
}
}

View File

@ -1,3 +1,5 @@
package governor
// The purpose of the Chain Governor is to limit the notional TVL that can leave a chain in a single day.
// It works by tracking transfers (types one and three) for a configured set of tokens from a configured set of emitters (chains).
//
@ -23,11 +25,10 @@
//
// To enable the chain governor, you must specified the --chainGovernorEnabled guardiand command line argument.
package governor
import (
"context"
"encoding/hex"
"errors"
"fmt"
"math"
"math/big"
@ -204,7 +205,14 @@ func (gov *ChainGovernor) initConfig() error {
}
key := tokenKey{chain: vaa.ChainID(ct.chain), addr: addr}
te := &tokenEntry{cfgPrice: cfgPrice, price: initialPrice, decimals: decimals, symbol: symbol, coinGeckoId: ct.coinGeckoId, token: key}
te := &tokenEntry{
cfgPrice: cfgPrice,
price: initialPrice,
decimals: decimals,
symbol: symbol,
coinGeckoId: ct.coinGeckoId,
token: key,
}
te.updatePrice()
gov.tokens[key] = te
@ -294,6 +302,10 @@ func (gov *ChainGovernor) ProcessMsg(msg *common.MessagePublication) bool {
}
func (gov *ChainGovernor) ProcessMsgForTime(msg *common.MessagePublication, now time.Time) (bool, error) {
// Validation:
// - ensure MessagePublication is not nil
// - check that the MessagePublication is governed
// - check that the message is not a duplicate
if msg == nil {
return false, fmt.Errorf("msg is nil")
}
@ -301,7 +313,7 @@ func (gov *ChainGovernor) ProcessMsgForTime(msg *common.MessagePublication, now
gov.mutex.Lock()
defer gov.mutex.Unlock()
msgIsGoverned, ce, token, payload, err := gov.parseMsgAlreadyLocked(msg)
msgIsGoverned, emitterChainEntry, token, payload, err := gov.parseMsgAlreadyLocked(msg)
if err != nil {
return false, err
}
@ -330,10 +342,11 @@ func (gov *ChainGovernor) ProcessMsgForTime(msg *common.MessagePublication, now
return true, nil
}
// Get all outgoing transfers for `emitterChainEntry` that happened within the last 24 hours
startTime := now.Add(-time.Minute * time.Duration(gov.dayLengthInMinutes))
prevTotalValue, err := gov.TrimAndSumValueForChain(ce, startTime)
prevTotalValue, err := gov.TrimAndSumValueForChain(emitterChainEntry, startTime)
if err != nil {
gov.logger.Error("failed to trim transfers",
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),
@ -342,6 +355,7 @@ func (gov *ChainGovernor) ProcessMsgForTime(msg *common.MessagePublication, now
return false, err
}
// Compute the notional USD value of the transfers
value, err := computeValue(payload.Amount, token)
if err != nil {
gov.logger.Error("failed to compute value of transfer",
@ -367,7 +381,7 @@ func (gov *ChainGovernor) ProcessMsgForTime(msg *common.MessagePublication, now
enqueueIt := false
var releaseTime time.Time
if ce.isBigTransfer(value) {
if emitterChainEntry.isBigTransfer(value) {
enqueueIt = true
releaseTime = now.Add(maxEnqueuedTime)
gov.logger.Error("enqueuing vaa because it is a big transaction",
@ -376,11 +390,11 @@ func (gov *ChainGovernor) ProcessMsgForTime(msg *common.MessagePublication, now
zap.Uint64("newTotalValue", newTotalValue),
zap.String("msgID", msg.MessageIDString()),
zap.Stringer("releaseTime", releaseTime),
zap.Uint64("bigTransactionSize", ce.bigTransactionSize),
zap.Uint64("bigTransactionSize", emitterChainEntry.bigTransactionSize),
zap.String("hash", hash),
zap.Stringer("txHash", msg.TxHash),
)
} else if newTotalValue > ce.dailyLimit {
} else if newTotalValue > emitterChainEntry.dailyLimit {
enqueueIt = true
releaseTime = now.Add(maxEnqueuedTime)
gov.logger.Error("enqueuing vaa because it would exceed the daily limit",
@ -407,7 +421,10 @@ func (gov *ChainGovernor) ProcessMsgForTime(msg *common.MessagePublication, now
return false, err
}
ce.pending = append(ce.pending, &pendingEntry{token: token, amount: payload.Amount, hash: hash, dbData: dbData})
emitterChainEntry.pending = append(
emitterChainEntry.pending,
&pendingEntry{token: token, amount: payload.Amount, hash: hash, dbData: dbData},
)
gov.msgsSeen[hash] = transferEnqueued
return false, nil
}
@ -421,7 +438,8 @@ func (gov *ChainGovernor) ProcessMsgForTime(msg *common.MessagePublication, now
zap.Stringer("txHash", msg.TxHash),
)
xfer := db.Transfer{Timestamp: now,
xfer := db.Transfer{
Timestamp: now,
Value: value,
OriginChain: token.token.chain,
OriginAddress: token.token.addr,
@ -442,7 +460,7 @@ func (gov *ChainGovernor) ProcessMsgForTime(msg *common.MessagePublication, now
return false, err
}
ce.transfers = append(ce.transfers, &xfer)
emitterChainEntry.transfers = append(emitterChainEntry.transfers, &xfer)
gov.msgsSeen[hash] = transferComplete
return true, nil
}
@ -456,19 +474,27 @@ func (gov *ChainGovernor) IsGovernedMsg(msg *common.MessagePublication) (msgIsGo
}
// parseMsgAlreadyLocked determines if the message applies to the governor and also returns data useful to the governor. It assumes the caller holds the lock.
func (gov *ChainGovernor) parseMsgAlreadyLocked(msg *common.MessagePublication) (bool, *chainEntry, *tokenEntry, *vaa.TransferPayloadHdr, error) {
func (gov *ChainGovernor) parseMsgAlreadyLocked(
msg *common.MessagePublication,
) (bool, *chainEntry, *tokenEntry, *vaa.TransferPayloadHdr, error) {
// If we don't care about this chain, the VAA can be published.
ce, exists := gov.chains[msg.EmitterChain]
if !exists {
if msg.EmitterChain != vaa.ChainIDPythNet {
gov.logger.Info("ignoring vaa because the emitter chain is not configured", zap.String("msgID", msg.MessageIDString()))
gov.logger.Info(
"ignoring vaa because the emitter chain is not configured",
zap.String("msgID", msg.MessageIDString()),
)
}
return false, nil, nil, nil, nil
}
// If we don't care about this emitter, the VAA can be published.
if msg.EmitterAddress != ce.emitterAddr {
gov.logger.Info("ignoring vaa because the emitter address is not configured", zap.String("msgID", msg.MessageIDString()))
gov.logger.Info(
"ignoring vaa because the emitter address is not configured",
zap.String("msgID", msg.MessageIDString()),
)
return false, nil, nil, nil, nil
}
@ -519,7 +545,7 @@ func (gov *ChainGovernor) CheckPendingForTime(now time.Time) ([]*common.MessageP
foundOne := false
prevTotalValue, err := gov.TrimAndSumValueForChain(ce, startTime)
if err != nil {
gov.logger.Error("failed to trim transfers", zap.Error(err))
gov.logger.Error("Error when attempting to trim and sum transfers", zap.Error(err))
gov.msgsToPublish = msgsToPublish
return nil, err
}
@ -656,11 +682,110 @@ func computeValue(amount *big.Int, token *tokenEntry) (uint64, error) {
return value, nil
}
func (gov *ChainGovernor) TrimAndSumValueForChain(ce *chainEntry, startTime time.Time) (sum uint64, err error) {
sum, ce.transfers, err = gov.TrimAndSumValue(ce.transfers, startTime)
return sum, err
// TrimAndSumValueForChain calculates the `sum` of `Transfer`s for a given chain `emitter`. In effect, it represents a
// chain's "Governor Usage" for a given 24 hour period.
// This sum may be reduced by the sum of 'flow cancelling' transfers: that is, transfers of an allow-listed token
// that have the `emitter` as their destination chain.
// The resulting `sum` return value therefore represents the net flow across a chain when taking flow-cancelling tokens
// into account. Therefore, this value should never be less than 0 and should never exceed the "Governor limit" for the chain.
//
// As a side-effect, this function modifies the parameter `emitter`, upating its `transfers` field so that it only includes
// filtered `Transfer`s (i.e. outgoing `Transfer`s newer than `startTime`).
//
// SECURITY Invariant: The `sum` return value should never be less than 0
// SECURITY Invariant: The `sum` return value should never exceed the "Governor limit" for the chain
func (gov *ChainGovernor) TrimAndSumValueForChain(emitter *chainEntry, startTime time.Time) (sum uint64, err error) {
// Sum the value of all outgoing transfers
var sumOutgoing uint64
sumOutgoing, emitter.transfers, err = gov.TrimAndSumValue(emitter.transfers, startTime)
if err != nil {
return 0, err
}
// Subtract the sum of all flow cancelling transfers. Here the emitter's chainID is actually used as the destination
// chain in in the context of FlowCancellingTransfersForChain.
flowCancelSum, err := gov.SumTransferValues(gov.FlowCancellingTransfersForChain(emitter.emitterChainId, startTime))
if err != nil {
return 0, err
}
// If flowCancelSum is larger than or equal to sumOutgoing, simply return 0 as this means that all outgoing
// transfers have been cancelled by incoming transfers.
// This also avoids integer underflow.
if flowCancelSum >= sumOutgoing {
return 0, nil
}
sum = sumOutgoing - flowCancelSum
if sum > emitter.dailyLimit {
return 0, fmt.Errorf(
"invariant violation: calculated sum %d exceeds Governor limit %d",
sum,
emitter.dailyLimit,
)
}
return sum, nil
}
// SumTransferValues iterates over a slice of transfers and sums their value.
func (gov *ChainGovernor) SumTransferValues(transfers []*db.Transfer) (sum uint64, err error) {
sum = 0
// Iterate over all transfers usin tokens that have flow cancelling enabled.
// If the destination chain of the transfer is equal to the `ce` parameter, add the value
// of the transfer to the flow cancelling sum.
for _, transfer := range transfers {
// Overflow check. Note that transfer.Value cannot be negative
if (sum + transfer.Value) < sum {
return 0, errors.New("overflow when calculating flow cancelling sum")
}
sum += transfer.Value
}
return sum, nil
}
// FlowCancellingTransfersForChain builds a list of Transfers that contain assets that can 'flow cancel'
// (reduce the Governor usage of) a governed chain represented by `destinationChainID`.
func (gov *ChainGovernor) FlowCancellingTransfersForChain(
destinationChainID vaa.ChainID,
startTime time.Time,
) (transfers []*db.Transfer) {
flowCancelTokens := FlowCancelTokenList()
// transfers = make([]*db.Transfer, 0)
// Iterate over all transfers for all governed chains
for _, emitterChainEntry := range gov.chains {
for _, transfer := range emitterChainEntry.transfers {
// We care about the transfer if:
// - Its target chain is equal to the `destinationChainID` parameter
// - It happened after `startTime`
// - It is a flow cancelling token (The transfer's origin chain and
// origin address match a hard-coded flow cancelling asset)
if transfer.TargetChain != destinationChainID {
continue
}
if transfer.Timestamp.Before(startTime) {
continue
}
for _, flowCancelToken := range flowCancelTokens {
// Compare flow cancel fields with transfer fields. This requires conversions:
// - vaa.ChainID to uint16
// - vaa.Address to String
if uint16(transfer.OriginChain) == flowCancelToken.chain &&
transfer.OriginAddress.String() == flowCancelToken.addr {
transfers = append(transfers, transfer)
}
}
}
}
return transfers
}
// TrimAndSumValue iterates over a slice of db.Transfer structs. It filters out transfers that have a Timestamp value that
// is earlier than the parameter `startTime`. The function then iterates over the remaining transfers, sums their Value,
// and returns the sum and the filtered transfers.
func (gov *ChainGovernor) TrimAndSumValue(transfers []*db.Transfer, startTime time.Time) (uint64, []*db.Transfer, error) {
if len(transfers) == 0 {
return 0, transfers, nil

View File

@ -49,7 +49,12 @@ func (gov *ChainGovernor) setDayLengthInMinutes(min int) {
gov.dayLengthInMinutes = min
}
func (gov *ChainGovernor) setChainForTesting(emitterChainId vaa.ChainID, emitterAddrStr string, dailyLimit uint64, bigTransactionSize uint64) error {
func (gov *ChainGovernor) setChainForTesting(
emitterChainId vaa.ChainID,
emitterAddrStr string,
dailyLimit uint64,
bigTransactionSize uint64,
) error {
gov.mutex.Lock()
defer gov.mutex.Unlock()
@ -70,7 +75,12 @@ func (gov *ChainGovernor) setChainForTesting(emitterChainId vaa.ChainID, emitter
return nil
}
func (gov *ChainGovernor) setTokenForTesting(tokenChainID vaa.ChainID, tokenAddrStr string, symbol string, price float64) error {
func (gov *ChainGovernor) setTokenForTesting(
tokenChainID vaa.ChainID,
tokenAddrStr string,
symbol string,
price float64,
) error {
gov.mutex.Lock()
defer gov.mutex.Unlock()
@ -163,6 +173,214 @@ func TestSumAllFromToday(t *testing.T) {
assert.Equal(t, 1, len(updatedTransfers))
}
func TestSumWithFlowCancelling(t *testing.T) {
// NOTE: Replace this Chain:Address pair if the Flow Cancel Token List is modified
var originChain vaa.ChainID = 2
var originAddress vaa.Address
originAddress, err := vaa.StringToAddress("000000000000000000000000bcca60bb61934080951369a648fb03df4f96263c")
require.NoError(t, err)
ctx := context.Background()
gov, err := newChainGovernorForTest(ctx)
require.NoError(t, err)
assert.NotNil(t, gov)
now, err := time.Parse("2006-Jan-02", "2024-Feb-19")
require.NoError(t, err)
var transfers_from_emitter []*db.Transfer
var transfers_that_flow_cancel []*db.Transfer
transferTime, err := time.Parse("2006-Jan-02", "2024-Feb-19")
require.NoError(t, err)
// Set up values and governor limit
emitterTransferValue := uint64(125000)
flowCancelValue := uint64(100000)
emitterLimit := emitterTransferValue * 2 // make sure the limit always exceeds the transfer value
emitterChainId := 1
// Setup transfers
// - Transfer from emitter: we only care about Value
// - Transfer that flow cancels: Transfer must be a valid entry from FlowCancelTokenList() (based on origin chain and origin address)
// and the desintation chain must be the same as the emitter chain
transfers_from_emitter = append(transfers_from_emitter, &db.Transfer{Value: emitterTransferValue, Timestamp: transferTime})
transfers_that_flow_cancel = append(
transfers_that_flow_cancel,
&db.Transfer{
OriginChain: originChain,
OriginAddress: originAddress,
TargetChain: vaa.ChainID(emitterChainId),
Value: flowCancelValue,
Timestamp: transferTime,
},
)
// Populate chainEntrys and ChainGovernor
emitter := &chainEntry{
transfers: transfers_from_emitter,
emitterChainId: vaa.ChainID(emitterChainId),
dailyLimit: emitterLimit,
}
chain_with_flow_cancel_transfers := &chainEntry{transfers: transfers_that_flow_cancel, emitterChainId: 2}
gov.chains[emitter.emitterChainId] = emitter
gov.chains[chain_with_flow_cancel_transfers.emitterChainId] = chain_with_flow_cancel_transfers
// XXX: sanity check
expectedNumTransfers := 1
sum, transfers, err := gov.TrimAndSumValue(emitter.transfers, now)
require.NoError(t, err)
assert.Equal(t, expectedNumTransfers, len(transfers))
assert.NotZero(t, sum)
// Calculate Governor Usage for emitter, including flow cancelling
sum, err = gov.TrimAndSumValueForChain(emitter, now.Add(-time.Hour*24))
require.NoError(t, err)
assert.Equal(t, emitterTransferValue-flowCancelValue, sum)
}
// Flow cancelling transfers are subtracted from the overall sum of all transfers from a given
// emitter chain. Since we are working with uint64 values, ensure that there is no underflow.
// When the sum of all flow cancelling transfers is greater than emitted transfers for a chain,
// the expected result is that the resulting Governor Usage equals 0 (and not a negative number
// or a very large underflow result).
// Also, the function should not return an error in this case.
func TestFlowCancelCannotUnderflow(t *testing.T) {
// NOTE: Replace this Chain:Address pair if the Flow Cancel Token List is modified
var originChain vaa.ChainID = 2
var originAddress vaa.Address
originAddress, err := vaa.StringToAddress("000000000000000000000000bcca60bb61934080951369a648fb03df4f96263c")
require.NoError(t, err)
ctx := context.Background()
gov, err := newChainGovernorForTest(ctx)
require.NoError(t, err)
assert.NotNil(t, gov)
now, err := time.Parse("2006-Jan-02", "2024-Feb-19")
require.NoError(t, err)
var transfers_from_emitter []*db.Transfer
var transfers_that_flow_cancel []*db.Transfer
transferTime, err := time.Parse("2006-Jan-02", "2024-Feb-19")
require.NoError(t, err)
// Set up values and governor limit
emitterTransferValue := uint64(100000)
flowCancelValue := emitterTransferValue + 25000 // make sure this value is higher than `emitterTransferValue`
emitterLimit := emitterTransferValue * 2 // make sure the limit always exceeds the transfer value
emitterChainId := 1
// Setup transfers
// - Transfer from emitter: we only care about Value
// - Transfer that flow cancels: Transfer must be a valid entry from FlowCancelTokenList() (based on origin chain and origin address)
// and the destination chain must be the same as the emitter chain
transfers_from_emitter = append(transfers_from_emitter, &db.Transfer{Value: emitterTransferValue, Timestamp: transferTime})
transfers_that_flow_cancel = append(
transfers_that_flow_cancel,
&db.Transfer{
OriginChain: originChain,
OriginAddress: originAddress,
TargetChain: vaa.ChainID(emitterChainId),
Value: flowCancelValue,
Timestamp: transferTime,
},
)
// Populate chainEntrys and ChainGovernor
emitter := &chainEntry{
transfers: transfers_from_emitter,
emitterChainId: vaa.ChainID(emitterChainId),
dailyLimit: emitterLimit,
}
chain_with_flow_cancel_transfers := &chainEntry{transfers: transfers_that_flow_cancel, emitterChainId: 2}
gov.chains[emitter.emitterChainId] = emitter
gov.chains[chain_with_flow_cancel_transfers.emitterChainId] = chain_with_flow_cancel_transfers
// XXX: sanity check: Sum of transfers without flow cancelling should be positive.
expectedNumTransfers := 1
sum, transfers, err := gov.TrimAndSumValue(emitter.transfers, now)
require.NoError(t, err)
assert.Equal(t, expectedNumTransfers, len(transfers))
assert.Greater(t, sum, uint64(0))
// Calculate Governor Usage for emitter, including flow cancelling
sum, err = gov.TrimAndSumValueForChain(emitter, now.Add(-time.Hour*24))
require.NoError(t, err)
assert.Zero(t, sum)
}
// Simulate a case where the total sum of transfers for a chain in a 24 hour period exceeds
// the configured Governor limit. This should never happen, so we make sure that an error
// is returned if the system is in this state
func TestInvariantGovernorLimit(t *testing.T) {
ctx := context.Background()
gov, err := newChainGovernorForTest(ctx)
require.NoError(t, err)
assert.NotNil(t, gov)
now, err := time.Parse("2006-Jan-02", "2024-Feb-19")
require.NoError(t, err)
var transfers_from_emitter []*db.Transfer
transferTime, err := time.Parse("2006-Jan-02", "2024-Feb-19")
require.NoError(t, err)
emitterTransferValue := uint64(125000)
emitterLimit := emitterTransferValue * 20
emitterChainId := 1
// Create a lot of transfers. Their total value should exceed `emitterLimit`
for i := 0; i < 25; i++ {
transfers_from_emitter = append(
transfers_from_emitter,
&db.Transfer{Value: emitterTransferValue, Timestamp: transferTime},
)
}
// Populate chainEntry and ChainGovernor
emitter := &chainEntry{
transfers: transfers_from_emitter,
emitterChainId: vaa.ChainID(emitterChainId),
dailyLimit: emitterLimit,
}
gov.chains[emitter.emitterChainId] = emitter
// XXX: sanity check
expectedNumTransfers := 25
sum, transfers, err := gov.TrimAndSumValue(emitter.transfers, now)
require.NoError(t, err)
assert.Equal(t, expectedNumTransfers, len(transfers))
assert.NotZero(t, sum)
// Make sure we trigger the Invariant
sum, err = gov.TrimAndSumValueForChain(emitter, now.Add(-time.Hour*24))
require.ErrorContains(t, err, "invariant violation: calculated sum")
assert.Zero(t, sum)
}
func TestInvariantSumOverflow(t *testing.T) {
ctx := context.Background()
gov, err := newChainGovernorForTest(ctx)
require.NoError(t, err)
assert.NotNil(t, gov)
transferTime, err := time.Parse("2006-Jan-02", "2024-Feb-19")
require.NoError(t, err)
var transfers []*db.Transfer
// Add two transfers. When summed, they should trigger an overflow
transfers = append(transfers, &db.Transfer{Value: math.MaxUint64, Timestamp: transferTime})
transfers = append(transfers, &db.Transfer{Value: 1, Timestamp: transferTime})
sum, err := gov.SumTransferValues(transfers)
require.ErrorContains(t, err, "overflow when calculating flow cancelling sum")
assert.Zero(t, sum)
}
func TestTrimOneOfTwoTransfers(t *testing.T) {
ctx := context.Background()
gov, err := newChainGovernorForTest(ctx)
@ -316,7 +534,7 @@ func TestVaaForUninterestingEmitterChain(t *testing.T) {
assert.NotNil(t, gov)
emitterAddr, _ := vaa.StringToAddress("0x00")
var payload = []byte{1, 97, 97, 97, 97, 97}
payload := []byte{1, 97, 97, 97, 97, 97}
msg := common.MessagePublication{
TxHash: hashFromString("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063"),
@ -348,7 +566,7 @@ func TestVaaForUninterestingEmitterAddress(t *testing.T) {
assert.NotNil(t, gov)
emitterAddr, _ := vaa.StringToAddress("0x00")
var payload = []byte{1, 97, 97, 97, 97, 97}
payload := []byte{1, 97, 97, 97, 97, 97}
msg := common.MessagePublication{
TxHash: hashFromString("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063"),
@ -381,7 +599,7 @@ func TestVaaForUninterestingPayloadType(t *testing.T) {
assert.NotNil(t, gov)
emitterAddr, _ := vaa.StringToAddress("0x0290fb167208af455bb137780163b7b7a9a10c16")
var payload = []byte{2, 97, 97, 97, 97, 97}
payload := []byte{2, 97, 97, 97, 97, 97}
msg := common.MessagePublication{
TxHash: hashFromString("0x06f541f5ecfc43407c31587aa6ac3a689e8960f36dc23c332db5510dfc6a4063"),

View File

@ -35,6 +35,8 @@ func chainList() []chainConfigEntry {
{emitterChainID: vaa.ChainIDXpla, dailyLimit: 500_000, bigTransactionSize: 50_000},
{emitterChainID: vaa.ChainIDBase, dailyLimit: 2_000_000, bigTransactionSize: 200_000},
{emitterChainID: vaa.ChainIDSei, dailyLimit: 5_000_000, bigTransactionSize: 500_000},
{emitterChainID: vaa.ChainIDScroll, dailyLimit: 500_000, bigTransactionSize: 50_000},
{emitterChainID: vaa.ChainIDBlast, dailyLimit: 500_000, bigTransactionSize: 50_000},
{emitterChainID: vaa.ChainIDWormchain, dailyLimit: 500_000, bigTransactionSize: 50_000},
}
}

View File

@ -14,5 +14,37 @@ func manualTokenList() []tokenConfigEntry {
{chain: 13, addr: "0000000000000000000000005096db80b21ef45230c9e423c373f1fc9c0198dd", symbol: "WEMIX", coinGeckoId: "wemix-token", decimals: 8, price: 1.74},
{chain: 15, addr: "0000000000000000000000000000000000000000000000000000000000000000", symbol: "NEAR", coinGeckoId: "near", decimals: 8, price: 3.85},
{chain: 32, addr: "00881043998ff2b738519d444d2dd0da3da4545de08290c1076746538d5333df", symbol: "Sei", coinGeckoId: "sei-network", decimals: 6, price: 0.0},
// BLAST (tokens over $50,000 24h volume)
{chain: 36, addr: "0000000000000000000000004300000000000000000000000000000000000003", symbol: "USDB", coinGeckoId: "usdb", decimals: 18, price: 1.00},
{chain: 36, addr: "0000000000000000000000004300000000000000000000000000000000000004", symbol: "WETH", coinGeckoId: "weth", decimals: 18, price: 3157.42},
{chain: 36, addr: "0000000000000000000000002416092f143378750bb29b79ed961ab195cceea5", symbol: "EZETH", coinGeckoId: "renzo-restaked-eth", decimals: 18, price: 3092.32},
{chain: 36, addr: "0000000000000000000000004fee793d435c6d2c10c135983bb9d6d4fc7b9bbd", symbol: "USD+", coinGeckoId: "usd", decimals: 18, price: 1.00},
{chain: 36, addr: "000000000000000000000000818a92bc81aad0053d72ba753fb5bc3d0c5c0923", symbol: "JUICE", coinGeckoId: "juice-finance", decimals: 18, price: 0.1051},
{chain: 36, addr: "0000000000000000000000009e20461bc2c4c980f62f1b279d71734207a6a356", symbol: "OMNI", coinGeckoId: "omnicat", decimals: 18, price: 0.0004575},
{chain: 36, addr: "000000000000000000000000764933fbad8f5d04ccd088602096655c2ed9879f", symbol: "AI", coinGeckoId: "any-inu", decimals: 18, price: 0.00002742},
{chain: 36, addr: "0000000000000000000000005ffd9ebd27f2fcab044c0f0a26a45cb62fa29c06", symbol: "PAC", coinGeckoId: "pacmoon", decimals: 18, price: 0.05459},
{chain: 36, addr: "00000000000000000000000020fe91f17ec9080e3cac2d688b4ecb48c5ac3a9c", symbol: "YES", coinGeckoId: "yes-money", decimals: 18, price: 3.96},
{chain: 36, addr: "00000000000000000000000076da31d7c9cbeae102aff34d3398bc450c8374c1", symbol: "MIM", coinGeckoId: "magic-internet-money", decimals: 18, price: 0.9935},
{chain: 36, addr: "00000000000000000000000015d24de366f69b835be19f7cf9447e770315dd80", symbol: "KAP", coinGeckoId: "kapital-dao", decimals: 18, price: 0.1143},
{chain: 36, addr: "000000000000000000000000b9dfcd4cf589bb8090569cb52fac1b88dbe4981f", symbol: "BAG", coinGeckoId: "bag", decimals: 18, price: 0.002972},
{chain: 36, addr: "00000000000000000000000068449870eea84453044bd430822827e21fd8f101", symbol: "ZAI", coinGeckoId: "zaibot", decimals: 18, price: 0.2348},
{chain: 36, addr: "00000000000000000000000047c337bd5b9344a6f3d6f58c474d9d8cd419d8ca", symbol: "DACKIE", coinGeckoId: "dackieswap", decimals: 18, price: 0.006554},
{chain: 36, addr: "000000000000000000000000d43d8adac6a4c7d9aeece7c3151fca8f23752cf8", symbol: "ANDY", coinGeckoId: "andyerc", decimals: 9, price: 0.1165},
{chain: 36, addr: "00000000000000000000000087e154e86fb691ab8a27116e93ed8d54e2b8c18c", symbol: "TES", coinGeckoId: "titan-trading-token", decimals: 18, price: 0.867},
{chain: 36, addr: "000000000000000000000000870a8f46b62b8bdeda4c02530c1750cddf2ed32e", symbol: "USDC+", coinGeckoId: "usdc-plus-overnight", decimals: 18, price: 1.00},
{chain: 36, addr: "00000000000000000000000042e12d42b3d6c4a74a88a61063856756ea2db357", symbol: "ORBIT", coinGeckoId: "orbit-protocol", decimals: 18, price: 0.3074},
// SCROLL (tokens over $50,000 24h volume)
{chain: 34, addr: "0000000000000000000000000018d96c579121a94307249d47f053e2d687b5e7", symbol: "MVX", coinGeckoId: "metavault-trade", decimals: 18, price: 2.06},
{chain: 34, addr: "00000000000000000000000047c337bd5b9344a6f3d6f58c474d9d8cd419d8ca", symbol: "DACKIE", coinGeckoId: "dackieswap", decimals: 18, price: 0.00655},
{chain: 34, addr: "0000000000000000000000005300000000000000000000000000000000000004", symbol: "WETH", coinGeckoId: "bridged-wrapped-ether-scroll", decimals: 18, price: 3145.98},
{chain: 34, addr: "000000000000000000000000f55bec9cafdbe8730f096aa55dad6d22d44099df", symbol: "USDT", coinGeckoId: "bridged-tether-scroll", decimals: 6, price: 1.00},
{chain: 34, addr: "00000000000000000000000006efdbff2a14a7c8e15944d1f4a48f9f95f663a4", symbol: "USDC", coinGeckoId: "bridged-usd-coin-scroll", decimals: 6, price: 1.00},
{chain: 34, addr: "000000000000000000000000eb466342c4d449bc9f53a865d5cb90586f405215", symbol: "AXLUSDC", coinGeckoId: "bridged-axelar-wrapped-usd-coin-scroll", decimals: 6, price: 1.01},
{chain: 34, addr: "0000000000000000000000003c1bca5a656e69edcd0d4e36bebb3fcdaca60cf1", symbol: "WBTC", coinGeckoId: "bridged-wrapped-bitcoin-scroll", decimals: 8, price: 64415.17},
{chain: 34, addr: "00000000000000000000000060d01ec2d5e98ac51c8b4cf84dfcce98d527c747", symbol: "IZI", coinGeckoId: "izumi-finance", decimals: 18, price: 0.0142},
{chain: 34, addr: "0000000000000000000000000a3bb08b3a15a19b4de82f8acfc862606fb69a2d", symbol: "IUSD", coinGeckoId: "izumi-bond-usd", decimals: 18, price: 0.9195},
{chain: 34, addr: "000000000000000000000000f610a9dfb7c89644979b4a0f27063e9e7d7cda32", symbol: "WSTETH", coinGeckoId: "bridged-wrapped-lido-staked-ether-scroll", decimals: 18, price: 3659.28},
{chain: 34, addr: "000000000000000000000000cA77eB3fEFe3725Dc33bccB54eDEFc3D9f764f97", symbol: "DAI", coinGeckoId: "dai", decimals: 18, price: 1.00},
{chain: 34, addr: "00000000000000000000000053878B874283351D26d206FA512aEcE1Bef6C0dD", symbol: "RETH", coinGeckoId: "rocket-pool-eth", decimals: 18, price: 3475.55},
}
}

View File

@ -147,7 +147,7 @@ func GuardianOptionAccountant(
}
if websocket == "" {
return errors.New("if accountantContract is specified, accountantWS is required")
return errors.New("if either accountantContract or accountantNttContract is specified, accountantWS is required")
}
if contract != "" {
if wormchainConn == nil {

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,8 @@
package evm
import (
"errors"
"github.com/certusone/wormhole/node/pkg/common"
gossipv1 "github.com/certusone/wormhole/node/pkg/proto/gossip/v1"
"github.com/certusone/wormhole/node/pkg/query"
@ -20,6 +22,10 @@ type WatcherConfig struct {
L1FinalizerRequired watchers.NetworkID // (optional)
l1Finalizer interfaces.L1Finalizer
CcqBackfillCache bool
// These parameters are currently only used for Linea and should be set via SetLineaParams()
LineaRollUpUrl string
LineaRollUpContract string
}
func (wc *WatcherConfig) GetNetworkID() watchers.NetworkID {
@ -57,5 +63,12 @@ func (wc *WatcherConfig) Create(
watcher := NewEthWatcher(wc.Rpc, eth_common.HexToAddress(wc.Contract), string(wc.NetworkID), wc.ChainID, msgC, setWriteC, obsvReqC, queryReqC, queryResponseC, devMode, wc.CcqBackfillCache)
watcher.SetL1Finalizer(wc.l1Finalizer)
if wc.ChainID == vaa.ChainIDLinea {
if err := watcher.SetLineaParams(wc.LineaRollUpUrl, wc.LineaRollUpContract); err != nil {
return nil, nil, err
}
} else if wc.LineaRollUpUrl != "" || wc.LineaRollUpContract != "" {
return nil, nil, errors.New("LineaRollUpUrl and LineaRollUpContract may only be specified for Linea")
}
return watcher, watcher.Run, nil
}

View File

@ -0,0 +1,218 @@
// A block is considered finalized on Linea when it is marked finalized by the LineaRollup contract on Ethereum.
//
// For a discussion of finality on Linea, see here:
// https://www.notion.so/wormholefoundation/Testnet-Info-V2-633e4aa64a634d56a7ce07a103789774?pvs=4#03513c2eb3654d33aff2206a562d25b1
//
// The LineaRollup proxy contract on ethereum is available at the following addresses:
// Mainnet: 0xd19d4B5d358258f05D7B411E21A1460D11B0876F
// Testnet: 0xB218f8A4Bc926cF1cA7b3423c154a0D627Bdb7E5
//
// To generate the golang abi for the LineaRollup contract:
// - Grab the ABIs from the LineaRollup contract (not the proxy) (0x934Dd4C63E285551CEceF8459103554D0096c179 on Ethereum mainnet) and put it in /tmp/LineaRollup.abi.
// - mkdir node/pkg/watchers/evm/connectors/lineaabi
// - Install abigen: go install github.com/ethereum/go-ethereum/cmd/abigen@latest
// - abigen --abi /tmp/LineaRollup.abi --pkg lineaabi --out node/pkg/watchers/evm/connectors/lineaabi/LineaRollup.go
package connectors
import (
"context"
"fmt"
"time"
"github.com/certusone/wormhole/node/pkg/common"
rollUpAbi "github.com/certusone/wormhole/node/pkg/watchers/evm/connectors/lineaabi"
ethereum "github.com/ethereum/go-ethereum"
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"
"go.uber.org/zap"
)
// LineaConnector listens for new finalized blocks for Linea by reading the roll up contract on Ethereum.
type LineaConnector struct {
Connector
logger *zap.Logger
// These are used for querying the roll up contract.
rollUpRawClient *ethRpc.Client
rollUpClient *ethClient.Client
// These are used to subscribe for new block finalized events from the roll up contract.
rollUpFilterer *rollUpAbi.LineaabiFilterer
rollUpCaller *rollUpAbi.LineaabiCaller
latestBlockNum uint64
latestFinalizedBlockNum uint64
}
// NewLineaConnector creates a new Linea poll connector using the specified roll up contract.
func NewLineaConnector(
ctx context.Context,
logger *zap.Logger,
baseConnector Connector,
rollUpUrl string,
rollUpAddress string,
) (*LineaConnector, error) {
rollUpRawClient, err := ethRpc.DialContext(ctx, rollUpUrl)
if err != nil {
return nil, fmt.Errorf("failed to create roll up raw client for url %s: %w", rollUpUrl, err)
}
rollUpClient := ethClient.NewClient(rollUpRawClient)
addr := ethCommon.HexToAddress(rollUpAddress)
rollUpFilterer, err := rollUpAbi.NewLineaabiFilterer(addr, rollUpClient)
if err != nil {
return nil, fmt.Errorf("failed to create roll up filter for url %s: %w", rollUpUrl, err)
}
rollUpCaller, err := rollUpAbi.NewLineaabiCaller(addr, rollUpClient)
if err != nil {
return nil, fmt.Errorf("failed to create roll up caller for url %s: %w", rollUpUrl, err)
}
logger.Info("Using roll up for Linea", zap.String("rollUpUrl", rollUpUrl), zap.String("rollUpAddress", rollUpAddress))
connector := &LineaConnector{
Connector: baseConnector,
logger: logger,
rollUpRawClient: rollUpRawClient,
rollUpClient: rollUpClient,
rollUpFilterer: rollUpFilterer,
rollUpCaller: rollUpCaller,
}
return connector, nil
}
// SubscribeForBlocks starts polling. It implements the standard connector interface.
func (c *LineaConnector) SubscribeForBlocks(ctx context.Context, errC chan error, sink chan<- *NewBlock) (ethereum.Subscription, error) {
timeout, cancel := context.WithTimeout(ctx, 15*time.Second)
defer cancel()
// Use the standard geth head sink to get latest blocks.
headSink := make(chan *ethTypes.Header, 2)
headerSubscription, err := c.Connector.Client().SubscribeNewHead(ctx, headSink)
if err != nil {
return nil, fmt.Errorf("failed to subscribe for latest blocks: %w", err)
}
// Subscribe to data finalized events from the roll up contract.
dataFinalizedChan := make(chan *rollUpAbi.LineaabiDataFinalized, 2)
dataFinalizedSub, err := c.rollUpFilterer.WatchDataFinalized(&ethBind.WatchOpts{Context: timeout}, dataFinalizedChan, nil, nil, nil)
if err != nil {
return nil, fmt.Errorf("failed to subscribe for events from roll up contract: %w", err)
}
// Get the current latest block on Linea.
latestBlock, err := GetBlockByFinality(timeout, c.logger, c.Connector, Latest)
if err != nil {
return nil, fmt.Errorf("failed to get current latest block: %w", err)
}
c.latestBlockNum = latestBlock.Number.Uint64()
// Get and publish the current latest finalized block.
opts := &ethBind.CallOpts{Context: timeout}
initialBlock, err := c.rollUpCaller.CurrentL2BlockNumber(opts)
if err != nil {
return nil, fmt.Errorf("failed to get initial block: %w", err)
}
c.latestFinalizedBlockNum = initialBlock.Uint64()
if c.latestFinalizedBlockNum > c.latestBlockNum {
return nil, fmt.Errorf("latest finalized block reported by L1 (%d) is ahead of latest block reported by L2 (%d), L2 node seems to be stuck",
c.latestFinalizedBlockNum, c.latestBlockNum)
}
c.logger.Info("queried initial finalized block", zap.Uint64("initialBlock", c.latestFinalizedBlockNum), zap.Uint64("latestBlock", c.latestBlockNum))
if err = c.postFinalizedAndSafe(ctx, c.latestFinalizedBlockNum, sink); err != nil {
return nil, fmt.Errorf("failed to post initial block: %w", err)
}
common.RunWithScissors(ctx, errC, "linea_block_poller", func(ctx context.Context) error {
for {
select {
case <-ctx.Done():
dataFinalizedSub.Unsubscribe()
return nil
case err := <-dataFinalizedSub.Err():
errC <- fmt.Errorf("finalized data watcher posted an error: %w", err)
dataFinalizedSub.Unsubscribe()
return nil
case evt := <-dataFinalizedChan:
if err := c.processDataFinalizedEvent(ctx, sink, evt); err != nil {
errC <- fmt.Errorf("failed to process block finalized event: %w", err)
dataFinalizedSub.Unsubscribe()
return nil
}
case ev := <-headSink:
if ev == nil {
c.logger.Error("new latest header event is nil")
continue
}
if ev.Number == nil {
c.logger.Error("new latest header block number is nil")
continue
}
c.latestBlockNum = ev.Number.Uint64()
sink <- &NewBlock{
Number: ev.Number,
Time: ev.Time,
Hash: ev.Hash(),
Finality: Latest,
}
}
}
})
return headerSubscription, nil
}
// processDataFinalizedEvent handles a DataFinalized event published by the roll up contract.
func (c *LineaConnector) processDataFinalizedEvent(ctx context.Context, sink chan<- *NewBlock, evt *rollUpAbi.LineaabiDataFinalized) error {
latestFinalizedBlockNum := evt.LastBlockFinalized.Uint64()
// Leaving this log info in for now because these events come very infrequently.
c.logger.Info("processing data finalized event",
zap.Uint64("latestFinalizedBlockNum", latestFinalizedBlockNum),
zap.Uint64("prevFinalizedBlockNum", c.latestFinalizedBlockNum),
)
if latestFinalizedBlockNum > c.latestBlockNum {
return fmt.Errorf("latest finalized block reported by L1 (%d) is ahead of latest block reported by L2 (%d), L2 node seems to be stuck",
latestFinalizedBlockNum, c.latestBlockNum)
}
for blockNum := c.latestFinalizedBlockNum + 1; blockNum <= latestFinalizedBlockNum; blockNum++ {
if err := c.postFinalizedAndSafe(ctx, blockNum, sink); err != nil {
c.latestFinalizedBlockNum = blockNum - 1
return fmt.Errorf("failed to post block %d: %w", blockNum, err)
}
}
c.latestFinalizedBlockNum = latestFinalizedBlockNum
return nil
}
// postFinalizedAndSafe publishes a block as finalized and safe. It takes a block number and looks it up on chain to publish the current values.
func (c *LineaConnector) postFinalizedAndSafe(ctx context.Context, blockNum uint64, sink chan<- *NewBlock) error {
timeout, cancel := context.WithTimeout(ctx, 15*time.Second)
defer cancel()
block, err := GetBlockByNumberUint64(timeout, c.logger, c.Connector, blockNum, Finalized)
if err != nil {
return fmt.Errorf("failed to get block %d: %w", blockNum, err)
}
// Publish the finalized block.
sink <- block
// Publish same thing for the safe block.
sink <- block.Copy(Safe)
return nil
}

File diff suppressed because one or more lines are too long

View File

@ -2,6 +2,7 @@ package evm
import (
"context"
"errors"
"fmt"
"math"
"math/big"
@ -136,6 +137,10 @@ type (
ccqBatchSize int64
ccqBackfillCache bool
ccqLogger *zap.Logger
// These parameters are currently only used for Linea and should be set via SetLineaParams()
lineaRollUpUrl string
lineaRollUpContract string
}
pendingKey struct {
@ -242,6 +247,19 @@ func (w *Watcher) Run(parentCtx context.Context) error {
p2p.DefaultRegistry.AddErrorCount(w.chainID, 1)
return fmt.Errorf("dialing eth client failed: %w", err)
}
} else if w.chainID == vaa.ChainIDLinea {
baseConnector, err := connectors.NewEthereumBaseConnector(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)
}
w.ethConn, err = connectors.NewLineaConnector(ctx, logger, baseConnector, w.lineaRollUpUrl, w.lineaRollUpContract)
if err != nil {
ethConnectionErrors.WithLabelValues(w.networkName, "dial_error").Inc()
p2p.DefaultRegistry.AddErrorCount(w.chainID, 1)
return fmt.Errorf("failed to create Linea poller: %w", err)
}
} else {
// Everything else is instant finality.
logger.Info("assuming instant finality")
@ -699,41 +717,61 @@ func fetchCurrentGuardianSet(ctx context.Context, ethConn connectors.Connector)
// getFinality determines if the chain supports "finalized" and "safe". This is hard coded so it requires thought to change something. However, it also reads the RPC
// to make sure the node actually supports the expected values, and returns an error if it doesn't. Note that we do not support using safe mode but not finalized mode.
func (w *Watcher) getFinality(ctx context.Context) (bool, bool, error) {
// TODO: Need to handle finality for Linea before it can be deployed in Mainnet.
finalized := false
safe := false
// Tilt supports polling for both finalized and safe.
if w.unsafeDevMode {
finalized = true
safe = true
// The following chains support polling for both finalized and safe.
} else if w.chainID == vaa.ChainIDAcala ||
w.chainID == vaa.ChainIDArbitrum ||
w.chainID == vaa.ChainIDArbitrumSepolia ||
w.chainID == vaa.ChainIDBase ||
w.chainID == vaa.ChainIDBaseSepolia ||
w.chainID == vaa.ChainIDBlast ||
w.chainID == vaa.ChainIDBSC ||
w.chainID == vaa.ChainIDEthereum ||
w.chainID == vaa.ChainIDHolesky ||
w.chainID == vaa.ChainIDKarura ||
w.chainID == vaa.ChainIDMantle ||
w.chainID == vaa.ChainIDMoonbeam ||
w.chainID == vaa.ChainIDOptimism ||
w.chainID == vaa.ChainIDSepolia ||
w.chainID == vaa.ChainIDHolesky ||
w.chainID == vaa.ChainIDArbitrumSepolia ||
w.chainID == vaa.ChainIDBaseSepolia ||
w.chainID == vaa.ChainIDOptimismSepolia ||
w.chainID == vaa.ChainIDSepolia ||
w.chainID == vaa.ChainIDXLayer {
finalized = true
safe = true
} else if w.chainID == vaa.ChainIDScroll {
// As of 11/10/2023 Scroll supports polling for finalized but not safe.
finalized = true
} else if w.chainID == vaa.ChainIDPolygon ||
w.chainID == vaa.ChainIDPolygonSepolia {
// The following chains have their own specialized finalizers.
} else if w.chainID == vaa.ChainIDCelo ||
w.chainID == vaa.ChainIDLinea {
return false, false, nil
// 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
} else if w.chainID == vaa.ChainIDPolygon ||
w.chainID == vaa.ChainIDPolygonSepolia {
finalized = true
} else if w.chainID == vaa.ChainIDBerachain {
// Berachain supports instant finality: https://docs.berachain.com/faq/
// As of 11/10/2023 Scroll supports polling for finalized but not safe.
} else if w.chainID == vaa.ChainIDScroll {
finalized = true
// The following chains support instant finality.
} else if w.chainID == vaa.ChainIDAvalanche ||
w.chainID == vaa.ChainIDBerachain || // Berachain supports instant finality: https://docs.berachain.com/faq/
w.chainID == vaa.ChainIDOasis ||
w.chainID == vaa.ChainIDAurora ||
w.chainID == vaa.ChainIDFantom ||
w.chainID == vaa.ChainIDKlaytn {
return false, false, nil
// Anything else is undefined / not supported.
} else {
return false, false, fmt.Errorf("unsupported chain: %s", w.chainID.String())
}
// If finalized / safe should be supported, read the RPC to make sure they actually are.
@ -935,3 +973,22 @@ func (w *Watcher) waitForBlockTime(ctx context.Context, logger *zap.Logger, errC
func msgIdFromLogEvent(chainID vaa.ChainID, ev *ethabi.AbiLogMessagePublished) string {
return fmt.Sprintf("%v/%v/%v", uint16(chainID), PadAddress(ev.Sender), ev.Sequence)
}
// SetLineaParams is used to enable polling on Linea using the roll up contract on Ethereum.
func (w *Watcher) SetLineaParams(lineaRollUpUrl string, lineaRollUpContract string) error {
if w.chainID != vaa.ChainIDLinea {
return errors.New("function only allowed for Linea")
}
if w.unsafeDevMode && lineaRollUpUrl == "" && lineaRollUpContract == "" {
return nil
}
if lineaRollUpUrl == "" {
return fmt.Errorf("lineaRollUpUrl must be set")
}
if lineaRollUpContract == "" {
return fmt.Errorf("lineaRollUpContract must be set")
}
w.lineaRollUpUrl = lineaRollUpUrl
w.lineaRollUpContract = lineaRollUpContract
return nil
}

View File

@ -40,7 +40,7 @@ service NodePrivilegedService {
// ChainGovernorReleasePendingVAA release a VAA from the chain governor pending list, publishing it immediately.
rpc ChainGovernorReleasePendingVAA (ChainGovernorReleasePendingVAARequest) returns (ChainGovernorReleasePendingVAAResponse);
// ChainGovernorResetReleaseTimer resets the release timer for a chain governor pending VAA to the configured maximum.
rpc ChainGovernorResetReleaseTimer (ChainGovernorResetReleaseTimerRequest) returns (ChainGovernorResetReleaseTimerResponse);
@ -51,10 +51,10 @@ service NodePrivilegedService {
rpc SignExistingVAA (SignExistingVAARequest) returns (SignExistingVAAResponse);
// DumpRPCs returns the RPCs being used by the guardian
rpc DumpRPCs (DumpRPCsRequest) returns (DumpRPCsResponse);
rpc DumpRPCs (DumpRPCsRequest) returns (DumpRPCsResponse);
// GetMissingVAAs returns the VAAs from a cloud function that need to be reobserved.
rpc GetAndObserveMissingVAAs (GetAndObserveMissingVAAsRequest) returns (GetAndObserveMissingVAAsResponse);
rpc GetAndObserveMissingVAAs (GetAndObserveMissingVAAsRequest) returns (GetAndObserveMissingVAAsResponse);
}
message InjectGovernanceVAARequest {
@ -85,7 +85,7 @@ message GovernanceMessage {
GuardianSetUpdate guardian_set = 10;
ContractUpgrade contract_upgrade = 11;
// Token bridge, NFT module, and Wormhole Relayer module (for the first two)
// Token bridge, NFT module, and Wormhole Relayer module (for the first two)
BridgeRegisterChain bridge_register_chain = 12;
BridgeUpgradeContract bridge_contract_upgrade = 13;
@ -117,6 +117,10 @@ message GovernanceMessage {
IbcUpdateChannelChain ibc_update_channel_chain = 21;
// Wormhole Relayer module
WormholeRelayerSetDefaultDeliveryProvider wormhole_relayer_set_default_delivery_provider = 22;
// Generic governance
EvmCall evm_call = 28;
SolanaCall solana_call = 29;
}
}
@ -191,7 +195,7 @@ message AccountantModifyBalance {
// ContractUpgrade represents a Wormhole contract update to be submitted to and signed by the node.
message ContractUpgrade {
// ID of the chain where the Wormhole contract should be updated (uint8).
// ID of the chain where the Wormhole contract should be updated (uint16).
uint32 chain_id = 1;
// Hex-encoded address (without leading 0x) address of the new program/contract.
@ -417,3 +421,30 @@ message GetAndObserveMissingVAAsRequest {
message GetAndObserveMissingVAAsResponse {
string response =1;
}
// EvmCall represents a generic EVM call that can be executed by the generalized governance contract.
message EvmCall {
// ID of the chain where the action should be executed (uint16).
uint32 chain_id = 1;
// Address of the governance contract (eth address starting with 0x)
string governance_contract = 2;
// Address of the governed contract (eth address starting with 0x)
string target_contract = 3;
// ABI-encoded calldata to be passed on to the governed contract (hex encoded)
string abi_encoded_call = 4;
}
// SolanaCall represents a generic Solana call that can be executed by the generalized governance contract.
message SolanaCall {
// ID of the chain where the action should be executed (uint16).
uint32 chain_id = 1;
// Address of the governance contract (solana address)
string governance_contract = 2;
// Encoded instruction data to be passed on to the governed contract (hex encoded)
string encoded_instruction = 3;
}

View File

@ -3,6 +3,8 @@
## 0.10.15
Add Provenance to cosmwasm chains
Add Scroll mainnet support
Add Blast mainnet support
## 0.10.14

View File

@ -1,6 +1,6 @@
{
"name": "@certusone/wormhole-sdk",
"version": "0.10.14",
"version": "0.10.15",
"description": "SDK for interacting with Wormhole",
"homepage": "https://wormhole.com",
"main": "./lib/cjs/index.js",

View File

@ -309,8 +309,8 @@ const MAINNET = {
nft_bridge: undefined,
},
scroll: {
core: undefined,
token_bridge: undefined,
core: "0xbebdb6C8ddC678FfA9f8748f85C815C556Dd8ac6",
token_bridge: "0x24850c6f61C438823F01B7A3BF2B89B72174Fa9d",
nft_bridge: undefined,
},
mantle: {
@ -319,8 +319,8 @@ const MAINNET = {
nft_bridge: undefined,
},
blast: {
core: undefined,
token_bridge: undefined,
core: "0xbebdb6C8ddC678FfA9f8748f85C815C556Dd8ac6",
token_bridge: "0x24850c6f61C438823F01B7A3BF2B89B72174Fa9d",
nft_bridge: undefined,
},
xlayer: {

View File

@ -118,6 +118,8 @@ var knownTokenbridgeEmitters = map[vaa.ChainID]string{
vaa.ChainIDOptimism: "0000000000000000000000001D68124e65faFC907325e3EDbF8c4d84499DAa8b",
vaa.ChainIDBase: "0000000000000000000000008d2de8d2f73F1F4cAB472AC9A881C9b123C79627",
vaa.ChainIDXpla: "8f9cf727175353b17a5f574270e370776123d90fd74956ae4277962b4fdee24c",
vaa.ChainIDScroll: "00000000000000000000000024850c6f61C438823F01B7A3BF2B89B72174Fa9d",
vaa.ChainIDBlast: "00000000000000000000000024850c6f61C438823F01B7A3BF2B89B72174Fa9d",
vaa.ChainIDInjective: "00000000000000000000000045dbea4617971d93188eda21530bc6503d153313",
vaa.ChainIDSui: "ccceeb29348f71bdd22ffef43a2a19c1f5b5e17c5cca5411529120182672ade5",
vaa.ChainIDSei: "86c5fd957e2db8389553e1728f9c27964b22a8154091ccba54d75f4b10c61f5e",

View File

@ -4,8 +4,9 @@ import (
"bytes"
"encoding/binary"
"fmt"
"math"
"github.com/ethereum/go-ethereum/common"
ethcommon "github.com/ethereum/go-ethereum/common"
"github.com/holiman/uint256"
)
@ -55,6 +56,13 @@ var WormholeRelayerModule = [32]byte{
}
var WormholeRelayerModuleStr = string(WormholeRelayerModule[:])
var GeneralPurposeGovernanceModule = [32]byte{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x65, 0x6E, 0x65, 0x72, 0x61, 0x6C,
0x50, 0x75, 0x72, 0x70, 0x6F, 0x73, 0x65, 0x47, 0x6F, 0x76, 0x65, 0x72, 0x6E, 0x61, 0x6E,
0x63, 0x65,
}
var GeneralPurposeGovernanceModuleStr = string(GeneralPurposeGovernanceModule[:])
type GovernanceAction uint8
var (
@ -99,6 +107,10 @@ var (
// Wormhole relayer governance actions
WormholeRelayerSetDefaultDeliveryProvider GovernanceAction = 3
// General purpose governance
GeneralPurposeGovernanceEvmAction GovernanceAction = 1
GeneralPurposeGovernanceSolanaAction GovernanceAction = 2
)
type (
@ -110,7 +122,7 @@ type (
// BodyGuardianSetUpdate is a governance message to set a new guardian set
BodyGuardianSetUpdate struct {
Keys []common.Address
Keys []ethcommon.Address
NewIndex uint32
}
@ -216,6 +228,24 @@ type (
ChainID ChainID
NewDefaultDeliveryProviderAddress Address
}
// BodyGeneralPurposeGovernanceEvm is a general purpose governance message for EVM chains
BodyGeneralPurposeGovernanceEvm struct {
ChainID ChainID
GovernanceContract ethcommon.Address
TargetContract ethcommon.Address
Payload []byte
}
// BodyGeneralPurposeGovernanceSolana is a general purpose governance message for Solana chains
BodyGeneralPurposeGovernanceSolana struct {
ChainID ChainID
GovernanceContract Address
// NOTE: unlike in EVM, no target contract in the schema here, the
// instruction encodes the target contract address (unlike in EVM, where
// an abi encoded calldata doesn't include the target contract address)
Instruction []byte
}
)
func (b BodyContractUpgrade) Serialize() []byte {
@ -402,6 +432,31 @@ func (r BodyWormholeRelayerSetDefaultDeliveryProvider) Serialize() []byte {
return serializeBridgeGovernanceVaa(WormholeRelayerModuleStr, WormholeRelayerSetDefaultDeliveryProvider, r.ChainID, payload.Bytes())
}
func (r BodyGeneralPurposeGovernanceEvm) Serialize() ([]byte, error) {
payload := &bytes.Buffer{}
payload.Write(r.GovernanceContract[:])
payload.Write(r.TargetContract[:])
// write payload len as uint16
if len(r.Payload) > math.MaxUint16 {
return nil, fmt.Errorf("payload too long; expected at most %d bytes", math.MaxUint16)
}
MustWrite(payload, binary.BigEndian, uint16(len(r.Payload)))
payload.Write(r.Payload)
return serializeBridgeGovernanceVaa(GeneralPurposeGovernanceModuleStr, GeneralPurposeGovernanceEvmAction, r.ChainID, payload.Bytes()), nil
}
func (r BodyGeneralPurposeGovernanceSolana) Serialize() []byte {
payload := &bytes.Buffer{}
payload.Write(r.GovernanceContract[:])
// NOTE: unlike in EVM, we don't write the payload length here, because we're using
// a custom instruction encoding (there is no standard encoding like evm ABI
// encoding), generated by an external tool. That tool length-prefixes all
// the relevant dynamic fields.
payload.Write(r.Instruction)
return serializeBridgeGovernanceVaa(GeneralPurposeGovernanceModuleStr, GeneralPurposeGovernanceSolanaAction, r.ChainID, payload.Bytes())
}
func EmptyPayloadVaa(module string, actionId GovernanceAction, chainId ChainID) []byte {
return serializeBridgeGovernanceVaa(module, actionId, chainId, []byte{})
}

View File

@ -38,7 +38,7 @@ require (
github.com/beorn7/perks v1.0.1 // indirect
github.com/bgentry/speakeasy v0.1.0 // indirect
github.com/btcsuite/btcd v0.22.1 // indirect
github.com/btcsuite/btcd/btcec/v2 v2.2.0 // indirect
github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect
github.com/cespare/xxhash v1.1.0 // indirect
github.com/cespare/xxhash/v2 v2.1.2 // indirect
github.com/coinbase/rosetta-sdk-go v0.7.0 // indirect
@ -49,8 +49,7 @@ require (
github.com/cosmos/gogoproto v1.4.3 // indirect
github.com/cosmos/gorocksdb v1.2.0 // indirect
github.com/cosmos/iavl v0.19.4 // indirect
github.com/cosmos/ledger-cosmos-go v0.11.1 // indirect
github.com/cosmos/ledger-go v0.9.2 // indirect
github.com/cosmos/ledger-cosmos-go v0.12.4 // indirect
github.com/creachadair/taskgroup v0.3.2 // indirect
github.com/danieljoos/wincred v1.1.2 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
@ -122,7 +121,8 @@ require (
github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 // indirect
github.com/tendermint/btcd v0.1.1 // indirect
github.com/tendermint/go-amino v0.16.0 // indirect
github.com/zondax/hid v0.9.0 // indirect
github.com/zondax/hid v0.9.2 // indirect
github.com/zondax/ledger-go v0.14.3 // indirect
go.etcd.io/bbolt v1.3.6 // indirect
golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e // indirect
golang.org/x/net v0.2.0 // indirect

View File

@ -332,6 +332,7 @@ github.com/btcsuite/btcd v0.22.1 h1:CnwP9LM/M9xuRrGSCGeMVs9iv09uMqwsVX7EeIpgV2c=
github.com/btcsuite/btcd v0.22.1/go.mod h1:wqgTSL29+50LRkmOVknEdmt8ZojIzhuWvgu/iptuN7Y=
github.com/btcsuite/btcd/btcec/v2 v2.2.0 h1:fzn1qaOt32TuLjFlkzYSsBC35Q3KUjT1SwPxiMSCF5k=
github.com/btcsuite/btcd/btcec/v2 v2.2.0/go.mod h1:U7MHm051Al6XmscBQ0BoNydpOTsFAn707034b5nY8zU=
github.com/btcsuite/btcd/btcec/v2 v2.3.2/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04=
github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 h1:q0rUy8C/TYNBQS1+CGKw68tLOFYSNEs0TFnxxnS9+4U=
github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc=
github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA=
@ -579,6 +580,8 @@ github.com/cosmos/keyring v1.1.7-0.20210622111912-ef00f8ac3d76 h1:DdzS1m6o/pCqeZ
github.com/cosmos/keyring v1.1.7-0.20210622111912-ef00f8ac3d76/go.mod h1:0mkLWIoZuQ7uBoospo5Q9zIpqq6rYCPJDSUdeCJvPM8=
github.com/cosmos/ledger-cosmos-go v0.11.1 h1:9JIYsGnXP613pb2vPjFeMMjBI5lEDsEaF6oYorTy6J4=
github.com/cosmos/ledger-cosmos-go v0.11.1/go.mod h1:J8//BsAGTo3OC/vDLjMRFLW6q0WAaXvHnVc7ZmE8iUY=
github.com/cosmos/ledger-cosmos-go v0.12.4 h1:drvWt+GJP7Aiw550yeb3ON/zsrgW0jgh5saFCr7pDnw=
github.com/cosmos/ledger-cosmos-go v0.12.4/go.mod h1:fjfVWRf++Xkygt9wzCsjEBdjcf7wiiY35fv3ctT+k4M=
github.com/cosmos/ledger-go v0.9.2 h1:Nnao/dLwaVTk1Q5U9THldpUMMXU94BOTWPddSmVB6pI=
github.com/cosmos/ledger-go v0.9.2/go.mod h1:oZJ2hHAZROdlHiwTg4t7kP+GKIIkBT+o6c9QWFanOyI=
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
@ -2118,6 +2121,10 @@ github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50/go.mod h1:NUSPS
github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f/go.mod h1:GlGEuHIJweS1mbCqG+7vt2nvWLzLLnRHbXz5JKd/Qbg=
github.com/zondax/hid v0.9.0 h1:eiT3P6vNxAEVxXMw66eZUAAnU2zD33JBkfG/EnfAKl8=
github.com/zondax/hid v0.9.0/go.mod h1:l5wttcP0jwtdLjqjMMWFVEE7d1zO0jvSPA9OPZxWpEM=
github.com/zondax/hid v0.9.2 h1:WCJFnEDMiqGF64nlZz28E9qLVZ0KSJ7xpc5DLEyma2U=
github.com/zondax/hid v0.9.2/go.mod h1:l5wttcP0jwtdLjqjMMWFVEE7d1zO0jvSPA9OPZxWpEM=
github.com/zondax/ledger-go v0.14.3 h1:wEpJt2CEcBJ428md/5MgSLsXLBos98sBOyxNmCjfUCw=
github.com/zondax/ledger-go v0.14.3/go.mod h1:IKKaoxupuB43g4NxeQmbLXv7T9AlQyie1UpHb342ycI=
gitlab.com/bosi/decorder v0.2.1/go.mod h1:6C/nhLSbF6qZbYD8bRmISBwc6vcWdNsiIBkRvjJFrH0=
gitlab.com/bosi/decorder v0.2.3/go.mod h1:9K1RB5+VPNQYtXtTDAzd2OEftsZb1oV0IrJrzChSdGE=
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=