feat(ccip): cap LINK funding to deployer balance per chain; fix Arbitrum gas

- parse_link_tags: add --cap-to-deployer for fund-ccip-bridges-with-link.sh
- fund-ccip: min(target, balance//bridges) per chain; reuse one wei for both
  bridges under cap so post-transfer balance does not undershoot the second send
- Arbitrum: append legacy --gas-price from RPC (3x) with floor to clear base fee

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
defiQUG
2026-05-11 16:09:31 -07:00
parent 0561d26bcd
commit 01e0779a3d
2 changed files with 119 additions and 23 deletions

View File

@@ -1,7 +1,8 @@
#!/usr/bin/env bash
# Fund all CCIP WETH9/WETH10 bridge contracts with LINK on each chain.
# Amount via tag (not .env): --link <amount> (default 10 LINK), --dry-run to print commands only.
# Usage: ./scripts/deployment/fund-ccip-bridges-with-link.sh [--link 10] [--dry-run]
# --cap-to-deployer: per chain, each bridge gets min(--link, deployer_LINK_balance // bridges_on_chain).
# Usage: ./scripts/deployment/fund-ccip-bridges-with-link.sh [--link 10] [--cap-to-deployer] [--dry-run]
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
@@ -74,6 +75,49 @@ print_skip() {
echo " Skipped (insufficient LINK balance: have ${bal%% *}, need $needed)"
}
# Integer wei per bridge: min(LINK_AMOUNT_WEI, balance // n_bridges).
per_bridge_cap_wei() {
local token="$1" owner="$2" rpc="$3" n="$4"
local bal
bal=$(get_token_balance "$token" "$owner" "$rpc")
bal="${bal%% *}"
[[ "$bal" =~ ^[0-9]+$ ]] || bal="0"
[[ "${n:-1}" -lt 1 ]] && n=1
python3 -c "b=int('$bal'); r=int('${LINK_AMOUNT_WEI}'); n=int('$n'); print(min(r, b//n))"
}
# Echo wei to transfer for one bridge; 0 means skip.
resolve_bridge_transfer_wei() {
local token="$1" owner="$2" rpc="$3" n_bridges="$4"
if [[ "${CAP_LINK_TO_DEPLOYER_BALANCE:-0}" == "1" ]]; then
per_bridge_cap_wei "$token" "$owner" "$rpc" "$n_bridges"
return
fi
if has_sufficient_link "$token" "$owner" "$rpc" "$LINK_AMOUNT_WEI"; then
echo "$LINK_AMOUNT_WEI"
else
echo "0"
fi
}
print_skip_or_cap_zero() {
local label="$1" token="$2" owner="$3" rpc="$4"
if [[ "${CAP_LINK_TO_DEPLOYER_BALANCE:-0}" == "1" ]]; then
local bal
bal=$(get_token_balance "$token" "$owner" "$rpc")
echo " Skipped ($label: deployer LINK ${bal%% *} wei → 0 per-bridge after split/cap vs target $LINK_AMOUNT_WEI)"
else
print_skip "$label" "$token" "$owner" "$rpc" "$LINK_AMOUNT_WEI"
fi
}
log_capped_notice() {
local label="$1" wei="$2"
if [[ "${CAP_LINK_TO_DEPLOYER_BALANCE:-0}" == "1" ]] && [[ "$wei" != "0" ]] && [[ "$wei" -lt "$LINK_AMOUNT_WEI" ]]; then
echo " $label: transfer ${wei} wei (capped from target ${LINK_AMOUNT_WEI})"
fi
}
if [[ -z "$PRIVATE_KEY" ]]; then
echo "ERROR: PRIVATE_KEY not set" >&2
exit 1
@@ -85,7 +129,8 @@ if [[ -z "$DEPLOYER_ADDR" ]]; then
exit 1
fi
echo "Funding CCIP bridges with LINK (amount per bridge: $LINK_AMOUNT_WEI wei)"
echo "Funding CCIP bridges with LINK (target per bridge: $LINK_AMOUNT_WEI wei)"
[[ "${CAP_LINK_TO_DEPLOYER_BALANCE:-0}" == "1" ]] && echo "Mode: --cap-to-deployer (each chain uses min(target, balance // bridges_on_chain))"
echo "Deployer: $DEPLOYER_ADDR"
echo ""
@@ -96,18 +141,30 @@ if [[ -n "${RPC_URL_138:-}" && -n "${LINK_TOKEN_CHAIN138:-${LINK_TOKEN:-}}" ]];
rpc=$(ensure_rpc "$RPC_URL_138")
echo "Chain 138 (RPC: ${rpc%%\?*}...)"
_gas138="--legacy --gas-limit 250000 --gas-price 2000000000 --timeout 120"
_n138=0
[[ -n "${CCIPWETH9_BRIDGE_CHAIN138:-}" ]] && _n138=$((_n138 + 1))
[[ -n "${CCIPWETH10_BRIDGE_CHAIN138:-}" ]] && _n138=$((_n138 + 1))
_cap_once=0
if [[ "${CAP_LINK_TO_DEPLOYER_BALANCE:-0}" == "1" ]]; then
_wei_chain138=$(per_bridge_cap_wei "$link" "$DEPLOYER_ADDR" "$rpc" "$_n138")
_cap_once=1
fi
if [[ -n "${CCIPWETH9_BRIDGE_CHAIN138:-}" ]]; then
if has_sufficient_link "$link" "$DEPLOYER_ADDR" "$rpc" "$LINK_AMOUNT_WEI"; then
run_or_echo "cast send $link \"transfer(address,uint256)\" ${CCIPWETH9_BRIDGE_CHAIN138,,} $LINK_AMOUNT_WEI --rpc-url \"$rpc\" --private-key \"\$PRIVATE_KEY\" $_gas138"
if [[ "$_cap_once" == "1" ]]; then _wei="$_wei_chain138"; else _wei=$(resolve_bridge_transfer_wei "$link" "$DEPLOYER_ADDR" "$rpc" "$_n138"); fi
if [[ "$_wei" == "0" ]]; then
print_skip_or_cap_zero "CHAIN138/WETH9" "$link" "$DEPLOYER_ADDR" "$rpc"
else
print_skip "CHAIN138/WETH9" "$link" "$DEPLOYER_ADDR" "$rpc" "$LINK_AMOUNT_WEI"
log_capped_notice "CHAIN138/WETH9" "$_wei"
run_or_echo "cast send $link \"transfer(address,uint256)\" ${CCIPWETH9_BRIDGE_CHAIN138,,} $_wei --rpc-url \"$rpc\" --private-key \"\$PRIVATE_KEY\" $_gas138"
fi
fi
if [[ -n "${CCIPWETH10_BRIDGE_CHAIN138:-}" ]]; then
if has_sufficient_link "$link" "$DEPLOYER_ADDR" "$rpc" "$LINK_AMOUNT_WEI"; then
run_or_echo "cast send $link \"transfer(address,uint256)\" ${CCIPWETH10_BRIDGE_CHAIN138,,} $LINK_AMOUNT_WEI --rpc-url \"$rpc\" --private-key \"\$PRIVATE_KEY\" $_gas138"
if [[ "$_cap_once" == "1" ]]; then _wei="$_wei_chain138"; else _wei=$(resolve_bridge_transfer_wei "$link" "$DEPLOYER_ADDR" "$rpc" "$_n138"); fi
if [[ "$_wei" == "0" ]]; then
print_skip_or_cap_zero "CHAIN138/WETH10" "$link" "$DEPLOYER_ADDR" "$rpc"
else
print_skip "CHAIN138/WETH10" "$link" "$DEPLOYER_ADDR" "$rpc" "$LINK_AMOUNT_WEI"
log_capped_notice "CHAIN138/WETH10" "$_wei"
run_or_echo "cast send $link \"transfer(address,uint256)\" ${CCIPWETH10_BRIDGE_CHAIN138,,} $_wei --rpc-url \"$rpc\" --private-key \"\$PRIVATE_KEY\" $_gas138"
fi
fi
echo ""
@@ -119,18 +176,30 @@ if [[ -n "${ETHEREUM_MAINNET_RPC:-}" && -n "${MAINNET_LINK_TOKEN:-${CCIP_ETH_LIN
rpc=$(ensure_rpc "$ETHEREUM_MAINNET_RPC")
echo "Ethereum Mainnet"
_pub_timeout="--timeout 300 --rpc-timeout 120"
_neth=0
[[ -n "${MAINNET_CCIP_WETH9_BRIDGE:-}" ]] && _neth=$((_neth + 1))
[[ -n "${MAINNET_CCIP_WETH10_BRIDGE:-}" ]] && _neth=$((_neth + 1))
_cap_once_eth=0
if [[ "${CAP_LINK_TO_DEPLOYER_BALANCE:-0}" == "1" ]]; then
_wei_chain_eth=$(per_bridge_cap_wei "$link" "$DEPLOYER_ADDR" "$rpc" "$_neth")
_cap_once_eth=1
fi
if [[ -n "${MAINNET_CCIP_WETH9_BRIDGE:-}" ]]; then
if has_sufficient_link "$link" "$DEPLOYER_ADDR" "$rpc" "$LINK_AMOUNT_WEI"; then
run_or_echo "cast send $link \"transfer(address,uint256)\" $MAINNET_CCIP_WETH9_BRIDGE $LINK_AMOUNT_WEI --rpc-url \"$rpc\" --private-key \"\$PRIVATE_KEY\" --legacy $_pub_timeout"
if [[ "$_cap_once_eth" == "1" ]]; then _wei="$_wei_chain_eth"; else _wei=$(resolve_bridge_transfer_wei "$link" "$DEPLOYER_ADDR" "$rpc" "$_neth"); fi
if [[ "$_wei" == "0" ]]; then
print_skip_or_cap_zero "ETH/WETH9" "$link" "$DEPLOYER_ADDR" "$rpc"
else
print_skip "ETH/WETH9" "$link" "$DEPLOYER_ADDR" "$rpc" "$LINK_AMOUNT_WEI"
log_capped_notice "ETH/WETH9" "$_wei"
run_or_echo "cast send $link \"transfer(address,uint256)\" $MAINNET_CCIP_WETH9_BRIDGE $_wei --rpc-url \"$rpc\" --private-key \"\$PRIVATE_KEY\" --legacy $_pub_timeout"
fi
fi
if [[ -n "${MAINNET_CCIP_WETH10_BRIDGE:-}" ]]; then
if has_sufficient_link "$link" "$DEPLOYER_ADDR" "$rpc" "$LINK_AMOUNT_WEI"; then
run_or_echo "cast send $link \"transfer(address,uint256)\" $MAINNET_CCIP_WETH10_BRIDGE $LINK_AMOUNT_WEI --rpc-url \"$rpc\" --private-key \"\$PRIVATE_KEY\" --legacy $_pub_timeout"
if [[ "$_cap_once_eth" == "1" ]]; then _wei="$_wei_chain_eth"; else _wei=$(resolve_bridge_transfer_wei "$link" "$DEPLOYER_ADDR" "$rpc" "$_neth"); fi
if [[ "$_wei" == "0" ]]; then
print_skip_or_cap_zero "ETH/WETH10" "$link" "$DEPLOYER_ADDR" "$rpc"
else
print_skip "ETH/WETH10" "$link" "$DEPLOYER_ADDR" "$rpc" "$LINK_AMOUNT_WEI"
log_capped_notice "ETH/WETH10" "$_wei"
run_or_echo "cast send $link \"transfer(address,uint256)\" $MAINNET_CCIP_WETH10_BRIDGE $_wei --rpc-url \"$rpc\" --private-key \"\$PRIVATE_KEY\" --legacy $_pub_timeout"
fi
fi
echo ""
@@ -163,21 +232,43 @@ for label in BSC POLYGON BASE OPTIMISM ARBITRUM AVALANCHE CRONOS GNOSIS CELO WEM
echo "$label"
_pub_timeout_loop="--timeout 300 --rpc-timeout 120"
if [[ -n "$addr9" ]]; then
if has_sufficient_link "$link" "$DEPLOYER_ADDR" "$rpc" "$LINK_AMOUNT_WEI"; then
run_or_echo "cast send ${link,,} \"transfer(address,uint256)\" ${addr9,,} $LINK_AMOUNT_WEI --rpc-url \"$rpc\" --private-key \"\$PRIVATE_KEY\" --legacy $_pub_timeout_loop"
# Arbitrum: default cast fee fields can sit under base fee; bump legacy gas price from RPC.
if [[ "$label" == "ARBITRUM" ]]; then
_gp_try=$(cast gas-price --rpc-url "$rpc" 2>/dev/null | head -1 | tr -d '\r\n ' || true)
if [[ -n "$_gp_try" ]] && [[ "$_gp_try" =~ ^[0-9]+$ ]] && [[ "$_gp_try" -gt 0 ]]; then
_gp_arb=$(python3 -c "print(max(int(int('$_gp_try') * 3), 120000000))")
else
print_skip "$label/WETH9" "$link" "$DEPLOYER_ADDR" "$rpc" "$LINK_AMOUNT_WEI"
_gp_arb="1200000000"
fi
_pub_timeout_loop="$_pub_timeout_loop --gas-price $_gp_arb"
fi
_nl2=0
[[ -n "$addr9" ]] && _nl2=$((_nl2 + 1))
[[ -n "$addr10" ]] && _nl2=$((_nl2 + 1))
_cap_once_l2=0
if [[ "${CAP_LINK_TO_DEPLOYER_BALANCE:-0}" == "1" ]]; then
_wei_chain_l2=$(per_bridge_cap_wei "$link" "$DEPLOYER_ADDR" "$rpc" "$_nl2")
_cap_once_l2=1
fi
if [[ -n "$addr9" ]]; then
if [[ "$_cap_once_l2" == "1" ]]; then _wei="$_wei_chain_l2"; else _wei=$(resolve_bridge_transfer_wei "$link" "$DEPLOYER_ADDR" "$rpc" "$_nl2"); fi
if [[ "$_wei" == "0" ]]; then
print_skip_or_cap_zero "$label/WETH9" "$link" "$DEPLOYER_ADDR" "$rpc"
else
log_capped_notice "$label/WETH9" "$_wei"
run_or_echo "cast send ${link,,} \"transfer(address,uint256)\" ${addr9,,} $_wei --rpc-url \"$rpc\" --private-key \"\$PRIVATE_KEY\" --legacy $_pub_timeout_loop"
fi
fi
if [[ -n "$addr10" ]]; then
if has_sufficient_link "$link" "$DEPLOYER_ADDR" "$rpc" "$LINK_AMOUNT_WEI"; then
run_or_echo "cast send ${link,,} \"transfer(address,uint256)\" ${addr10,,} $LINK_AMOUNT_WEI --rpc-url \"$rpc\" --private-key \"\$PRIVATE_KEY\" --legacy $_pub_timeout_loop"
if [[ "$_cap_once_l2" == "1" ]]; then _wei="$_wei_chain_l2"; else _wei=$(resolve_bridge_transfer_wei "$link" "$DEPLOYER_ADDR" "$rpc" "$_nl2"); fi
if [[ "$_wei" == "0" ]]; then
print_skip_or_cap_zero "$label/WETH10" "$link" "$DEPLOYER_ADDR" "$rpc"
else
print_skip "$label/WETH10" "$link" "$DEPLOYER_ADDR" "$rpc" "$LINK_AMOUNT_WEI"
log_capped_notice "$label/WETH10" "$_wei"
run_or_echo "cast send ${link,,} \"transfer(address,uint256)\" ${addr10,,} $_wei --rpc-url \"$rpc\" --private-key \"\$PRIVATE_KEY\" --legacy $_pub_timeout_loop"
fi
fi
echo ""
done
echo "Done. Use --link <amount> and --dry-run to adjust."
echo "Done. Use --link <amount>, --cap-to-deployer, and --dry-run to adjust."