#!/usr/bin/env bash set -euo pipefail # Harvest receiver surplus into the treasury manager and/or distribute quote to # the configured gas and recycle recipients. Default: simulation only. # # Env: # PRIVATE_KEY, ETHEREUM_MAINNET_RPC required # QUOTE_PUSH_TREASURY_MANAGER_MAINNET optional; auto-picks latest manager broadcast # QUOTE_PUSH_TREASURY_HARVEST optional; defaults to 1 # QUOTE_PUSH_TREASURY_GAS_DISTRIBUTION_RAW optional; defaults to 0 # QUOTE_PUSH_TREASURY_RECYCLE_DISTRIBUTION_RAW optional; defaults to 0 # QUOTE_PUSH_TREASURY_TRANSFER_RECEIVER_OWNER_TO optional; transfers receiver ownership when set # # Usage: # bash scripts/deployment/manage-mainnet-quote-push-treasury.sh --dry-run # QUOTE_PUSH_TREASURY_GAS_DISTRIBUTION_RAW=1000 \ # QUOTE_PUSH_TREASURY_RECYCLE_DISTRIBUTION_RAW=2000 \ # bash scripts/deployment/manage-mainnet-quote-push-treasury.sh --apply SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROXMOX_ROOT="$(cd "${SCRIPT_DIR}/../.." && pwd)" SMOM="${PROXMOX_ROOT}/smom-dbis-138" _qp_private_key="${PRIVATE_KEY-}" _qp_rpc="${ETHEREUM_MAINNET_RPC-}" _qp_manager="${QUOTE_PUSH_TREASURY_MANAGER_MAINNET-}" _qp_harvest="${QUOTE_PUSH_TREASURY_HARVEST-}" _qp_gas_raw="${QUOTE_PUSH_TREASURY_GAS_DISTRIBUTION_RAW-}" _qp_recycle_raw="${QUOTE_PUSH_TREASURY_RECYCLE_DISTRIBUTION_RAW-}" _qp_transfer_receiver_owner_to="${QUOTE_PUSH_TREASURY_TRANSFER_RECEIVER_OWNER_TO-}" # 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_harvest" ]] && export QUOTE_PUSH_TREASURY_HARVEST="$_qp_harvest" [[ -n "$_qp_gas_raw" ]] && export QUOTE_PUSH_TREASURY_GAS_DISTRIBUTION_RAW="$_qp_gas_raw" [[ -n "$_qp_recycle_raw" ]] && export QUOTE_PUSH_TREASURY_RECYCLE_DISTRIBUTION_RAW="$_qp_recycle_raw" [[ -n "$_qp_transfer_receiver_owner_to" ]] && export QUOTE_PUSH_TREASURY_TRANSFER_RECEIVER_OWNER_TO="$_qp_transfer_receiver_owner_to" unset _qp_private_key _qp_rpc _qp_manager _qp_harvest _qp_gas_raw _qp_recycle_raw _qp_transfer_receiver_owner_to require_cmd() { command -v "$1" >/dev/null 2>&1 || { echo "[fail] missing required command: $1" >&2 exit 1 } } require_env() { local name="$1" if [[ -z "${!name:-}" ]]; then echo "[fail] missing required env: $name" >&2 exit 1 fi } 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 } require_cmd cast require_cmd forge MODE="dry-run" BROADCAST=() for arg in "$@"; do case "$arg" in --dry-run) MODE="dry-run"; BROADCAST=() ;; --apply) MODE="apply"; BROADCAST=(--broadcast) ;; *) echo "[fail] unknown arg: $arg (use --dry-run or --apply)" >&2 exit 2 ;; esac done require_env PRIVATE_KEY require_env ETHEREUM_MAINNET_RPC 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 require_env QUOTE_PUSH_TREASURY_MANAGER_MAINNET DEPLOYER="$(cast wallet address --private-key "$PRIVATE_KEY")" manager_owner="$(cast call "$QUOTE_PUSH_TREASURY_MANAGER_MAINNET" 'owner()(address)' --rpc-url "$ETHEREUM_MAINNET_RPC" | awk '{print $1}')" manager_operator="$(cast call "$QUOTE_PUSH_TREASURY_MANAGER_MAINNET" 'operator()(address)' --rpc-url "$ETHEREUM_MAINNET_RPC" | awk '{print $1}')" if [[ "${manager_owner,,}" != "${DEPLOYER,,}" && "${manager_operator,,}" != "${DEPLOYER,,}" ]]; then echo "[fail] deployer $DEPLOYER is neither manager owner ($manager_owner) nor operator ($manager_operator)" >&2 exit 1 fi quote_balance="$(cast call "$QUOTE_PUSH_TREASURY_MANAGER_MAINNET" 'quoteBalance()(uint256)' --rpc-url "$ETHEREUM_MAINNET_RPC" | awk '{print $1}')" available_quote="$(cast call "$QUOTE_PUSH_TREASURY_MANAGER_MAINNET" 'availableQuote()(uint256)' --rpc-url "$ETHEREUM_MAINNET_RPC" | awk '{print $1}')" receiver_sweepable="$(cast call "$QUOTE_PUSH_TREASURY_MANAGER_MAINNET" 'receiverSweepableQuote()(uint256)' --rpc-url "$ETHEREUM_MAINNET_RPC" | awk '{print $1}')" echo "=== manage-mainnet-quote-push-treasury ($MODE) ===" echo "manager=$QUOTE_PUSH_TREASURY_MANAGER_MAINNET" echo "manager_owner=$manager_owner" echo "manager_operator=$manager_operator" echo "harvest=${QUOTE_PUSH_TREASURY_HARVEST:-1}" echo "gas_distribution_raw=${QUOTE_PUSH_TREASURY_GAS_DISTRIBUTION_RAW:-0}" echo "recycle_distribution_raw=${QUOTE_PUSH_TREASURY_RECYCLE_DISTRIBUTION_RAW:-0}" echo "transfer_receiver_owner_to=${QUOTE_PUSH_TREASURY_TRANSFER_RECEIVER_OWNER_TO:-0x0000000000000000000000000000000000000000}" echo "quote_balance_raw=$quote_balance" echo "available_quote_raw=$available_quote" echo "receiver_sweepable_raw=$receiver_sweepable" ( cd "$SMOM" forge script script/flash/ManageQuotePushTreasuryManager.s.sol:ManageQuotePushTreasuryManager \ --rpc-url "$ETHEREUM_MAINNET_RPC" \ "${BROADCAST[@]}" \ -vvvv )