Files
proxmox/scripts/deployment/run-mainnet-aave-cwusdc-quote-push-once.sh
2026-04-13 21:38:57 -07:00

320 lines
13 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
# Run one Mainnet Aave flash quote-push via forge (see RunMainnetAaveCwusdcUsdcQuotePushOnce.s.sol).
# Default: simulation only. Use --apply to broadcast.
#
# Required env:
# PRIVATE_KEY, ETHEREUM_MAINNET_RPC
# DODO_PMM_INTEGRATION_MAINNET
# AAVE_QUOTE_PUSH_RECEIVER_MAINNET optional; defaults to canonical receiver or latest broadcast
# QUOTE_PUSH_EXTERNAL_UNWINDER_MAINNET optional; can be auto-picked from latest broadcast when QUOTE_PUSH_UNWINDER_TYPE is set
# FLASH_QUOTE_AMOUNT_RAW optional; defaults to 200000
# UNWIND_MODE: 0 = V3 single-hop fee; 1 = DODO pool; 2 = V3 exactInput path (UNWIND_V3_PATH_HEX);
# 4 = TwoHopDodoIntegrationUnwinder (UNWIND_TWO_HOP_*)
# 5 = DODOToUniswapV3MultiHopExternalUnwinder (UNWIND_DODO_POOL + UNWIND_INTERMEDIATE_TOKEN + UNWIND_V3_PATH_HEX)
# 6 = TwoHopDodoToUniswapV3MultiHopExternalUnwinder
# (UNWIND_TWO_HOP_* + UNWIND_INTERMEDIATE_TOKEN + UNWIND_V3_PATH_HEX)
#
# Usage:
# source scripts/lib/load-project-env.sh
# bash scripts/deployment/run-mainnet-aave-cwusdc-quote-push-once.sh --dry-run
# bash scripts/deployment/run-mainnet-aave-cwusdc-quote-push-once.sh --apply
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROXMOX_ROOT="$(cd "${SCRIPT_DIR}/../.." && pwd)"
SMOM="${PROXMOX_ROOT}/smom-dbis-138"
DEFAULT_AAVE_QUOTE_PUSH_RECEIVER_MAINNET="0x241cb416aaFC2654078b7E2376adED2bDeFbCBa2"
DEFAULT_POOL_CWUSDC_USDC_MAINNET="0x69776fc607e9edA8042e320e7e43f54d06c68f0E"
# Preserve explicit caller overrides across sourced repo env files.
_qp_private_key="${PRIVATE_KEY-}"
_qp_rpc="${ETHEREUM_MAINNET_RPC-}"
_qp_receiver="${AAVE_QUOTE_PUSH_RECEIVER_MAINNET-}"
_qp_unwinder="${QUOTE_PUSH_EXTERNAL_UNWINDER_MAINNET-}"
_qp_amount="${FLASH_QUOTE_AMOUNT_RAW-}"
_qp_unwind_type="${QUOTE_PUSH_UNWINDER_TYPE-}"
_qp_unwind_mode="${UNWIND_MODE-}"
_qp_pool="${POOL_CWUSDC_USDC_MAINNET-}"
_qp_integration="${DODO_PMM_INTEGRATION_MAINNET-}"
_qp_pool_a="${UNWIND_TWO_HOP_POOL_A-}"
_qp_pool_b="${UNWIND_TWO_HOP_POOL_B-}"
_qp_mid_token="${UNWIND_TWO_HOP_MID_TOKEN-}"
_qp_min_mid_out="${UNWIND_MIN_MID_OUT_RAW-}"
_qp_min_out_pmm="${MIN_OUT_PMM-}"
_qp_min_out_unwind="${MIN_OUT_UNWIND-}"
_qp_min_out_unwind_buffer="${MIN_OUT_UNWIND_BUFFER_RAW-}"
_qp_fee_u24="${UNWIND_V3_FEE_U24-}"
_qp_dodo_pool="${UNWIND_DODO_POOL-}"
_qp_v3_path="${UNWIND_V3_PATH_HEX-}"
_qp_intermediate_token="${UNWIND_INTERMEDIATE_TOKEN-}"
_qp_min_intermediate_out="${UNWIND_MIN_INTERMEDIATE_OUT_RAW-}"
# 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_unwinder" ]] && export QUOTE_PUSH_EXTERNAL_UNWINDER_MAINNET="$_qp_unwinder"
[[ -n "$_qp_amount" ]] && export FLASH_QUOTE_AMOUNT_RAW="$_qp_amount"
[[ -n "$_qp_unwind_type" ]] && export QUOTE_PUSH_UNWINDER_TYPE="$_qp_unwind_type"
[[ -n "$_qp_unwind_mode" ]] && export UNWIND_MODE="$_qp_unwind_mode"
[[ -n "$_qp_pool" ]] && export POOL_CWUSDC_USDC_MAINNET="$_qp_pool"
[[ -n "$_qp_integration" ]] && export DODO_PMM_INTEGRATION_MAINNET="$_qp_integration"
[[ -n "$_qp_pool_a" ]] && export UNWIND_TWO_HOP_POOL_A="$_qp_pool_a"
[[ -n "$_qp_pool_b" ]] && export UNWIND_TWO_HOP_POOL_B="$_qp_pool_b"
[[ -n "$_qp_mid_token" ]] && export UNWIND_TWO_HOP_MID_TOKEN="$_qp_mid_token"
[[ -n "$_qp_min_mid_out" ]] && export UNWIND_MIN_MID_OUT_RAW="$_qp_min_mid_out"
[[ -n "$_qp_min_out_pmm" ]] && export MIN_OUT_PMM="$_qp_min_out_pmm"
[[ -n "$_qp_min_out_unwind" ]] && export MIN_OUT_UNWIND="$_qp_min_out_unwind"
[[ -n "$_qp_min_out_unwind_buffer" ]] && export MIN_OUT_UNWIND_BUFFER_RAW="$_qp_min_out_unwind_buffer"
[[ -n "$_qp_fee_u24" ]] && export UNWIND_V3_FEE_U24="$_qp_fee_u24"
[[ -n "$_qp_dodo_pool" ]] && export UNWIND_DODO_POOL="$_qp_dodo_pool"
[[ -n "$_qp_v3_path" ]] && export UNWIND_V3_PATH_HEX="$_qp_v3_path"
[[ -n "$_qp_intermediate_token" ]] && export UNWIND_INTERMEDIATE_TOKEN="$_qp_intermediate_token"
[[ -n "$_qp_min_intermediate_out" ]] && export UNWIND_MIN_INTERMEDIATE_OUT_RAW="$_qp_min_intermediate_out"
unset _qp_private_key _qp_rpc _qp_receiver _qp_unwinder _qp_amount _qp_unwind_type _qp_unwind_mode
unset _qp_pool _qp_integration _qp_pool_a _qp_pool_b _qp_mid_token _qp_min_mid_out _qp_min_out_pmm
unset _qp_min_out_unwind _qp_min_out_unwind_buffer _qp_fee_u24 _qp_dodo_pool _qp_v3_path
unset _qp_intermediate_token _qp_min_intermediate_out
BROADCAST=()
if (($# == 0)); then
:
else
for a in "$@"; do
case "$a" in
--apply) BROADCAST=(--broadcast) ;;
--dry-run) BROADCAST=() ;;
*)
echo "[fail] unknown arg: $a" >&2
exit 2
;;
esac
done
fi
require() {
local n="$1"
if [[ -z "${!n:-}" ]]; then
if [[ "$n" == "QUOTE_PUSH_EXTERNAL_UNWINDER_MAINNET" ]]; then
cat >&2 <<EOF
[fail] missing required env: QUOTE_PUSH_EXTERNAL_UNWINDER_MAINNET
[hint] No real broadcasted unwinder was found for auto-pick.
[hint] Next step:
QUOTE_PUSH_UNWINDER_TYPE=two_hop_dodo bash scripts/deployment/deploy-mainnet-aave-quote-push-stack.sh --apply
[hint] Then export:
AAVE_QUOTE_PUSH_RECEIVER_MAINNET=${AAVE_QUOTE_PUSH_RECEIVER_MAINNET:-$DEFAULT_AAVE_QUOTE_PUSH_RECEIVER_MAINNET}
QUOTE_PUSH_EXTERNAL_UNWINDER_MAINNET=<real_apply_deployed_unwinder_address>
FLASH_QUOTE_AMOUNT_RAW=${FLASH_QUOTE_AMOUNT_RAW:-200000}
UNWIND_MODE=${UNWIND_MODE:-4}
UNWIND_TWO_HOP_POOL_A=${UNWIND_TWO_HOP_POOL_A:-0xe944b7Cb012A0820c07f54D51e92f0e1C74168DB}
UNWIND_TWO_HOP_POOL_B=${UNWIND_TWO_HOP_POOL_B:-0x27f3aE7EE71Be3d77bAf17d4435cF8B895DD25D2}
UNWIND_TWO_HOP_MID_TOKEN=${UNWIND_TWO_HOP_MID_TOKEN:-0xaF5017d0163ecb99d9B5D94e3b4D7b09Af44D8AE}
EOF
exit 1
fi
echo "[fail] missing required env: $n" >&2
exit 1
fi
}
pick_latest_create_address() {
local script_name="$1"
local contract_name="$2"
local latest_json="${SMOM}/broadcast/${script_name}/1/run-latest.json"
if [[ ! -f "$latest_json" ]]; then
return 1
fi
if ! 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
}
pick_default_unwinder() {
local addr=""
PICK_DEFAULT_UNWINDER_ADDR=""
PICK_DEFAULT_UNWINDER_MODE=""
addr="$(pick_latest_create_address "DeployTwoHopDodoIntegrationUnwinder.s.sol" "TwoHopDodoIntegrationUnwinder" || true)"
if [[ -n "$addr" && "$addr" != "null" ]]; then
PICK_DEFAULT_UNWINDER_ADDR="$addr"
PICK_DEFAULT_UNWINDER_MODE="4"
return 0
fi
addr="$(pick_latest_create_address "DeployDODOIntegrationExternalUnwinder.s.sol" "DODOIntegrationExternalUnwinder" || true)"
if [[ -n "$addr" && "$addr" != "null" ]]; then
PICK_DEFAULT_UNWINDER_ADDR="$addr"
PICK_DEFAULT_UNWINDER_MODE="1"
return 0
fi
addr="$(pick_latest_create_address "DeployUniswapV3ExternalUnwinder.s.sol" "UniswapV3ExternalUnwinder" || true)"
if [[ -n "$addr" && "$addr" != "null" ]]; then
PICK_DEFAULT_UNWINDER_ADDR="$addr"
PICK_DEFAULT_UNWINDER_MODE="0"
return 0
fi
addr="$(pick_latest_create_address "DeployDODOToUniswapV3MultiHopExternalUnwinder.s.sol" "DODOToUniswapV3MultiHopExternalUnwinder" || true)"
if [[ -n "$addr" && "$addr" != "null" ]]; then
PICK_DEFAULT_UNWINDER_ADDR="$addr"
PICK_DEFAULT_UNWINDER_MODE="5"
return 0
fi
addr="$(pick_latest_create_address "DeployTwoHopDodoToUniswapV3MultiHopExternalUnwinder.s.sol" "TwoHopDodoToUniswapV3MultiHopExternalUnwinder" || true)"
if [[ -n "$addr" && "$addr" != "null" ]]; then
PICK_DEFAULT_UNWINDER_ADDR="$addr"
PICK_DEFAULT_UNWINDER_MODE="6"
return 0
fi
return 1
}
UNW="${QUOTE_PUSH_UNWINDER_TYPE:-}"
if [[ -z "${AAVE_QUOTE_PUSH_RECEIVER_MAINNET:-}" ]]; then
inferred_receiver="$(pick_latest_create_address "DeployAaveQuotePushFlashReceiver.s.sol" "AaveQuotePushFlashReceiver" || true)"
export AAVE_QUOTE_PUSH_RECEIVER_MAINNET="${inferred_receiver:-$DEFAULT_AAVE_QUOTE_PUSH_RECEIVER_MAINNET}"
fi
if [[ -z "${POOL_CWUSDC_USDC_MAINNET:-}" || "${_qp_pool:-}" == "" ]]; then
export POOL_CWUSDC_USDC_MAINNET="$DEFAULT_POOL_CWUSDC_USDC_MAINNET"
fi
if [[ -z "${FLASH_QUOTE_AMOUNT_RAW:-}" ]]; then
export FLASH_QUOTE_AMOUNT_RAW=200000
fi
if [[ -z "${MIN_OUT_PMM:-}" ]]; then
export MIN_OUT_PMM=1
fi
if [[ -z "${QUOTE_PUSH_EXTERNAL_UNWINDER_MAINNET:-}" && -n "$UNW" ]]; then
unwind_script=""
unwind_contract=""
case "$UNW" in
univ3)
unwind_script="DeployUniswapV3ExternalUnwinder.s.sol"
unwind_contract="UniswapV3ExternalUnwinder"
export UNWIND_MODE="${UNWIND_MODE:-0}"
;;
dodo)
unwind_script="DeployDODOIntegrationExternalUnwinder.s.sol"
unwind_contract="DODOIntegrationExternalUnwinder"
export UNWIND_MODE="${UNWIND_MODE:-1}"
;;
two_hop_dodo)
unwind_script="DeployTwoHopDodoIntegrationUnwinder.s.sol"
unwind_contract="TwoHopDodoIntegrationUnwinder"
export UNWIND_MODE="${UNWIND_MODE:-4}"
;;
dodo_univ3)
unwind_script="DeployDODOToUniswapV3MultiHopExternalUnwinder.s.sol"
unwind_contract="DODOToUniswapV3MultiHopExternalUnwinder"
export UNWIND_MODE="${UNWIND_MODE:-5}"
;;
two_hop_dodo_univ3)
unwind_script="DeployTwoHopDodoToUniswapV3MultiHopExternalUnwinder.s.sol"
unwind_contract="TwoHopDodoToUniswapV3MultiHopExternalUnwinder"
export UNWIND_MODE="${UNWIND_MODE:-6}"
;;
*)
echo "[fail] QUOTE_PUSH_UNWINDER_TYPE must be univ3, dodo, two_hop_dodo, dodo_univ3, or two_hop_dodo_univ3 when set" >&2
exit 1
;;
esac
inferred_unwinder="$(pick_latest_create_address "$unwind_script" "$unwind_contract" || true)"
if [[ -n "$inferred_unwinder" && "$inferred_unwinder" != "null" ]]; then
export QUOTE_PUSH_EXTERNAL_UNWINDER_MAINNET="$inferred_unwinder"
fi
fi
if [[ -z "${QUOTE_PUSH_EXTERNAL_UNWINDER_MAINNET:-}" ]]; then
if pick_default_unwinder; then
if [[ -n "$PICK_DEFAULT_UNWINDER_ADDR" && "$PICK_DEFAULT_UNWINDER_ADDR" != "null" ]]; then
export QUOTE_PUSH_EXTERNAL_UNWINDER_MAINNET="$PICK_DEFAULT_UNWINDER_ADDR"
export UNWIND_MODE="$PICK_DEFAULT_UNWINDER_MODE"
fi
fi
fi
if [[ "${UNWIND_MODE:-}" == "4" ]]; then
export UNWIND_TWO_HOP_POOL_A="${UNWIND_TWO_HOP_POOL_A:-0xe944b7Cb012A0820c07f54D51e92f0e1C74168DB}"
export UNWIND_TWO_HOP_POOL_B="${UNWIND_TWO_HOP_POOL_B:-0x27f3aE7EE71Be3d77bAf17d4435cF8B895DD25D2}"
export UNWIND_TWO_HOP_MID_TOKEN="${UNWIND_TWO_HOP_MID_TOKEN:-0xaF5017d0163ecb99d9B5D94e3b4D7b09Af44D8AE}"
export UNWIND_MIN_MID_OUT_RAW="${UNWIND_MIN_MID_OUT_RAW:-1}"
elif [[ "${UNWIND_MODE:-}" == "5" ]]; then
export UNWIND_DODO_POOL="${UNWIND_DODO_POOL:-0xCC0fd27A40775c9AfcD2BBd3f7c902b0192c247A}"
export UNWIND_INTERMEDIATE_TOKEN="${UNWIND_INTERMEDIATE_TOKEN:-0xdAC17F958D2ee523a2206206994597C13D831ec7}"
export UNWIND_MIN_INTERMEDIATE_OUT_RAW="${UNWIND_MIN_INTERMEDIATE_OUT_RAW:-1}"
elif [[ "${UNWIND_MODE:-}" == "6" ]]; then
export UNWIND_TWO_HOP_POOL_A="${UNWIND_TWO_HOP_POOL_A:-0xe944b7Cb012A0820c07f54D51e92f0e1C74168DB}"
export UNWIND_TWO_HOP_POOL_B="${UNWIND_TWO_HOP_POOL_B:-0x79156F6B7bf71a1B72D78189B540A89A6C13F6FC}"
export UNWIND_TWO_HOP_MID_TOKEN="${UNWIND_TWO_HOP_MID_TOKEN:-0xaF5017d0163ecb99d9B5D94e3b4D7b09Af44D8AE}"
export UNWIND_INTERMEDIATE_TOKEN="${UNWIND_INTERMEDIATE_TOKEN:-0xdAC17F958D2ee523a2206206994597C13D831ec7}"
export UNWIND_MIN_MID_OUT_RAW="${UNWIND_MIN_MID_OUT_RAW:-1}"
export UNWIND_MIN_INTERMEDIATE_OUT_RAW="${UNWIND_MIN_INTERMEDIATE_OUT_RAW:-1}"
export MIN_OUT_UNWIND_BUFFER_RAW="${MIN_OUT_UNWIND_BUFFER_RAW:-0}"
fi
require ETHEREUM_MAINNET_RPC
require PRIVATE_KEY
require AAVE_QUOTE_PUSH_RECEIVER_MAINNET
require QUOTE_PUSH_EXTERNAL_UNWINDER_MAINNET
require DODO_PMM_INTEGRATION_MAINNET
require FLASH_QUOTE_AMOUNT_RAW
UM="${UNWIND_MODE:-0}"
if [[ "$UM" == "0" ]]; then
require UNWIND_V3_FEE_U24
elif [[ "$UM" == "1" ]]; then
require UNWIND_DODO_POOL
elif [[ "$UM" == "2" ]]; then
require UNWIND_V3_PATH_HEX
elif [[ "$UM" == "4" ]]; then
require UNWIND_TWO_HOP_POOL_A
require UNWIND_TWO_HOP_POOL_B
require UNWIND_TWO_HOP_MID_TOKEN
elif [[ "$UM" == "5" ]]; then
require UNWIND_DODO_POOL
require UNWIND_INTERMEDIATE_TOKEN
require UNWIND_V3_PATH_HEX
elif [[ "$UM" == "6" ]]; then
require UNWIND_TWO_HOP_POOL_A
require UNWIND_TWO_HOP_POOL_B
require UNWIND_TWO_HOP_MID_TOKEN
require UNWIND_INTERMEDIATE_TOKEN
require UNWIND_V3_PATH_HEX
else
echo "[fail] UNWIND_MODE must be 0, 1, 2, 4, 5, or 6" >&2
exit 1
fi
echo "receiver=$AAVE_QUOTE_PUSH_RECEIVER_MAINNET"
echo "unwinder=$QUOTE_PUSH_EXTERNAL_UNWINDER_MAINNET"
echo "flash_quote_amount_raw=$FLASH_QUOTE_AMOUNT_RAW unwind_mode=$UM"
(
cd "$SMOM"
forge script script/flash/RunMainnetAaveCwusdcUsdcQuotePushOnce.s.sol:RunMainnetAaveCwusdcUsdcQuotePushOnce \
--rpc-url "$ETHEREUM_MAINNET_RPC" \
"${BROADCAST[@]}" \
-vvvv
)
echo "Done. Re-check: bash scripts/verify/check-mainnet-cwusdc-usdc-reserve-peg.sh"
echo "Receiver surplus accounting: bash scripts/verify/report-mainnet-aave-quote-push-surplus-accounting.sh"