6.7 KiB
CCIP Bridge Destinations and LINK Funding
This document describes how to configure addDestination on each CCIP WETH9/WETH10 bridge and how to fund bridges with LINK for cross-chain fees. Use it after deploying bridges via deploy-all-mainnets-with-mapper-oracle-pmm.sh ccip (or DeployAll per chain).
1. Overview
- Each CCIPWETH9Bridge and CCIPWETH10Bridge must have destination chains set via
addDestination(uint64 chainSelector, address receiverBridge). - Only the bridge admin can call
addDestination. Use the same deployer key (or the key that owns admin) when running scripts. - For each pair of chains (e.g. Ethereum ↔ Chain 138), you add the destination chain selector and the receiver bridge address on the other chain.
- CCIP fees can be paid in LINK (or native token depending on contract). Ensure each bridge contract has enough LINK (and/or native) to pay for
ccipSendfees.
2. Chain Selectors and .env Bridge Variables
Use these from .env (or Chainlink CCIP Supported Networks):
| Chain | Chain ID | Selector (.env) | WETH9 Bridge (.env) | WETH10 Bridge (.env) |
|---|---|---|---|---|
| Ethereum | 1 | ETH_MAINNET_SELECTOR |
MAINNET_CCIP_WETH9_BRIDGE |
MAINNET_CCIP_WETH10_BRIDGE |
| BSC | 56 | BSC_SELECTOR |
CCIPWETH9_BRIDGE_BSC |
CCIPWETH10_BRIDGE_BSC |
| Polygon | 137 | POLYGON_SELECTOR |
CCIPWETH9_BRIDGE_POLYGON |
CCIPWETH10_BRIDGE_POLYGON |
| Arbitrum | 42161 | ARBITRUM_SELECTOR |
CCIPWETH9_BRIDGE_ARBITRUM |
CCIPWETH10_BRIDGE_ARBITRUM |
| Optimism | 10 | OPTIMISM_SELECTOR |
CCIPWETH9_BRIDGE_OPTIMISM |
CCIPWETH10_BRIDGE_OPTIMISM |
| Avalanche | 43114 | AVALANCHE_SELECTOR |
CCIPWETH9_BRIDGE_AVALANCHE |
(set if deployed) |
| Cronos | 25 | CRONOS_SELECTOR |
CCIPWETH9_BRIDGE_CRONOS |
CCIPWETH10_BRIDGE_CRONOS |
| Base | 8453 | BASE_SELECTOR |
CCIPWETH9_BRIDGE_BASE |
CCIPWETH10_BRIDGE_BASE |
| Gnosis | 100 | GNOSIS_SELECTOR |
CCIPWETH9_BRIDGE_GNOSIS |
CCIPWETH10_BRIDGE_GNOSIS |
| Chain 138 | 138 | CHAIN138_SELECTOR (if set) |
CCIPWETH9_BRIDGE_CHAIN138 |
CCIPWETH10_BRIDGE_CHAIN138 |
3. Adding Destinations (addDestination)
For each bridge, call:
bridge.addDestination(destinationChainSelector, receiverBridgeAddress);
- destinationChainSelector: the selector of the destination chain (e.g. Ethereum’s selector when configuring “this chain → Ethereum”).
- receiverBridgeAddress: the address of the same type of bridge (WETH9 or WETH10) on the destination chain.
Example: On Ethereum WETH9 bridge, to allow transfers to Chain 138:
# From smom-dbis-138, with .env loaded
cast send "$MAINNET_CCIP_WETH9_BRIDGE" "addDestination(uint64,address)" "$CHAIN138_SELECTOR" "$CCIPWETH9_BRIDGE_CHAIN138" \
--rpc-url "$ETHEREUM_MAINNET_RPC" --private-key "$PRIVATE_KEY"
Example: On Chain 138 WETH9 bridge, to allow transfers to Ethereum:
cast send "$CCIPWETH9_BRIDGE_CHAIN138" "addDestination(uint64,address)" "$ETH_MAINNET_SELECTOR" "$MAINNET_CCIP_WETH9_BRIDGE" \
--rpc-url "$RPC_URL_138" --private-key "$PRIVATE_KEY" --legacy
Using the existing script (Ethereum mainnet)
For Ethereum WETH9/WETH10 bridges, you can use:
# From repo root, with .env loaded
scripts/ccip/ccip-configure-destination.sh --token weth9 --action add --selector <DEST_CHAIN_SELECTOR> --receiver <RECEIVER_BRIDGE_ADDR> --pk "$PRIVATE_KEY" --rpc "$ETHEREUM_MAINNET_RPC"
scripts/ccip/ccip-configure-destination.sh --token weth10 --action add --selector <DEST_CHAIN_SELECTOR> --receiver <RECEIVER_BRIDGE_ADDR> --pk "$PRIVATE_KEY" --rpc "$ETHEREUM_MAINNET_RPC"
Repeat for each destination chain (BSC, Polygon, Base, Optimism, Avalanche, Cronos, Gnosis, Chain 138) using the correct selector and the corresponding bridge address on that chain.
4. LINK Funding
- CCIP charges fees for each cross-chain message; bridges typically pay in LINK (or native) depending on the contract’s
feeTokenandccipSendusage. - Per chain: Ensure the bridge contract holds enough LINK (and native for gas) so it can pay CCIP fees when users call
sendCrossChain(or equivalent). - How to fund:
- Get LINK on the same chain as the bridge (e.g. from an exchange or faucet).
- Transfer LINK to the bridge contract address (the same address you use for
addDestination), or use any approved mechanism (e.g. admin top-up function if the contract has one).
- LINK token addresses per chain are in
.env(e.g.CCIP_GNOSIS_LINK_TOKEN,CCIP_ETH_LINK_TOKEN, etc.) and on Chainlink CCIP Supported Networks. - Script: Run
scripts/deployment/fund-ccip-bridges-with-link.shto send LINK to all CCIP bridges (sources .env; set--link amount, default 10 LINK; use --dry-runto print commands only).
5. Script: Configure all destinations
From repo root (with .env loaded):
# Step A: Chain 138 → each mainnet (requires RPC_URL_138)
# Step B: Each mainnet → Chain 138 (requires CHAIN138_SELECTOR in .env)
bash scripts/deployment/configure-all-ccip-bridge-destinations.sh
Use --dry-run to print commands only. Step A uses --gas-limit (default 200000) to avoid RPC estimateGas issues on Chain 138; "destination already exists" means that lane is already configured. Step B: optional .env overrides for high-fee chains: BRIDGE_ETH_GAS_PRICE=40000000, BRIDGE_ARBITRUM_GAS_PRICE=25000000, BRIDGE_AVALANCHE_GAS_PRICE=140000000.
6. Checklist (post-deploy)
- Run
configure-all-ccip-bridge-destinations.sh(and retry any failed chains). - For each deployed bridge (WETH9 and WETH10) on each chain, call
addDestinationfor every other chain you want to support (using that chain’s selector and the receiver bridge address). - Fund each bridge contract with LINK (and native if needed) on its chain.
- Run a small test transfer per lane (e.g. 138 ↔ Ethereum, 138 ↔ BSC) and verify on explorers.
7. References
- Runbook:
docs/deployment/ALL_MAINNETS_DEPLOYMENT_RUNBOOK.md - Script (Ethereum):
scripts/ccip/ccip-configure-destination.sh - Bridge config (138 ↔ Mainnet):
scripts/deployment/configure-bridge-destinations.sh(note: may use different ABI; preferaddDestination(uint64,address)for CCIPWETH9/CCIPWETH10) - WETH CCIP deployment:
docs/operations/integrations/WETH_CCIP_DEPLOYMENT.md