#!/usr/bin/env bash set -euo pipefail # Deploy the Mainnet quote-push treasury manager and optionally transfer the # receiver ownership to it. Default: simulation only. Use --apply to broadcast. # # Env: # PRIVATE_KEY, ETHEREUM_MAINNET_RPC required # AAVE_QUOTE_PUSH_RECEIVER_MAINNET optional; auto-picks latest receiver broadcast # QUOTE_PUSH_SURPLUS_TOKEN_MAINNET optional; defaults to mainnet USDC # QUOTE_PUSH_TREASURY_OWNER optional; defaults to deployer # QUOTE_PUSH_TREASURY_OPERATOR optional; defaults to owner # QUOTE_PUSH_TREASURY_GAS_RECIPIENT optional; defaults to owner # QUOTE_PUSH_TREASURY_RECYCLE_RECIPIENT optional; defaults to owner # QUOTE_PUSH_RECEIVER_RESERVE_RAW optional; defaults to 0 # QUOTE_PUSH_TREASURY_RESERVE_RAW optional; defaults to 0 # QUOTE_PUSH_TREASURY_TAKE_RECEIVER_OWNERSHIP optional; 1 transfers receiver ownership to manager # # Usage: # bash scripts/deployment/deploy-mainnet-quote-push-treasury-manager.sh --dry-run # QUOTE_PUSH_TREASURY_TAKE_RECEIVER_OWNERSHIP=1 \ # bash scripts/deployment/deploy-mainnet-quote-push-treasury-manager.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_receiver="${AAVE_QUOTE_PUSH_RECEIVER_MAINNET-}" _qp_token="${QUOTE_PUSH_SURPLUS_TOKEN_MAINNET-}" _qp_owner="${QUOTE_PUSH_TREASURY_OWNER-}" _qp_operator="${QUOTE_PUSH_TREASURY_OPERATOR-}" _qp_gas_recipient="${QUOTE_PUSH_TREASURY_GAS_RECIPIENT-}" _qp_recycle_recipient="${QUOTE_PUSH_TREASURY_RECYCLE_RECIPIENT-}" _qp_receiver_reserve="${QUOTE_PUSH_RECEIVER_RESERVE_RAW-}" _qp_manager_reserve="${QUOTE_PUSH_TREASURY_RESERVE_RAW-}" _qp_take_receiver="${QUOTE_PUSH_TREASURY_TAKE_RECEIVER_OWNERSHIP-}" # 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_receiver" ]] && export AAVE_QUOTE_PUSH_RECEIVER_MAINNET="$_qp_receiver" [[ -n "$_qp_token" ]] && export QUOTE_PUSH_SURPLUS_TOKEN_MAINNET="$_qp_token" [[ -n "$_qp_owner" ]] && export QUOTE_PUSH_TREASURY_OWNER="$_qp_owner" [[ -n "$_qp_operator" ]] && export QUOTE_PUSH_TREASURY_OPERATOR="$_qp_operator" [[ -n "$_qp_gas_recipient" ]] && export QUOTE_PUSH_TREASURY_GAS_RECIPIENT="$_qp_gas_recipient" [[ -n "$_qp_recycle_recipient" ]] && export QUOTE_PUSH_TREASURY_RECYCLE_RECIPIENT="$_qp_recycle_recipient" [[ -n "$_qp_receiver_reserve" ]] && export QUOTE_PUSH_RECEIVER_RESERVE_RAW="$_qp_receiver_reserve" [[ -n "$_qp_manager_reserve" ]] && export QUOTE_PUSH_TREASURY_RESERVE_RAW="$_qp_manager_reserve" [[ -n "$_qp_take_receiver" ]] && export QUOTE_PUSH_TREASURY_TAKE_RECEIVER_OWNERSHIP="$_qp_take_receiver" unset _qp_private_key _qp_rpc _qp_receiver _qp_token _qp_owner _qp_operator _qp_gas_recipient unset _qp_recycle_recipient _qp_receiver_reserve _qp_manager_reserve _qp_take_receiver 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 } resolved_chain_id() { if [[ -n "${ETHEREUM_MAINNET_RPC:-}" ]] && command -v cast >/dev/null 2>&1; then cast chain-id --rpc-url "$ETHEREUM_MAINNET_RPC" 2>/dev/null | awk '{print $1}' return 0 fi echo "1" } pick_latest_create_address() { local script_name="$1" local contract_name="$2" local mode="${3:-apply}" local chain_id chain_id="$(resolved_chain_id)" local latest_json="${SMOM}/broadcast/${script_name}/${chain_id}/run-latest.json" if [[ "$mode" == "dry-run" ]]; then latest_json="${SMOM}/broadcast/${script_name}/${chain_id}/dry-run/run-latest.json" fi if [[ ! -f "$latest_json" ]] || ! command -v jq >/dev/null 2>&1; then return 1 fi jq -r --arg contract "$contract_name" \ '.transactions[]? | select(.transactionType == "CREATE" and .contractName == $contract) | .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 DEPLOYER="$(cast wallet address --private-key "$PRIVATE_KEY")" if [[ -z "${AAVE_QUOTE_PUSH_RECEIVER_MAINNET:-}" ]]; then inferred_receiver="$(pick_latest_create_address "DeployAaveQuotePushFlashReceiver.s.sol" "AaveQuotePushFlashReceiver" "apply" || true)" if [[ -n "$inferred_receiver" && "$inferred_receiver" != "null" ]]; then export AAVE_QUOTE_PUSH_RECEIVER_MAINNET="$inferred_receiver" fi fi require_env AAVE_QUOTE_PUSH_RECEIVER_MAINNET if [[ "${QUOTE_PUSH_TREASURY_TAKE_RECEIVER_OWNERSHIP:-0}" == "1" ]]; then current_receiver_owner="$(cast call "$AAVE_QUOTE_PUSH_RECEIVER_MAINNET" 'owner()(address)' --rpc-url "$ETHEREUM_MAINNET_RPC" 2>/dev/null | awk '{print $1}' || true)" if [[ -z "$current_receiver_owner" ]]; then echo "[fail] receiver does not expose owner(): $AAVE_QUOTE_PUSH_RECEIVER_MAINNET" >&2 exit 1 fi if [[ "${current_receiver_owner,,}" != "${DEPLOYER,,}" ]]; then cat >&2 <&2 <&2 <