- Added new deployment script references for Aave quote-push and treasury manager in .env.master.example. - Updated AGENTS.md to include information on GRU reference primacy versus public PMM mesh execution model. - Minor updates to various documentation files to reflect changes in policy and operational guidelines. Made-with: Cursor
215 lines
7.4 KiB
Bash
Executable File
215 lines
7.4 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Operator (deployer) funds grid wallets from an exported JSON manifest.
|
|
#
|
|
# Modes:
|
|
# ERC-20 (default): TOKEN + AMOUNT_WEI_PER_WALLET — transfer() from operator to each grid address.
|
|
# Native (--native): NATIVE_AMOUNT_WEI (or AMOUNT_WEI_PER_WALLET) — simple value transfer for gas on Chain 138.
|
|
#
|
|
# Default: dry-run. Live: --apply
|
|
#
|
|
# Usage (ERC-20):
|
|
# PMM_SOAK_GRID_JSON=config/pmm-soak-wallet-grid.json \
|
|
# TOKEN=0x93E66202A11B1772E55407B32B44e5Cd8eda7f22 AMOUNT_WEI_PER_WALLET=10000000000 \
|
|
# bash scripts/deployment/pmm-soak-operator-fund-grid.sh --apply --from-linear 0 --to-linear 99
|
|
#
|
|
# Usage (native / gas):
|
|
# PMM_SOAK_GRID_JSON=config/pmm-soak-wallet-grid.json \
|
|
# NATIVE_AMOUNT_WEI=20000000000000000 \
|
|
# bash scripts/deployment/pmm-soak-operator-fund-grid.sh --native --apply --from-linear 0 --to-linear 199
|
|
#
|
|
# Env:
|
|
# PRIVATE_KEY / DEPLOYER_PRIVATE_KEY — operator
|
|
# RPC_URL_138
|
|
# PMM_SOAK_GRID_JSON — default: $PROJECT_ROOT/config/pmm-soak-wallet-grid.json
|
|
# TOKEN — ERC-20 (not used with --native)
|
|
# AMOUNT_WEI_PER_WALLET — per-recipient raw amount (ERC-20); also accepted for --native if NATIVE_AMOUNT_WEI unset
|
|
# NATIVE_AMOUNT_WEI — preferred for --native (wei per wallet)
|
|
# CHAIN138_DEPLOY_GAS_PRICE_WEI — default 1000
|
|
# CAST_SEND_TIMEOUT_SEC — passed to cast as ETH_TIMEOUT (seconds to wait for tx confirmation; default 900)
|
|
# CAST_RPC_TIMEOUT_SEC — ETH_RPC_TIMEOUT for cast (default 120)
|
|
# PMM_SOAK_RPC_URL_OVERRIDE — after dotenv load, force RPC_URL_138 for all cast calls
|
|
# PMM_SOAK_FUND_PROGRESS_EVERY — during --apply, log ETA every N successful txs (0=off except final; default 50)
|
|
#
|
|
set -euo pipefail
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
PROJECT_ROOT="$(cd "${SCRIPT_DIR}/../.." && pwd)"
|
|
# shellcheck source=/dev/null
|
|
source "${PROJECT_ROOT}/scripts/lib/pmm-soak-dotenv-override.sh"
|
|
pmm_soak_snapshot_pool_env_for_restore
|
|
# shellcheck source=/dev/null
|
|
[[ -f "${PROJECT_ROOT}/scripts/lib/load-project-env.sh" ]] && source "${PROJECT_ROOT}/scripts/lib/load-project-env.sh"
|
|
pmm_soak_restore_pool_env_after_dotenv
|
|
if [[ -n "${PMM_SOAK_RPC_URL_OVERRIDE:-}" ]]; then
|
|
export RPC_URL_138="$PMM_SOAK_RPC_URL_OVERRIDE"
|
|
export CHAIN138_RPC_URL="$RPC_URL_138"
|
|
export CHAIN138_RPC="$RPC_URL_138"
|
|
export ETH_RPC_URL="$RPC_URL_138"
|
|
fi
|
|
|
|
require_cmd() {
|
|
command -v "$1" >/dev/null 2>&1 || {
|
|
echo "[fund-grid] missing: $1" >&2
|
|
exit 1
|
|
}
|
|
}
|
|
|
|
require_cmd cast
|
|
require_cmd python3
|
|
|
|
APPLY=0
|
|
FROM_L=0
|
|
TO_L=6533
|
|
MODE="erc20"
|
|
|
|
while [[ $# -gt 0 ]]; do
|
|
case "$1" in
|
|
--apply) APPLY=1 ;;
|
|
--native) MODE="native" ;;
|
|
--erc20) MODE="erc20" ;;
|
|
--from-linear)
|
|
FROM_L="$2"
|
|
shift
|
|
;;
|
|
--to-linear)
|
|
TO_L="$2"
|
|
shift
|
|
;;
|
|
-h | --help)
|
|
sed -n '2,31p' "$0"
|
|
exit 0
|
|
;;
|
|
*)
|
|
echo "[fund-grid] unknown arg: $1" >&2
|
|
exit 2
|
|
;;
|
|
esac
|
|
shift
|
|
done
|
|
|
|
PK="${DEPLOYER_PRIVATE_KEY:-${PRIVATE_KEY:-}}"
|
|
RPC="${RPC_URL_138:-http://192.168.11.211:8545}"
|
|
GRID_JSON="${PMM_SOAK_GRID_JSON:-${PROJECT_ROOT}/config/pmm-soak-wallet-grid.json}"
|
|
TOKEN_ADDR="${TOKEN:-}"
|
|
GAS_WEI="${CHAIN138_DEPLOY_GAS_PRICE_WEI:-1000}"
|
|
|
|
NATIVE_AMOUNT="${NATIVE_AMOUNT_WEI:-}"
|
|
ERC20_AMOUNT="${AMOUNT_WEI_PER_WALLET:-}"
|
|
|
|
if [[ "$MODE" == "native" ]]; then
|
|
AMOUNT="${NATIVE_AMOUNT:-${ERC20_AMOUNT:-}}"
|
|
if [[ -z "$AMOUNT" ]]; then
|
|
echo "[fund-grid] --native requires NATIVE_AMOUNT_WEI or AMOUNT_WEI_PER_WALLET (wei per wallet)" >&2
|
|
exit 1
|
|
fi
|
|
else
|
|
AMOUNT="${ERC20_AMOUNT:-}"
|
|
if [[ -z "$TOKEN_ADDR" || -z "$AMOUNT" ]]; then
|
|
echo "[fund-grid] ERC-20 mode: set TOKEN and AMOUNT_WEI_PER_WALLET" >&2
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
if [[ ! -f "$GRID_JSON" ]]; then
|
|
echo "[fund-grid] missing grid JSON: $GRID_JSON" >&2
|
|
exit 1
|
|
fi
|
|
|
|
if [[ "$APPLY" -eq 1 && -z "$PK" ]]; then
|
|
echo "[fund-grid] --apply requires PRIVATE_KEY / DEPLOYER_PRIVATE_KEY" >&2
|
|
exit 1
|
|
fi
|
|
|
|
OPERATOR="$(cast wallet address --private-key "$PK" 2>/dev/null || true)"
|
|
if [[ "$APPLY" -eq 1 && -z "$OPERATOR" ]]; then
|
|
echo "[fund-grid] could not derive operator address" >&2
|
|
exit 1
|
|
fi
|
|
|
|
mapfile -t RECIPIENTS < <(
|
|
python3 - "$GRID_JSON" "$FROM_L" "$TO_L" <<'PY'
|
|
import json, sys
|
|
path, lo, hi = sys.argv[1], int(sys.argv[2]), int(sys.argv[3])
|
|
with open(path, encoding="utf-8") as f:
|
|
doc = json.load(f)
|
|
for w in doc["wallets"]:
|
|
li = int(w["linearIndex"])
|
|
if lo <= li <= hi:
|
|
print(w["address"])
|
|
PY
|
|
)
|
|
|
|
total="${#RECIPIENTS[@]}"
|
|
if [[ "$MODE" == "native" ]]; then
|
|
echo "[fund-grid] mode=native recipients=[$FROM_L,$TO_L] count=$total amount_each_wei=$AMOUNT apply=$APPLY"
|
|
else
|
|
echo "[fund-grid] mode=erc20 recipients=[$FROM_L,$TO_L] count=$total token=$TOKEN_ADDR amount_each=$AMOUNT apply=$APPLY"
|
|
fi
|
|
|
|
if [[ "$total" -eq 0 ]]; then
|
|
exit 0
|
|
fi
|
|
|
|
export ETH_TIMEOUT="${CAST_SEND_TIMEOUT_SEC:-900}"
|
|
export ETH_RPC_TIMEOUT="${CAST_RPC_TIMEOUT_SEC:-120}"
|
|
|
|
total_needed="$(python3 -c "print(int('$AMOUNT') * $total)")"
|
|
|
|
if [[ "$APPLY" -eq 0 ]]; then
|
|
echo "[fund-grid] dry-run sample (first 3):"
|
|
for i in 0 1 2; do
|
|
[[ "$i" -lt "$total" ]] || break
|
|
if [[ "$MODE" == "native" ]]; then
|
|
echo " cast send ${RECIPIENTS[$i]} --value $AMOUNT --rpc-url \"\$RPC_URL_138\" --private-key \"\$PRIVATE_KEY\" --legacy --gas-price $GAS_WEI"
|
|
else
|
|
echo " cast send $TOKEN_ADDR 'transfer(address,uint256)(bool)' ${RECIPIENTS[$i]} $AMOUNT --rpc-url \"\$RPC_URL_138\" --private-key \"\$PRIVATE_KEY\" --legacy --gas-price $GAS_WEI"
|
|
fi
|
|
done
|
|
if [[ "$MODE" == "native" ]]; then
|
|
echo "[fund-grid] aggregate native to recipients: $total_needed wei (+ operator gas for each funding tx)"
|
|
else
|
|
echo "[fund-grid] aggregate ERC-20 to recipients: $total_needed raw units (+ operator gas for each funding tx)"
|
|
fi
|
|
echo "[fund-grid] rerun with --apply to broadcast $total transactions"
|
|
exit 0
|
|
fi
|
|
|
|
if [[ "$MODE" == "native" && -n "$OPERATOR" ]]; then
|
|
op_bal="$(cast balance "$OPERATOR" --rpc-url "$RPC" 2>/dev/null | head -1 || echo "0")"
|
|
echo "[fund-grid] operator native balance (approx): $op_bal wei - need $total_needed wei to recipients + gas for $total txs"
|
|
fi
|
|
|
|
_pmm_fund_grid_err() {
|
|
echo "[fund-grid] ERR line=${BASH_LINENO[0]} n=${n:-0}/${total} mode=${MODE} recipients=[$FROM_L,$TO_L]" >&2
|
|
}
|
|
trap '_pmm_fund_grid_err' ERR
|
|
|
|
_chunk_wall_start="$SECONDS"
|
|
# Avoid names starting with "_" inside (( )) under set -u (some shells/envs treat expansion oddly).
|
|
fund_progress_every=50
|
|
if [[ -n "${PMM_SOAK_FUND_PROGRESS_EVERY:-}" && "${PMM_SOAK_FUND_PROGRESS_EVERY}" =~ ^[0-9]+$ ]]; then
|
|
fund_progress_every="${PMM_SOAK_FUND_PROGRESS_EVERY}"
|
|
fi
|
|
n=0
|
|
for r in "${RECIPIENTS[@]}"; do
|
|
n=$((n + 1))
|
|
echo "[fund-grid] $n/$total -> $r"
|
|
if [[ "$MODE" == "native" ]]; then
|
|
cast send "$r" --value "$AMOUNT" --rpc-url "$RPC" --private-key "$PK" --legacy --gas-price "$GAS_WEI"
|
|
else
|
|
cast send "$TOKEN_ADDR" 'transfer(address,uint256)(bool)' "$r" "$AMOUNT" \
|
|
--rpc-url "$RPC" --private-key "$PK" --legacy --gas-price "$GAS_WEI"
|
|
fi
|
|
if [[ "${fund_progress_every}" -gt 0 ]]; then
|
|
if (( n % fund_progress_every == 0 )) || (( n == total )); then
|
|
_el=$((SECONDS - _chunk_wall_start))
|
|
python3 -c "n=$n;total=$total;el=$_el;avg=el/n if n else 0.0;rem=total-n;eta=int(rem*avg) if rem>0 else 0;print(f'[fund-grid] progress {n}/{total} chunk_elapsed_s={el} avg_s_per_tx={avg:.2f} est_remaining_this_chunk_s={eta}')" 2>/dev/null || true
|
|
fi
|
|
elif [[ "$n" -eq "$total" ]]; then
|
|
echo "[fund-grid] progress ${n}/${total} chunk_elapsed_s=$((SECONDS - _chunk_wall_start)) (final)"
|
|
fi
|
|
done
|
|
|
|
trap - ERR
|
|
echo "[fund-grid] done"
|