2026-04-18 12:07:15 -07:00
|
|
|
|
#!/usr/bin/env bash
|
chore: sync workspace — configs, docs, scripts, CI, pnpm, submodules
- Submodule pins: dbis_core, cross-chain-pmm-lps, mcp-proxmox (local, push may be pending), metamask-integration, smom-dbis-138
- Atomic swap + cross-chain-pmm-lops-publish, deploy-portal workflow, phoenix deploy-targets, routing/aggregator matrices
- Docs, token-lists, forge proxy, phoenix API, runbooks, verify scripts
Made-with: Cursor
2026-04-21 22:01:33 -07:00
|
|
|
|
# Send native ETH to each address in config/pmm-soak-wallet-grid.json (Elemental
|
|
|
|
|
|
# Imperium 33×33×6 matrix).
|
|
|
|
|
|
#
|
|
|
|
|
|
# Default mode (spread): take BALANCE_PCT of the signer's native balance (minus
|
|
|
|
|
|
# optional reserve), split across the selected wallet slice with independent
|
|
|
|
|
|
# uniform random multipliers in [1 - SPREAD_PCT/100, 1 + SPREAD_PCT/100] around
|
|
|
|
|
|
# equal weight, then renormalize so the total sent equals that budget exactly.
|
|
|
|
|
|
#
|
|
|
|
|
|
# Legacy mode: random 5–9 ETH per wallet (--uniform-eth).
|
2026-04-18 12:07:15 -07:00
|
|
|
|
#
|
|
|
|
|
|
# Requires: cast (Foundry), jq, python3. Loads PRIVATE_KEY and RPC via load-project-env.sh.
|
|
|
|
|
|
#
|
|
|
|
|
|
# Usage:
|
|
|
|
|
|
# ./scripts/deployment/send-eth-ei-matrix-wallets.sh [--dry-run] [--limit N] [--offset N]
|
|
|
|
|
|
#
|
chore: sync workspace — configs, docs, scripts, CI, pnpm, submodules
- Submodule pins: dbis_core, cross-chain-pmm-lps, mcp-proxmox (local, push may be pending), metamask-integration, smom-dbis-138
- Atomic swap + cross-chain-pmm-lops-publish, deploy-portal workflow, phoenix deploy-targets, routing/aggregator matrices
- Docs, token-lists, forge proxy, phoenix API, runbooks, verify scripts
Made-with: Cursor
2026-04-21 22:01:33 -07:00
|
|
|
|
# --dry-run Print planned sends only (no transactions).
|
|
|
|
|
|
# --limit N Process at most N wallets (after offset). Default: all.
|
|
|
|
|
|
# --offset N Skip the first N wallets (resume / partial run).
|
|
|
|
|
|
# --balance-pct P Percent of (balance minus reserve) to distribute (default: 80).
|
|
|
|
|
|
# --spread-pct S Per-wallet multiplier range ±S%% around fair share (default: 15).
|
|
|
|
|
|
# --reserve-wei W Wei to leave untouchable before applying balance-pct (default: 0).
|
|
|
|
|
|
# --uniform-eth Legacy: random 5–9 ETH per wallet (ignores balance-pct/spread).
|
2026-04-18 12:07:15 -07:00
|
|
|
|
#
|
|
|
|
|
|
# Gas (Chain 138 / Besu): defaults avoid stuck pending txs from near-zero EIP-1559 caps.
|
|
|
|
|
|
# Override if needed:
|
|
|
|
|
|
# EI_MATRIX_GAS_PRICE=100000000000
|
|
|
|
|
|
# EI_MATRIX_PRIORITY_GAS_PRICE=20000000000
|
|
|
|
|
|
#
|
chore: sync workspace — configs, docs, scripts, CI, pnpm, submodules
- Submodule pins: dbis_core, cross-chain-pmm-lps, mcp-proxmox (local, push may be pending), metamask-integration, smom-dbis-138
- Atomic swap + cross-chain-pmm-lops-publish, deploy-portal workflow, phoenix deploy-targets, routing/aggregator matrices
- Docs, token-lists, forge proxy, phoenix API, runbooks, verify scripts
Made-with: Cursor
2026-04-21 22:01:33 -07:00
|
|
|
|
# Spread mode defaults (same as --balance-pct / --spread-pct / --reserve-wei):
|
|
|
|
|
|
# EI_MATRIX_BALANCE_PCT=80 EI_MATRIX_SPREAD_PCT=15 EI_MATRIX_RESERVE_WEI=0
|
|
|
|
|
|
# Balance query uses public RPC by default; override with EI_MATRIX_BALANCE_RPC. Tx RPC: RPC_URL_138 or public.
|
|
|
|
|
|
#
|
2026-04-18 12:07:15 -07:00
|
|
|
|
# Nonces: each send uses an explicit --nonce from eth_getTransactionCount(..., "pending")
|
|
|
|
|
|
# and increments locally so --async does not race duplicate nonces.
|
|
|
|
|
|
#
|
chore: sync workspace — configs, docs, scripts, CI, pnpm, submodules
- Submodule pins: dbis_core, cross-chain-pmm-lps, mcp-proxmox (local, push may be pending), metamask-integration, smom-dbis-138
- Atomic swap + cross-chain-pmm-lops-publish, deploy-portal workflow, phoenix deploy-targets, routing/aggregator matrices
- Docs, token-lists, forge proxy, phoenix API, runbooks, verify scripts
Made-with: Cursor
2026-04-21 22:01:33 -07:00
|
|
|
|
# RPC: defaults to Chain 138 public HTTP (reachable without LAN). Override with RPC_URL_138
|
|
|
|
|
|
# (e.g. core or Besu on 192.168.x.x). Public URL env: CHAIN138_PUBLIC_RPC_URL or RPC_URL_138_PUBLIC.
|
|
|
|
|
|
#
|
2026-04-18 12:07:15 -07:00
|
|
|
|
set -euo pipefail
|
|
|
|
|
|
|
|
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
|
|
|
|
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
|
|
|
|
|
cd "$PROJECT_ROOT"
|
|
|
|
|
|
|
|
|
|
|
|
DRY_RUN=false
|
|
|
|
|
|
LIMIT=""
|
|
|
|
|
|
OFFSET="0"
|
chore: sync workspace — configs, docs, scripts, CI, pnpm, submodules
- Submodule pins: dbis_core, cross-chain-pmm-lps, mcp-proxmox (local, push may be pending), metamask-integration, smom-dbis-138
- Atomic swap + cross-chain-pmm-lops-publish, deploy-portal workflow, phoenix deploy-targets, routing/aggregator matrices
- Docs, token-lists, forge proxy, phoenix API, runbooks, verify scripts
Made-with: Cursor
2026-04-21 22:01:33 -07:00
|
|
|
|
BALANCE_PCT="${EI_MATRIX_BALANCE_PCT:-80}"
|
|
|
|
|
|
SPREAD_PCT="${EI_MATRIX_SPREAD_PCT:-15}"
|
|
|
|
|
|
RESERVE_WEI="${EI_MATRIX_RESERVE_WEI:-0}"
|
|
|
|
|
|
UNIFORM_ETH_LEGACY=false
|
2026-04-18 12:07:15 -07:00
|
|
|
|
while [[ $# -gt 0 ]]; do
|
|
|
|
|
|
case "$1" in
|
|
|
|
|
|
--dry-run) DRY_RUN=true; shift ;;
|
|
|
|
|
|
--limit) LIMIT="${2:?}"; shift 2 ;;
|
|
|
|
|
|
--offset) OFFSET="${2:?}"; shift 2 ;;
|
chore: sync workspace — configs, docs, scripts, CI, pnpm, submodules
- Submodule pins: dbis_core, cross-chain-pmm-lps, mcp-proxmox (local, push may be pending), metamask-integration, smom-dbis-138
- Atomic swap + cross-chain-pmm-lops-publish, deploy-portal workflow, phoenix deploy-targets, routing/aggregator matrices
- Docs, token-lists, forge proxy, phoenix API, runbooks, verify scripts
Made-with: Cursor
2026-04-21 22:01:33 -07:00
|
|
|
|
--balance-pct) BALANCE_PCT="${2:?}"; shift 2 ;;
|
|
|
|
|
|
--spread-pct) SPREAD_PCT="${2:?}"; shift 2 ;;
|
|
|
|
|
|
--reserve-wei) RESERVE_WEI="${2:?}"; shift 2 ;;
|
|
|
|
|
|
--uniform-eth) UNIFORM_ETH_LEGACY=true; shift ;;
|
2026-04-18 12:07:15 -07:00
|
|
|
|
*) echo "Unknown arg: $1" >&2; exit 1 ;;
|
|
|
|
|
|
esac
|
|
|
|
|
|
done
|
|
|
|
|
|
|
|
|
|
|
|
# shellcheck disable=SC1091
|
|
|
|
|
|
source "$PROJECT_ROOT/scripts/lib/load-project-env.sh"
|
|
|
|
|
|
|
chore: sync workspace — configs, docs, scripts, CI, pnpm, submodules
- Submodule pins: dbis_core, cross-chain-pmm-lps, mcp-proxmox (local, push may be pending), metamask-integration, smom-dbis-138
- Atomic swap + cross-chain-pmm-lops-publish, deploy-portal workflow, phoenix deploy-targets, routing/aggregator matrices
- Docs, token-lists, forge proxy, phoenix API, runbooks, verify scripts
Made-with: Cursor
2026-04-21 22:01:33 -07:00
|
|
|
|
CHAIN138_PUBLIC_RPC_DEFAULT="https://rpc-http-pub.d-bis.org"
|
|
|
|
|
|
RPC_PUBLIC="${CHAIN138_PUBLIC_RPC_URL:-${RPC_URL_138_PUBLIC:-$CHAIN138_PUBLIC_RPC_DEFAULT}}"
|
|
|
|
|
|
# Balance read for spread budget: public RPC first (aligns with deployer checks on public endpoints).
|
|
|
|
|
|
# After that, nonce + sends use RPC (same as RPC_URL_138 when set, else public).
|
|
|
|
|
|
BALANCE_RPC="${EI_MATRIX_BALANCE_RPC:-$RPC_PUBLIC}"
|
|
|
|
|
|
RPC="${RPC_URL_138:-$RPC_PUBLIC}"
|
|
|
|
|
|
|
2026-04-18 12:07:15 -07:00
|
|
|
|
LOCK_FILE="${PROJECT_ROOT}/reports/status/ei-matrix-eth-send.lock"
|
|
|
|
|
|
mkdir -p "$(dirname "$LOCK_FILE")"
|
|
|
|
|
|
exec 200>"$LOCK_FILE"
|
|
|
|
|
|
if ! flock -n 200; then
|
|
|
|
|
|
echo "Another send-eth-ei-matrix-wallets.sh is already running (lock: $LOCK_FILE)." >&2
|
|
|
|
|
|
exit 1
|
|
|
|
|
|
fi
|
|
|
|
|
|
GRID="$PROJECT_ROOT/config/pmm-soak-wallet-grid.json"
|
|
|
|
|
|
DEPLOYER_CANONICAL="0x4A666F96fC8764181194447A7dFdb7d471b301C8"
|
|
|
|
|
|
# Wei per gas — must exceed stuck-replacement threshold on busy pools (see script header).
|
|
|
|
|
|
EI_MATRIX_GAS_PRICE="${EI_MATRIX_GAS_PRICE:-100000000000}"
|
|
|
|
|
|
EI_MATRIX_PRIORITY_GAS_PRICE="${EI_MATRIX_PRIORITY_GAS_PRICE:-20000000000}"
|
|
|
|
|
|
|
|
|
|
|
|
[[ -f "$GRID" ]] || { echo "Missing $GRID" >&2; exit 1; }
|
|
|
|
|
|
command -v cast &>/dev/null || { echo "cast (Foundry) required" >&2; exit 1; }
|
|
|
|
|
|
command -v jq &>/dev/null || { echo "jq required" >&2; exit 1; }
|
|
|
|
|
|
|
|
|
|
|
|
[[ -n "${PRIVATE_KEY:-}" ]] || { echo "PRIVATE_KEY not set (source smom-dbis-138/.env or root .env)" >&2; exit 1; }
|
|
|
|
|
|
|
|
|
|
|
|
FROM_ADDR=$(cast wallet address --private-key "$PRIVATE_KEY")
|
|
|
|
|
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
chore: sync workspace — configs, docs, scripts, CI, pnpm, submodules
- Submodule pins: dbis_core, cross-chain-pmm-lps, mcp-proxmox (local, push may be pending), metamask-integration, smom-dbis-138
- Atomic swap + cross-chain-pmm-lops-publish, deploy-portal workflow, phoenix deploy-targets, routing/aggregator matrices
- Docs, token-lists, forge proxy, phoenix API, runbooks, verify scripts
Made-with: Cursor
2026-04-21 22:01:33 -07:00
|
|
|
|
if $UNIFORM_ETH_LEGACY; then
|
|
|
|
|
|
echo "EI matrix ETH distribution (legacy: random 5–9 ETH per wallet)"
|
|
|
|
|
|
else
|
|
|
|
|
|
echo "EI matrix ETH distribution (${BALANCE_PCT}% of balance, ±${SPREAD_PCT}% jitter, normalized)"
|
|
|
|
|
|
fi
|
2026-04-18 12:07:15 -07:00
|
|
|
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
chore: sync workspace — configs, docs, scripts, CI, pnpm, submodules
- Submodule pins: dbis_core, cross-chain-pmm-lps, mcp-proxmox (local, push may be pending), metamask-integration, smom-dbis-138
- Atomic swap + cross-chain-pmm-lops-publish, deploy-portal workflow, phoenix deploy-targets, routing/aggregator matrices
- Docs, token-lists, forge proxy, phoenix API, runbooks, verify scripts
Made-with: Cursor
2026-04-21 22:01:33 -07:00
|
|
|
|
echo "Balance RPC (public): $BALANCE_RPC"
|
|
|
|
|
|
echo "Tx / nonce RPC: $RPC"
|
2026-04-18 12:07:15 -07:00
|
|
|
|
echo "Signer: $FROM_ADDR"
|
|
|
|
|
|
echo "Grid: $GRID"
|
|
|
|
|
|
echo "Dry-run: $DRY_RUN"
|
|
|
|
|
|
echo "Offset: $OFFSET Limit: ${LIMIT:-all}"
|
chore: sync workspace — configs, docs, scripts, CI, pnpm, submodules
- Submodule pins: dbis_core, cross-chain-pmm-lps, mcp-proxmox (local, push may be pending), metamask-integration, smom-dbis-138
- Atomic swap + cross-chain-pmm-lops-publish, deploy-portal workflow, phoenix deploy-targets, routing/aggregator matrices
- Docs, token-lists, forge proxy, phoenix API, runbooks, verify scripts
Made-with: Cursor
2026-04-21 22:01:33 -07:00
|
|
|
|
if ! $UNIFORM_ETH_LEGACY; then
|
|
|
|
|
|
echo "Reserve: ${RESERVE_WEI} wei excluded before balance-pct"
|
|
|
|
|
|
fi
|
2026-04-18 12:07:15 -07:00
|
|
|
|
echo "Gas: maxFee=$EI_MATRIX_GAS_PRICE wei priorityFee=$EI_MATRIX_PRIORITY_GAS_PRICE wei"
|
|
|
|
|
|
echo ""
|
|
|
|
|
|
|
|
|
|
|
|
if [[ "${FROM_ADDR,,}" != "${DEPLOYER_CANONICAL,,}" ]]; then
|
|
|
|
|
|
echo "[WARN] Signer is not canonical deployer $DEPLOYER_CANONICAL — continuing anyway."
|
|
|
|
|
|
echo ""
|
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
|
|
pending_nonce() {
|
|
|
|
|
|
local resp hex
|
|
|
|
|
|
resp=$(curl -sS -X POST "$RPC" -H "Content-Type: application/json" \
|
|
|
|
|
|
-d "{\"jsonrpc\":\"2.0\",\"method\":\"eth_getTransactionCount\",\"params\":[\"${FROM_ADDR}\",\"pending\"],\"id\":1}" 2>/dev/null) || return 1
|
|
|
|
|
|
hex=$(echo "$resp" | jq -r '.result // empty')
|
|
|
|
|
|
[[ -n "$hex" ]] || return 1
|
|
|
|
|
|
cast to-dec "$hex"
|
|
|
|
|
|
}
|
|
|
|
|
|
|
chore: sync workspace — configs, docs, scripts, CI, pnpm, submodules
- Submodule pins: dbis_core, cross-chain-pmm-lps, mcp-proxmox (local, push may be pending), metamask-integration, smom-dbis-138
- Atomic swap + cross-chain-pmm-lops-publish, deploy-portal workflow, phoenix deploy-targets, routing/aggregator matrices
- Docs, token-lists, forge proxy, phoenix API, runbooks, verify scripts
Made-with: Cursor
2026-04-21 22:01:33 -07:00
|
|
|
|
random_wei_uniform_legacy() {
|
2026-04-18 12:07:15 -07:00
|
|
|
|
python3 -c "import random; from decimal import Decimal; print(int(Decimal(str(random.uniform(5.0, 9.0))) * 10**18))"
|
|
|
|
|
|
}
|
|
|
|
|
|
|
chore: sync workspace — configs, docs, scripts, CI, pnpm, submodules
- Submodule pins: dbis_core, cross-chain-pmm-lps, mcp-proxmox (local, push may be pending), metamask-integration, smom-dbis-138
- Atomic swap + cross-chain-pmm-lops-publish, deploy-portal workflow, phoenix deploy-targets, routing/aggregator matrices
- Docs, token-lists, forge proxy, phoenix API, runbooks, verify scripts
Made-with: Cursor
2026-04-21 22:01:33 -07:00
|
|
|
|
# Args: count budget_wei spread_pct — prints one wei amount per line; sum(lines) == budget_wei
|
|
|
|
|
|
generate_spread_amounts_wei() {
|
|
|
|
|
|
local count="$1" budget="$2" spread="$3"
|
|
|
|
|
|
python3 - "$count" "$budget" "$spread" <<'PY'
|
|
|
|
|
|
import random
|
|
|
|
|
|
import sys
|
|
|
|
|
|
|
|
|
|
|
|
n = int(sys.argv[1])
|
|
|
|
|
|
budget = int(sys.argv[2])
|
|
|
|
|
|
spread = float(sys.argv[3])
|
|
|
|
|
|
if n <= 0:
|
|
|
|
|
|
sys.exit("count must be positive")
|
|
|
|
|
|
if budget < 0:
|
|
|
|
|
|
sys.exit("budget must be non-negative")
|
|
|
|
|
|
if spread < 0 or spread > 100:
|
|
|
|
|
|
sys.exit("spread-pct must be in [0, 100]")
|
|
|
|
|
|
# Integer-only weights (float on ~10^27 wei rounds to 0 → huge remainder loop and hang)
|
|
|
|
|
|
base = 10000
|
|
|
|
|
|
low_w = max(1, (100 * base - int(spread * base)) // 100)
|
|
|
|
|
|
high_w = (100 * base + int(spread * base)) // 100
|
|
|
|
|
|
w = [random.randint(low_w, high_w) for _ in range(n)]
|
|
|
|
|
|
s = sum(w)
|
|
|
|
|
|
raw = [(budget * wi) // s for wi in w]
|
|
|
|
|
|
rem = budget - sum(raw)
|
|
|
|
|
|
for i in range(rem):
|
|
|
|
|
|
raw[i % n] += 1
|
|
|
|
|
|
for w in raw:
|
|
|
|
|
|
print(w)
|
|
|
|
|
|
PY
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-04-18 12:07:15 -07:00
|
|
|
|
ERR_LOG="${PROJECT_ROOT}/reports/status/ei-matrix-eth-send-failures.log"
|
|
|
|
|
|
mkdir -p "$(dirname "$ERR_LOG")"
|
|
|
|
|
|
|
|
|
|
|
|
if ! $DRY_RUN; then
|
|
|
|
|
|
NONCE=$(pending_nonce) || { echo "Could not read pending nonce for $FROM_ADDR" >&2; exit 1; }
|
|
|
|
|
|
echo "Starting nonce (pending): $NONCE"
|
|
|
|
|
|
echo ""
|
|
|
|
|
|
else
|
|
|
|
|
|
NONCE=0
|
|
|
|
|
|
fi
|
|
|
|
|
|
|
chore: sync workspace — configs, docs, scripts, CI, pnpm, submodules
- Submodule pins: dbis_core, cross-chain-pmm-lps, mcp-proxmox (local, push may be pending), metamask-integration, smom-dbis-138
- Atomic swap + cross-chain-pmm-lops-publish, deploy-portal workflow, phoenix deploy-targets, routing/aggregator matrices
- Docs, token-lists, forge proxy, phoenix API, runbooks, verify scripts
Made-with: Cursor
2026-04-21 22:01:33 -07:00
|
|
|
|
# Args: addr wei idx — uses global NONCE, sent, failed, DRY_RUN, RPC, PRIVATE_KEY, EI_MATRIX_* , ERR_LOG
|
|
|
|
|
|
matrix_try_send() {
|
|
|
|
|
|
local addr="$1" wei="$2" idx="$3"
|
|
|
|
|
|
local eth_approx out tx GP PP attempt
|
|
|
|
|
|
if [[ "$wei" == "0" ]]; then
|
|
|
|
|
|
echo "[skip] idx=$idx $addr zero wei"
|
|
|
|
|
|
return 0
|
|
|
|
|
|
fi
|
|
|
|
|
|
eth_approx=$(python3 -c "w=int('$wei'); print(f'{w / 1e18:.6f}')")
|
|
|
|
|
|
if $DRY_RUN; then
|
|
|
|
|
|
echo "[dry-run] idx=$idx $addr ${wei} wei (~${eth_approx} ETH)"
|
|
|
|
|
|
return 0
|
|
|
|
|
|
fi
|
|
|
|
|
|
GP="$EI_MATRIX_GAS_PRICE"
|
|
|
|
|
|
PP="$EI_MATRIX_PRIORITY_GAS_PRICE"
|
|
|
|
|
|
attempt=1
|
|
|
|
|
|
while [[ "$attempt" -le 2 ]]; do
|
|
|
|
|
|
if out=$(cast send "$addr" --value "$wei" --rpc-url "$RPC" --private-key "$PRIVATE_KEY" \
|
|
|
|
|
|
--nonce "$NONCE" \
|
|
|
|
|
|
--async \
|
|
|
|
|
|
--gas-price "$GP" \
|
|
|
|
|
|
--priority-gas-price "$PP" \
|
|
|
|
|
|
2>&1); then
|
|
|
|
|
|
tx=$(echo "$out" | tail -n1)
|
|
|
|
|
|
echo "[ok] idx=$idx nonce=$NONCE $addr ${eth_approx} ETH tx=$tx"
|
|
|
|
|
|
sent=$((sent + 1))
|
|
|
|
|
|
NONCE=$((NONCE + 1))
|
|
|
|
|
|
echo "$idx" > "${PROJECT_ROOT}/reports/status/ei-matrix-eth-send-last-idx.txt"
|
|
|
|
|
|
break
|
|
|
|
|
|
fi
|
|
|
|
|
|
if echo "$out" | grep -q "Replacement transaction underpriced" && [[ "$attempt" -eq 1 ]]; then
|
|
|
|
|
|
GP=$((GP * 2))
|
|
|
|
|
|
PP=$((PP * 2))
|
|
|
|
|
|
NONCE=$(pending_nonce) || true
|
|
|
|
|
|
attempt=$((attempt + 1))
|
|
|
|
|
|
continue
|
|
|
|
|
|
fi
|
|
|
|
|
|
echo "[fail] idx=$idx nonce=$NONCE $addr $out" | tee -a "$ERR_LOG" >&2
|
|
|
|
|
|
failed=$((failed + 1))
|
|
|
|
|
|
NONCE=$(pending_nonce) || true
|
|
|
|
|
|
break
|
|
|
|
|
|
done
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-04-18 12:07:15 -07:00
|
|
|
|
stream_addresses() {
|
chore: sync workspace — configs, docs, scripts, CI, pnpm, submodules
- Submodule pins: dbis_core, cross-chain-pmm-lps, mcp-proxmox (local, push may be pending), metamask-integration, smom-dbis-138
- Atomic swap + cross-chain-pmm-lops-publish, deploy-portal workflow, phoenix deploy-targets, routing/aggregator matrices
- Docs, token-lists, forge proxy, phoenix API, runbooks, verify scripts
Made-with: Cursor
2026-04-21 22:01:33 -07:00
|
|
|
|
# Slice in jq only — jq|head breaks with SIGPIPE under pipefail when LIMIT is set.
|
2026-04-18 12:07:15 -07:00
|
|
|
|
if [[ -n "${LIMIT:-}" ]]; then
|
chore: sync workspace — configs, docs, scripts, CI, pnpm, submodules
- Submodule pins: dbis_core, cross-chain-pmm-lps, mcp-proxmox (local, push may be pending), metamask-integration, smom-dbis-138
- Atomic swap + cross-chain-pmm-lops-publish, deploy-portal workflow, phoenix deploy-targets, routing/aggregator matrices
- Docs, token-lists, forge proxy, phoenix API, runbooks, verify scripts
Made-with: Cursor
2026-04-21 22:01:33 -07:00
|
|
|
|
jq -r --argjson o "$OFFSET" --argjson l "$LIMIT" '.wallets[$o:$o+$l][] | .address' "$GRID"
|
2026-04-18 12:07:15 -07:00
|
|
|
|
else
|
chore: sync workspace — configs, docs, scripts, CI, pnpm, submodules
- Submodule pins: dbis_core, cross-chain-pmm-lps, mcp-proxmox (local, push may be pending), metamask-integration, smom-dbis-138
- Atomic swap + cross-chain-pmm-lops-publish, deploy-portal workflow, phoenix deploy-targets, routing/aggregator matrices
- Docs, token-lists, forge proxy, phoenix API, runbooks, verify scripts
Made-with: Cursor
2026-04-21 22:01:33 -07:00
|
|
|
|
jq -r --argjson o "$OFFSET" '.wallets[$o:][] | .address' "$GRID"
|
2026-04-18 12:07:15 -07:00
|
|
|
|
fi
|
|
|
|
|
|
}
|
|
|
|
|
|
|
chore: sync workspace — configs, docs, scripts, CI, pnpm, submodules
- Submodule pins: dbis_core, cross-chain-pmm-lps, mcp-proxmox (local, push may be pending), metamask-integration, smom-dbis-138
- Atomic swap + cross-chain-pmm-lops-publish, deploy-portal workflow, phoenix deploy-targets, routing/aggregator matrices
- Docs, token-lists, forge proxy, phoenix API, runbooks, verify scripts
Made-with: Cursor
2026-04-21 22:01:33 -07:00
|
|
|
|
compute_budget_wei() {
|
|
|
|
|
|
python3 - "$1" "$2" "$3" <<'PY'
|
|
|
|
|
|
import sys
|
|
|
|
|
|
bal = int(sys.argv[1])
|
|
|
|
|
|
reserve = int(sys.argv[2])
|
|
|
|
|
|
pct = float(sys.argv[3])
|
|
|
|
|
|
avail = max(0, bal - reserve)
|
|
|
|
|
|
print(int(avail * pct / 100.0))
|
|
|
|
|
|
PY
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
ADDR_TMP=""
|
|
|
|
|
|
AMOUNTS_TMP=""
|
|
|
|
|
|
cleanup_tmp() {
|
|
|
|
|
|
[[ -n "$ADDR_TMP" && -f "$ADDR_TMP" ]] && rm -f "$ADDR_TMP"
|
|
|
|
|
|
[[ -n "$AMOUNTS_TMP" && -f "$AMOUNTS_TMP" ]] && rm -f "$AMOUNTS_TMP"
|
|
|
|
|
|
}
|
|
|
|
|
|
trap cleanup_tmp EXIT
|
|
|
|
|
|
|
|
|
|
|
|
if $UNIFORM_ETH_LEGACY; then
|
|
|
|
|
|
:
|
|
|
|
|
|
else
|
|
|
|
|
|
ADDR_TMP=$(mktemp)
|
|
|
|
|
|
AMOUNTS_TMP=$(mktemp)
|
|
|
|
|
|
stream_addresses > "$ADDR_TMP"
|
|
|
|
|
|
WALLET_COUNT=$(wc -l < "$ADDR_TMP" | tr -d '[:space:]')
|
|
|
|
|
|
if [[ -z "$WALLET_COUNT" || "$WALLET_COUNT" -eq 0 ]]; then
|
|
|
|
|
|
echo "No wallets in range (offset=$OFFSET limit=${LIMIT:-all})." >&2
|
|
|
|
|
|
exit 1
|
|
|
|
|
|
fi
|
|
|
|
|
|
BAL_WEI=$(cast balance "$FROM_ADDR" --rpc-url "$BALANCE_RPC" 2>/dev/null | awk '{print $1}' || echo "0")
|
|
|
|
|
|
BUDGET_WEI=$(compute_budget_wei "$BAL_WEI" "$RESERVE_WEI" "$BALANCE_PCT")
|
|
|
|
|
|
eth_bal=$(python3 -c "print(f'{int(\"$BAL_WEI\") / 1e18:.8f}')" 2>/dev/null || echo "?")
|
|
|
|
|
|
eth_bud=$(python3 -c "print(f'{int(\"$BUDGET_WEI\") / 1e18:.8f}')" 2>/dev/null || echo "?")
|
|
|
|
|
|
echo "Balance: $BAL_WEI wei (~$eth_bal ETH)"
|
|
|
|
|
|
echo "Budget: $BUDGET_WEI wei (~$eth_bud ETH) (${BALANCE_PCT}% of max(0, balance − ${RESERVE_WEI} reserve))"
|
|
|
|
|
|
echo "Wallets: $WALLET_COUNT spread: ±${SPREAD_PCT}% then normalized to budget"
|
|
|
|
|
|
echo ""
|
|
|
|
|
|
if [[ "$BUDGET_WEI" == "0" ]]; then
|
|
|
|
|
|
echo "Budget is zero (balance below reserve or pct=0). Nothing to send." >&2
|
|
|
|
|
|
exit 1
|
|
|
|
|
|
fi
|
|
|
|
|
|
generate_spread_amounts_wei "$WALLET_COUNT" "$BUDGET_WEI" "$SPREAD_PCT" > "$AMOUNTS_TMP"
|
|
|
|
|
|
fi
|
|
|
|
|
|
|
2026-04-18 12:07:15 -07:00
|
|
|
|
sent=0
|
|
|
|
|
|
failed=0
|
|
|
|
|
|
idx=$OFFSET
|
chore: sync workspace — configs, docs, scripts, CI, pnpm, submodules
- Submodule pins: dbis_core, cross-chain-pmm-lps, mcp-proxmox (local, push may be pending), metamask-integration, smom-dbis-138
- Atomic swap + cross-chain-pmm-lops-publish, deploy-portal workflow, phoenix deploy-targets, routing/aggregator matrices
- Docs, token-lists, forge proxy, phoenix API, runbooks, verify scripts
Made-with: Cursor
2026-04-21 22:01:33 -07:00
|
|
|
|
|
|
|
|
|
|
if $UNIFORM_ETH_LEGACY; then
|
|
|
|
|
|
while read -r addr; do
|
|
|
|
|
|
wei=$(random_wei_uniform_legacy)
|
|
|
|
|
|
matrix_try_send "$addr" "$wei" "$idx"
|
|
|
|
|
|
idx=$((idx + 1))
|
|
|
|
|
|
done < <(stream_addresses)
|
|
|
|
|
|
else
|
|
|
|
|
|
while IFS=$'\t' read -r addr wei; do
|
|
|
|
|
|
matrix_try_send "$addr" "$wei" "$idx"
|
|
|
|
|
|
idx=$((idx + 1))
|
|
|
|
|
|
done < <(paste -d $'\t' "$ADDR_TMP" "$AMOUNTS_TMP")
|
|
|
|
|
|
fi
|
2026-04-18 12:07:15 -07:00
|
|
|
|
|
|
|
|
|
|
echo ""
|
|
|
|
|
|
if $DRY_RUN; then
|
|
|
|
|
|
echo "Dry-run complete (no transactions sent). Indices covered: $OFFSET..$((idx - 1))."
|
|
|
|
|
|
else
|
|
|
|
|
|
echo "Done. Sent: $sent Failed: $failed"
|
|
|
|
|
|
fi
|