#!/usr/bin/env bash set -euo pipefail # Single entrypoint for the quote-push maintenance loop: # 1. plan current accounting / gas policy # 2. execute one flash quote-push # 3. recycle retained quote via treasury manager or direct sweep fallback # # Default: simulation only. Use --apply to broadcast / execute. # # Env: # PRIVATE_KEY, ETHEREUM_MAINNET_RPC required # DODO_PMM_INTEGRATION_MAINNET required unless QUOTE_PUSH_KEEPER_SKIP_FLASH=1 # QUOTE_PUSH_TREASURY_MANAGER_MAINNET optional; when set, manager path is preferred # QUOTE_PUSH_SURPLUS_TOKEN_MAINNET optional; defaults to mainnet USDC # QUOTE_PUSH_RECEIVER_RESERVE_RAW optional; defaults to 0 # QUOTE_PUSH_DEPLOYER_GAS_FLOOR_ETH optional; defaults to 0.003 # QUOTE_PUSH_OPERATION_BUFFER_ETH optional; defaults to 0.0005 # QUOTE_PUSH_NATIVE_TOKEN_PRICE optional; defaults to 3200 # QUOTE_PUSH_KEEPER_ALLOW_NET_NEGATIVE optional; default 0; set to 1 to bypass modeled net gate # QUOTE_PUSH_KEEPER_SKIP_FLASH optional; default 0 # QUOTE_PUSH_KEEPER_SKIP_RECYCLE optional; default 0 # # Usage: # bash scripts/deployment/run-mainnet-aave-quote-push-keeper.sh --dry-run # bash scripts/deployment/run-mainnet-aave-quote-push-keeper.sh --apply SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROXMOX_ROOT="$(cd "${SCRIPT_DIR}/../.." && pwd)" SMOM="${PROXMOX_ROOT}/smom-dbis-138" DEFAULT_USDC_MAINNET="0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48" _qp_private_key="${PRIVATE_KEY-}" _qp_rpc="${ETHEREUM_MAINNET_RPC-}" _qp_manager="${QUOTE_PUSH_TREASURY_MANAGER_MAINNET-}" _qp_token="${QUOTE_PUSH_SURPLUS_TOKEN_MAINNET-}" _qp_receiver_reserve="${QUOTE_PUSH_RECEIVER_RESERVE_RAW-}" _qp_gas_floor="${QUOTE_PUSH_DEPLOYER_GAS_FLOOR_ETH-}" _qp_gas_buffer="${QUOTE_PUSH_OPERATION_BUFFER_ETH-}" _qp_native_price="${QUOTE_PUSH_NATIVE_TOKEN_PRICE-}" _qp_allow_net_negative="${QUOTE_PUSH_KEEPER_ALLOW_NET_NEGATIVE-}" _qp_skip_flash="${QUOTE_PUSH_KEEPER_SKIP_FLASH-}" _qp_skip_recycle="${QUOTE_PUSH_KEEPER_SKIP_RECYCLE-}" # shellcheck disable=SC1091 source "${PROXMOX_ROOT}/scripts/lib/load-project-env.sh" 2>/dev/null || true # shellcheck disable=SC1091 source "${SMOM}/scripts/load-env.sh" >/dev/null 2>&1 || true [[ -n "$_qp_private_key" ]] && export PRIVATE_KEY="$_qp_private_key" [[ -n "$_qp_rpc" ]] && export ETHEREUM_MAINNET_RPC="$_qp_rpc" [[ -n "$_qp_manager" ]] && export QUOTE_PUSH_TREASURY_MANAGER_MAINNET="$_qp_manager" [[ -n "$_qp_token" ]] && export QUOTE_PUSH_SURPLUS_TOKEN_MAINNET="$_qp_token" [[ -n "$_qp_receiver_reserve" ]] && export QUOTE_PUSH_RECEIVER_RESERVE_RAW="$_qp_receiver_reserve" [[ -n "$_qp_gas_floor" ]] && export QUOTE_PUSH_DEPLOYER_GAS_FLOOR_ETH="$_qp_gas_floor" [[ -n "$_qp_gas_buffer" ]] && export QUOTE_PUSH_OPERATION_BUFFER_ETH="$_qp_gas_buffer" [[ -n "$_qp_native_price" ]] && export QUOTE_PUSH_NATIVE_TOKEN_PRICE="$_qp_native_price" [[ -n "$_qp_allow_net_negative" ]] && export QUOTE_PUSH_KEEPER_ALLOW_NET_NEGATIVE="$_qp_allow_net_negative" [[ -n "$_qp_skip_flash" ]] && export QUOTE_PUSH_KEEPER_SKIP_FLASH="$_qp_skip_flash" [[ -n "$_qp_skip_recycle" ]] && export QUOTE_PUSH_KEEPER_SKIP_RECYCLE="$_qp_skip_recycle" unset _qp_private_key _qp_rpc _qp_manager _qp_token _qp_receiver_reserve _qp_gas_floor unset _qp_gas_buffer _qp_native_price _qp_allow_net_negative _qp_skip_flash _qp_skip_recycle require_cmd() { command -v "$1" >/dev/null 2>&1 || { echo "[fail] missing required command: $1" >&2 exit 1 } } pick_latest_manager() { local latest_json="${SMOM}/broadcast/DeployQuotePushTreasuryManager.s.sol/1/run-latest.json" if [[ ! -f "$latest_json" ]] || ! command -v jq >/dev/null 2>&1; then return 1 fi jq -r '.transactions[]? | select(.transactionType == "CREATE" and .contractName == "QuotePushTreasuryManager") | .contractAddress' \ "$latest_json" | tail -n1 } pick_latest_receiver() { local latest_json="${SMOM}/broadcast/DeployAaveQuotePushFlashReceiver.s.sol/1/run-latest.json" if [[ ! -f "$latest_json" ]] || ! command -v jq >/dev/null 2>&1; then return 1 fi jq -r '.transactions[]? | select(.transactionType == "CREATE" and .contractName == "AaveQuotePushFlashReceiver") | .contractAddress' \ "$latest_json" | tail -n1 } to_human() { python3 - "$1" <<'PY' import sys print(f"{int(sys.argv[1]) / 1_000_000:.6f}") PY } compute_keeper_plan() { local manager_addr="${1:-}" local deployer_eth="$2" local token_addr="$3" local receiver_addr="$4" local receiver_reserve_raw="$5" local gas_floor_eth="$6" local gas_buffer_eth="$7" local native_price="$8" local receiver_quote_raw=0 local manager_quote_raw=0 local manager_available_raw=0 local receiver_sweepable_raw=0 local total_controlled_raw=0 local gas_distribution_raw=0 local recycle_distribution_raw=0 local gas_shortfall_eth=0 local gas_shortfall_quote_raw=0 local gas_recipient="" local recycle_recipient="" if [[ -n "$manager_addr" ]]; then manager_quote_raw="$(cast call "$manager_addr" 'quoteBalance()(uint256)' --rpc-url "$ETHEREUM_MAINNET_RPC" | awk '{print $1}')" manager_available_raw="$(cast call "$manager_addr" 'availableQuote()(uint256)' --rpc-url "$ETHEREUM_MAINNET_RPC" | awk '{print $1}')" receiver_sweepable_raw="$(cast call "$manager_addr" 'receiverSweepableQuote()(uint256)' --rpc-url "$ETHEREUM_MAINNET_RPC" | awk '{print $1}')" gas_recipient="$(cast call "$manager_addr" 'gasRecipient()(address)' --rpc-url "$ETHEREUM_MAINNET_RPC" | awk '{print $1}')" recycle_recipient="$(cast call "$manager_addr" 'recycleRecipient()(address)' --rpc-url "$ETHEREUM_MAINNET_RPC" | awk '{print $1}')" else receiver_quote_raw="$(cast call "$token_addr" 'balanceOf(address)(uint256)' "$receiver_addr" --rpc-url "$ETHEREUM_MAINNET_RPC" | awk '{print $1}')" receiver_sweepable_raw="$( python3 - "$receiver_quote_raw" "$receiver_reserve_raw" <<'PY' import sys receiver_quote_raw = int(sys.argv[1]) receiver_reserve_raw = int(sys.argv[2]) print(max(0, receiver_quote_raw - receiver_reserve_raw)) PY )" fi eval "$( python3 - "$deployer_eth" "$gas_floor_eth" "$gas_buffer_eth" "$native_price" \ "${manager_available_raw:-0}" "${receiver_sweepable_raw:-0}" <<'PY' import math import sys deployer_eth = float(sys.argv[1]) gas_floor_eth = float(sys.argv[2]) gas_buffer_eth = float(sys.argv[3]) native_price = float(sys.argv[4]) manager_available_raw = int(sys.argv[5]) receiver_sweepable_raw = int(sys.argv[6]) gas_shortfall_eth = max(0.0, gas_floor_eth + gas_buffer_eth - deployer_eth) gas_shortfall_quote_raw = math.ceil(gas_shortfall_eth * native_price * 1_000_000) total_controlled_raw = manager_available_raw + receiver_sweepable_raw gas_distribution_raw = min(total_controlled_raw, gas_shortfall_quote_raw) recycle_distribution_raw = max(0, total_controlled_raw - gas_distribution_raw) print(f"GAS_SHORTFALL_ETH={gas_shortfall_eth}") print(f"GAS_SHORTFALL_QUOTE_RAW={gas_shortfall_quote_raw}") print(f"TOTAL_CONTROLLED_RAW={total_controlled_raw}") print(f"GAS_DISTRIBUTION_RAW={gas_distribution_raw}") print(f"RECYCLE_DISTRIBUTION_RAW={recycle_distribution_raw}") PY )" KEEPER_MANAGER_QUOTE_RAW="${manager_quote_raw:-0}" KEEPER_MANAGER_AVAILABLE_RAW="${manager_available_raw:-0}" KEEPER_RECEIVER_QUOTE_RAW="${receiver_quote_raw:-0}" KEEPER_RECEIVER_SWEEPABLE_RAW="${receiver_sweepable_raw:-0}" KEEPER_TOTAL_CONTROLLED_RAW="${TOTAL_CONTROLLED_RAW:-0}" KEEPER_GAS_SHORTFALL_ETH="${GAS_SHORTFALL_ETH:-0}" KEEPER_GAS_SHORTFALL_QUOTE_RAW="${GAS_SHORTFALL_QUOTE_RAW:-0}" KEEPER_GAS_DISTRIBUTION_RAW="${GAS_DISTRIBUTION_RAW:-0}" KEEPER_RECYCLE_DISTRIBUTION_RAW="${RECYCLE_DISTRIBUTION_RAW:-0}" KEEPER_GAS_RECIPIENT="${gas_recipient:-}" KEEPER_RECYCLE_RECIPIENT="${recycle_recipient:-}" } parse_managed_cycle_summary() { local summary_line="$1" local native_price="$2" eval "$( python3 - "$summary_line" "$native_price" <<'PY' import math import sys line = sys.argv[1] native_price = float(sys.argv[2]) parts = {} for token in line.split(): if "=" not in token: continue key, value = token.split("=", 1) parts[key] = value harvested_raw = int(parts.get("harvested_raw", "0")) gas_distribution_raw = int(parts.get("gas_distribution_raw", "0")) recycle_distribution_raw = int(parts.get("recycle_distribution_raw", "0")) estimated_eth_required = float(parts.get("estimated_eth_required", "0") or 0) estimated_total_gas = int(parts.get("estimated_total_gas", "0") or 0) modeled_gas_cost_quote_raw = math.ceil(estimated_eth_required * native_price * 1_000_000) modeled_net_quote_raw = recycle_distribution_raw - modeled_gas_cost_quote_raw print(f"KEEPER_MANAGED_HARVESTED_RAW={harvested_raw}") print(f"KEEPER_MANAGED_GAS_DISTRIBUTION_RAW={gas_distribution_raw}") print(f"KEEPER_MANAGED_RECYCLE_DISTRIBUTION_RAW={recycle_distribution_raw}") print(f"KEEPER_MANAGED_ESTIMATED_ETH_REQUIRED={estimated_eth_required}") print(f"KEEPER_MANAGED_ESTIMATED_TOTAL_GAS={estimated_total_gas}") print(f"KEEPER_MANAGED_GAS_COST_QUOTE_RAW={modeled_gas_cost_quote_raw}") print(f"KEEPER_MANAGED_NET_QUOTE_RAW={modeled_net_quote_raw}") PY )" } require_cmd cast require_cmd python3 require_cmd forge MODE="dry-run" for arg in "$@"; do case "$arg" in --dry-run) MODE="dry-run" ;; --apply) MODE="apply" ;; *) echo "[fail] unknown arg: $arg (use --dry-run or --apply)" >&2 exit 2 ;; esac done if [[ -z "${PRIVATE_KEY:-}" || -z "${ETHEREUM_MAINNET_RPC:-}" ]]; then echo "[fail] PRIVATE_KEY and ETHEREUM_MAINNET_RPC are required" >&2 exit 1 fi if [[ -z "${QUOTE_PUSH_TREASURY_MANAGER_MAINNET:-}" ]]; then inferred_manager="$(pick_latest_manager || true)" if [[ -n "$inferred_manager" && "$inferred_manager" != "null" ]]; then export QUOTE_PUSH_TREASURY_MANAGER_MAINNET="$inferred_manager" fi fi if [[ -z "${AAVE_QUOTE_PUSH_RECEIVER_MAINNET:-}" ]]; then if [[ -n "${QUOTE_PUSH_TREASURY_MANAGER_MAINNET:-}" ]]; then manager_receiver="$(cast call "$QUOTE_PUSH_TREASURY_MANAGER_MAINNET" 'receiver()(address)' --rpc-url "$ETHEREUM_MAINNET_RPC" 2>/dev/null | awk '{print $1}' || true)" if [[ -n "$manager_receiver" && "$manager_receiver" != "0x0000000000000000000000000000000000000000" ]]; then export AAVE_QUOTE_PUSH_RECEIVER_MAINNET="$manager_receiver" fi fi if [[ -z "${AAVE_QUOTE_PUSH_RECEIVER_MAINNET:-}" ]]; then inferred_receiver="$(pick_latest_receiver || true)" if [[ -n "$inferred_receiver" && "$inferred_receiver" != "null" ]]; then export AAVE_QUOTE_PUSH_RECEIVER_MAINNET="$inferred_receiver" fi fi fi SKIP_FLASH="${QUOTE_PUSH_KEEPER_SKIP_FLASH:-0}" SKIP_RECYCLE="${QUOTE_PUSH_KEEPER_SKIP_RECYCLE:-0}" ALLOW_NET_NEGATIVE="${QUOTE_PUSH_KEEPER_ALLOW_NET_NEGATIVE:-0}" TOKEN="${QUOTE_PUSH_SURPLUS_TOKEN_MAINNET:-$DEFAULT_USDC_MAINNET}" RECEIVER="${AAVE_QUOTE_PUSH_RECEIVER_MAINNET:-}" RECEIVER_RESERVE_RAW="${QUOTE_PUSH_RECEIVER_RESERVE_RAW:-0}" GAS_FLOOR_ETH="${QUOTE_PUSH_DEPLOYER_GAS_FLOOR_ETH:-0.003}" OP_BUFFER_ETH="${QUOTE_PUSH_OPERATION_BUFFER_ETH:-0.0005}" NATIVE_TOKEN_PRICE="${QUOTE_PUSH_NATIVE_TOKEN_PRICE:-3200}" DEPLOYER="$(cast wallet address --private-key "$PRIVATE_KEY")" MANAGER="${QUOTE_PUSH_TREASURY_MANAGER_MAINNET:-}" if [[ -n "$MANAGER" ]]; then manager_receiver="$(cast call "$MANAGER" 'receiver()(address)' --rpc-url "$ETHEREUM_MAINNET_RPC" 2>/dev/null | awk '{print $1}' || true)" if [[ -z "$manager_receiver" ]]; then echo "[fail] could not resolve receiver() from manager $MANAGER" >&2 exit 1 fi if [[ -z "$RECEIVER" ]]; then RECEIVER="$manager_receiver" export AAVE_QUOTE_PUSH_RECEIVER_MAINNET="$RECEIVER" elif [[ "${manager_receiver,,}" != "${RECEIVER,,}" ]]; then cat >&2 <}" echo "skip_flash=$SKIP_FLASH" echo "skip_recycle=$SKIP_RECYCLE" echo "allow_net_negative=$ALLOW_NET_NEGATIVE" bash "${PROXMOX_ROOT}/scripts/verify/report-mainnet-aave-quote-push-surplus-accounting.sh" deployer_eth="$(cast balance "$DEPLOYER" --ether --rpc-url "$ETHEREUM_MAINNET_RPC")" compute_keeper_plan "$MANAGER" "$deployer_eth" "$TOKEN" "$RECEIVER" "$RECEIVER_RESERVE_RAW" "$GAS_FLOOR_ETH" "$OP_BUFFER_ETH" "$NATIVE_TOKEN_PRICE" echo echo "=== Keeper policy plan ===" echo "deployer_eth=$deployer_eth" echo "gas_shortfall_eth=$KEEPER_GAS_SHORTFALL_ETH" echo "gas_shortfall_quote_raw=$KEEPER_GAS_SHORTFALL_QUOTE_RAW human=$(to_human "$KEEPER_GAS_SHORTFALL_QUOTE_RAW")" if [[ -n "$MANAGER" ]]; then echo "manager_quote_raw=$KEEPER_MANAGER_QUOTE_RAW human=$(to_human "$KEEPER_MANAGER_QUOTE_RAW")" echo "manager_available_raw=$KEEPER_MANAGER_AVAILABLE_RAW human=$(to_human "$KEEPER_MANAGER_AVAILABLE_RAW")" echo "receiver_sweepable_raw=$KEEPER_RECEIVER_SWEEPABLE_RAW human=$(to_human "$KEEPER_RECEIVER_SWEEPABLE_RAW")" echo "gas_recipient=${KEEPER_GAS_RECIPIENT:-}" echo "recycle_recipient=${KEEPER_RECYCLE_RECIPIENT:-}" else echo "receiver_quote_raw=$KEEPER_RECEIVER_QUOTE_RAW human=$(to_human "$KEEPER_RECEIVER_QUOTE_RAW")" echo "receiver_sweepable_raw=$KEEPER_RECEIVER_SWEEPABLE_RAW human=$(to_human "$KEEPER_RECEIVER_SWEEPABLE_RAW")" fi echo "total_controlled_raw=$KEEPER_TOTAL_CONTROLLED_RAW human=$(to_human "$KEEPER_TOTAL_CONTROLLED_RAW")" echo "planned_gas_distribution_raw=$KEEPER_GAS_DISTRIBUTION_RAW human=$(to_human "$KEEPER_GAS_DISTRIBUTION_RAW")" echo "planned_recycle_distribution_raw=$KEEPER_RECYCLE_DISTRIBUTION_RAW human=$(to_human "$KEEPER_RECYCLE_DISTRIBUTION_RAW")" if [[ "$SKIP_RECYCLE" != "1" ]]; then if [[ -n "$MANAGER" ]]; then manager_receiver_owned="$(cast call "$MANAGER" 'isReceiverOwnedByManager()(bool)' --rpc-url "$ETHEREUM_MAINNET_RPC" | awk '{print $1}')" if [[ "$manager_receiver_owned" != "true" ]]; then cat >&2 < QUOTE_PUSH_TREASURY_TAKE_RECEIVER_OWNERSHIP=1 bash scripts/deployment/deploy-mainnet-quote-push-treasury-manager.sh --apply EOF exit 1 fi else receiver_owner="$(cast call "$RECEIVER" 'owner()(address)' --rpc-url "$ETHEREUM_MAINNET_RPC" 2>/dev/null | awk '{print $1}' || true)" if [[ -z "$receiver_owner" ]]; then cat >&2 <} [hint] Redeploy the updated receiver, then hand it to the treasury manager: bash scripts/deployment/deploy-mainnet-aave-quote-push-receiver.sh --apply AAVE_QUOTE_PUSH_RECEIVER_MAINNET= QUOTE_PUSH_TREASURY_TAKE_RECEIVER_OWNERSHIP=1 bash scripts/deployment/deploy-mainnet-quote-push-treasury-manager.sh --apply EOF exit 1 fi fi fi if [[ -n "$MANAGER" && "$SKIP_FLASH" != "1" && "$SKIP_RECYCLE" != "1" ]]; then export QUOTE_PUSH_TREASURY_HARVEST=1 export QUOTE_PUSH_TREASURY_GAS_HOLDBACK_TARGET_RAW="$KEEPER_GAS_SHORTFALL_QUOTE_RAW" set +e managed_cycle_output="$( bash "${PROXMOX_ROOT}/scripts/deployment/run-mainnet-aave-quote-push-managed-cycle.sh" --dry-run 2>&1 )" managed_cycle_status=$? set -e printf '%s\n' "$managed_cycle_output" if [[ "$managed_cycle_status" -ne 0 ]]; then exit "$managed_cycle_status" fi managed_summary_line="$(printf '%s\n' "$managed_cycle_output" | awk '/MANAGED_CYCLE_SUMMARY / {line=$0} END {print line}')" if [[ -z "$managed_summary_line" ]]; then echo "[fail] managed cycle precheck did not emit MANAGED_CYCLE_SUMMARY" >&2 exit 1 fi parse_managed_cycle_summary "$managed_summary_line" "$NATIVE_TOKEN_PRICE" echo echo "=== Managed cycle economics ===" echo "modeled_harvested_raw=$KEEPER_MANAGED_HARVESTED_RAW human=$(to_human "$KEEPER_MANAGED_HARVESTED_RAW")" echo "modeled_gas_distribution_raw=$KEEPER_MANAGED_GAS_DISTRIBUTION_RAW human=$(to_human "$KEEPER_MANAGED_GAS_DISTRIBUTION_RAW")" echo "modeled_recycle_distribution_raw=$KEEPER_MANAGED_RECYCLE_DISTRIBUTION_RAW human=$(to_human "$KEEPER_MANAGED_RECYCLE_DISTRIBUTION_RAW")" echo "modeled_estimated_eth_required=$KEEPER_MANAGED_ESTIMATED_ETH_REQUIRED" echo "modeled_estimated_total_gas=$KEEPER_MANAGED_ESTIMATED_TOTAL_GAS" echo "modeled_gas_cost_quote_raw=$KEEPER_MANAGED_GAS_COST_QUOTE_RAW human=$(to_human "$KEEPER_MANAGED_GAS_COST_QUOTE_RAW")" echo "modeled_net_quote_raw=$KEEPER_MANAGED_NET_QUOTE_RAW human=$(to_human "$KEEPER_MANAGED_NET_QUOTE_RAW")" if (( KEEPER_MANAGED_NET_QUOTE_RAW <= 0 )) && [[ "$ALLOW_NET_NEGATIVE" != "1" ]]; then echo "[stop] managed cycle is net negative after modeled gas; refusing to execute without QUOTE_PUSH_KEEPER_ALLOW_NET_NEGATIVE=1" if [[ "$MODE" == "dry-run" ]]; then exit 0 fi exit 1 fi if [[ "$MODE" == "dry-run" ]]; then if [[ "${KEEPER_RECYCLE_RECIPIENT,,}" == "${DEPLOYER,,}" ]]; then echo "[plan] A live managed cycle would route recycle quote back to the deployer, after which the wallet LP helper can be attempted." fi exit 0 fi bash "${PROXMOX_ROOT}/scripts/deployment/run-mainnet-aave-quote-push-managed-cycle.sh" --apply echo echo "=== Post-execution accounting ===" bash "${PROXMOX_ROOT}/scripts/verify/report-mainnet-aave-quote-push-surplus-accounting.sh" deployer_eth="$(cast balance "$DEPLOYER" --ether --rpc-url "$ETHEREUM_MAINNET_RPC")" compute_keeper_plan "$MANAGER" "$deployer_eth" "$TOKEN" "$RECEIVER" "$RECEIVER_RESERVE_RAW" "$GAS_FLOOR_ETH" "$OP_BUFFER_ETH" "$NATIVE_TOKEN_PRICE" if python3 - "$KEEPER_GAS_SHORTFALL_ETH" <<'PY' import sys sys.exit(0 if float(sys.argv[1]) > 0 else 1) PY then echo "[stop] quote was distributed, but deployer ETH is still below the recycle floor; skipping wallet LP tranche" exit 0 fi if (( KEEPER_RECYCLE_DISTRIBUTION_RAW == 0 )); then echo "[stop] no recycle allocation remains after gas holdback" exit 0 fi if [[ -z "${KEEPER_RECYCLE_RECIPIENT:-}" || "${KEEPER_RECYCLE_RECIPIENT,,}" != "${DEPLOYER,,}" ]]; then echo "[stop] recycle recipient is not the deployer wallet, so the wallet LP helper is intentionally skipped" exit 0 fi if ! bash "${PROXMOX_ROOT}/scripts/deployment/apply-mainnet-cwusdc-usdc-peg-tranche-from-wallet.sh" --apply; then status=$? if [[ "$status" == "3" ]]; then echo "[stop] recycle distribution completed, but no wallet-funded LP tranche is currently affordable" exit 0 fi exit "$status" fi exit 0 fi if [[ "$SKIP_FLASH" != "1" ]]; then bash "${PROXMOX_ROOT}/scripts/deployment/run-mainnet-aave-cwusdc-quote-push-once.sh" "--${MODE}" fi echo echo "=== Post-execution accounting ===" bash "${PROXMOX_ROOT}/scripts/verify/report-mainnet-aave-quote-push-surplus-accounting.sh" if [[ "$SKIP_RECYCLE" == "1" ]]; then echo "[stop] recycle phase skipped by QUOTE_PUSH_KEEPER_SKIP_RECYCLE=1" exit 0 fi deployer_eth="$(cast balance "$DEPLOYER" --ether --rpc-url "$ETHEREUM_MAINNET_RPC")" compute_keeper_plan "$MANAGER" "$deployer_eth" "$TOKEN" "$RECEIVER" "$RECEIVER_RESERVE_RAW" "$GAS_FLOOR_ETH" "$OP_BUFFER_ETH" "$NATIVE_TOKEN_PRICE" if (( KEEPER_TOTAL_CONTROLLED_RAW == 0 )); then echo "[stop] no controllable quote is available for recycle" exit 0 fi if [[ -n "$MANAGER" ]]; then export QUOTE_PUSH_TREASURY_HARVEST="$( python3 - "$KEEPER_RECEIVER_SWEEPABLE_RAW" <<'PY' import sys print("1" if int(sys.argv[1]) > 0 else "0") PY )" export QUOTE_PUSH_TREASURY_GAS_DISTRIBUTION_RAW="$KEEPER_GAS_DISTRIBUTION_RAW" export QUOTE_PUSH_TREASURY_RECYCLE_DISTRIBUTION_RAW="$KEEPER_RECYCLE_DISTRIBUTION_RAW" bash "${PROXMOX_ROOT}/scripts/deployment/manage-mainnet-quote-push-treasury.sh" "--${MODE}" if [[ "$MODE" == "dry-run" ]]; then if [[ "${KEEPER_RECYCLE_RECIPIENT,,}" == "${DEPLOYER,,}" && "$KEEPER_RECYCLE_DISTRIBUTION_RAW" != "0" ]]; then echo "[plan] After a live manager distribution to the deployer, the wallet tranche helper will be attempted." fi exit 0 fi if python3 - "$KEEPER_GAS_SHORTFALL_ETH" <<'PY' import sys sys.exit(0 if float(sys.argv[1]) > 0 else 1) PY then echo "[stop] quote was distributed, but deployer ETH is still below the recycle floor; skipping wallet LP tranche" exit 0 fi if (( KEEPER_RECYCLE_DISTRIBUTION_RAW == 0 )); then echo "[stop] no recycle allocation remains after gas holdback" exit 0 fi if [[ -z "${KEEPER_RECYCLE_RECIPIENT:-}" || "${KEEPER_RECYCLE_RECIPIENT,,}" != "${DEPLOYER,,}" ]]; then echo "[stop] recycle recipient is not the deployer wallet, so the wallet LP helper is intentionally skipped" exit 0 fi if ! bash "${PROXMOX_ROOT}/scripts/deployment/apply-mainnet-cwusdc-usdc-peg-tranche-from-wallet.sh" --apply; then status=$? if [[ "$status" == "3" ]]; then echo "[stop] recycle distribution completed, but no wallet-funded LP tranche is currently affordable" exit 0 fi exit "$status" fi else bash "${PROXMOX_ROOT}/scripts/deployment/recycle-mainnet-aave-quote-push-surplus.sh" "--${MODE}" fi