2026-04-12 06:12:20 -07:00
#!/usr/bin/env bash
set -euo pipefail
# Deploy Mainnet flash quote-push stack (Aave receiver + external unwinder).
# Default: simulation only (no --broadcast). Use --apply to broadcast.
2026-04-12 18:20:41 -07:00
# For receiver-only migrations, use deploy-mainnet-aave-quote-push-receiver.sh.
2026-04-12 06:12:20 -07:00
#
# Env:
# PRIVATE_KEY, ETHEREUM_MAINNET_RPC
# DODO_PMM_INTEGRATION_MAINNET required when QUOTE_PUSH_UNWINDER_TYPE=dodo
# UNISWAP_V3_SWAP_ROUTER_MAINNET optional for univ3; defaults to legacy SwapRouter `0xE592...`
2026-04-13 21:38:57 -07:00
# QUOTE_PUSH_UNWINDER_TYPE univ3 (default) | dodo | two_hop_dodo | dodo_univ3 | two_hop_dodo_univ3
2026-04-12 06:12:20 -07:00
#
# Usage:
# source scripts/lib/load-project-env.sh
# bash scripts/deployment/deploy-mainnet-aave-quote-push-stack.sh --dry-run
# bash scripts/deployment/deploy-mainnet-aave-quote-push-stack.sh --apply
SCRIPT_DIR = " $( cd " $( dirname " ${ BASH_SOURCE [0] } " ) " && pwd ) "
PROXMOX_ROOT = " $( cd " ${ SCRIPT_DIR } /../.. " && pwd ) "
SMOM = " ${ PROXMOX_ROOT } /smom-dbis-138 "
# Preserve explicit caller overrides across sourced repo env files.
_qp_private_key = " ${ PRIVATE_KEY - } "
_qp_rpc = " ${ ETHEREUM_MAINNET_RPC - } "
_qp_unwind_type = " ${ QUOTE_PUSH_UNWINDER_TYPE - } "
_qp_integration = " ${ DODO_PMM_INTEGRATION_MAINNET - } "
_qp_router = " ${ UNISWAP_V3_SWAP_ROUTER_MAINNET - } "
_qp_skip_receiver = " ${ DEPLOY_MAINNET_FLASH_SKIP_RECEIVER - } "
# 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_unwind_type " ] ] && export QUOTE_PUSH_UNWINDER_TYPE = " $_qp_unwind_type "
[ [ -n " $_qp_integration " ] ] && export DODO_PMM_INTEGRATION_MAINNET = " $_qp_integration "
[ [ -n " $_qp_router " ] ] && export UNISWAP_V3_SWAP_ROUTER_MAINNET = " $_qp_router "
[ [ -n " $_qp_skip_receiver " ] ] && export DEPLOY_MAINNET_FLASH_SKIP_RECEIVER = " $_qp_skip_receiver "
unset _qp_private_key _qp_rpc _qp_unwind_type _qp_integration _qp_router _qp_skip_receiver
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 " ] ] || ! 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
}
BROADCAST = ( )
MODE = "dry-run"
if ( ( $# = = 0) ) ; then
:
else
for a in " $@ " ; do
case " $a " in
--apply) BROADCAST = ( --broadcast) ; MODE = apply ; ;
--dry-run) BROADCAST = ( ) ; MODE = dry-run ; ;
*)
echo " [fail] unknown arg: $a (use --dry-run or --apply) " >& 2
exit 2
; ;
esac
done
fi
if [ [ -z " ${ ETHEREUM_MAINNET_RPC :- } " || -z " ${ PRIVATE_KEY :- } " ] ] ; then
echo "[fail] ETHEREUM_MAINNET_RPC and PRIVATE_KEY are required" >& 2
exit 1
fi
UNW = " ${ QUOTE_PUSH_UNWINDER_TYPE :- univ3 } "
echo " mode= $MODE unwinder_type= $UNW "
if [ [ " ${ DEPLOY_MAINNET_FLASH_SKIP_RECEIVER :- } " = = "1" ] ] ; then
echo "Step 1/2: skipped (DEPLOY_MAINNET_FLASH_SKIP_RECEIVER=1; reuse AAVE_QUOTE_PUSH_RECEIVER_MAINNET)"
else
echo "Step 1/2: DeployAaveQuotePushFlashReceiver"
(
cd " $SMOM "
forge script script/deploy/DeployAaveQuotePushFlashReceiver.s.sol:DeployAaveQuotePushFlashReceiver \
--rpc-url " $ETHEREUM_MAINNET_RPC " \
" ${ BROADCAST [@] } " \
-vvvv
)
fi
if [ [ " $UNW " = = "dodo" ] ] ; then
if [ [ -z " ${ DODO_PMM_INTEGRATION_MAINNET :- } " ] ] ; then
echo "[fail] DODO_PMM_INTEGRATION_MAINNET required for dodo unwinder" >& 2
exit 1
fi
echo "Step 2/2: DeployDODOIntegrationExternalUnwinder"
(
cd " $SMOM "
forge script script/deploy/DeployDODOIntegrationExternalUnwinder.s.sol:DeployDODOIntegrationExternalUnwinder \
--rpc-url " $ETHEREUM_MAINNET_RPC " \
" ${ BROADCAST [@] } " \
-vvvv
)
elif [ [ " $UNW " = = "two_hop_dodo" ] ] ; then
if [ [ -z " ${ DODO_PMM_INTEGRATION_MAINNET :- } " ] ] ; then
echo "[fail] DODO_PMM_INTEGRATION_MAINNET required for two_hop_dodo unwinder" >& 2
exit 1
fi
echo "Step 2/2: DeployTwoHopDodoIntegrationUnwinder"
(
cd " $SMOM "
forge script script/deploy/DeployTwoHopDodoIntegrationUnwinder.s.sol:DeployTwoHopDodoIntegrationUnwinder \
--rpc-url " $ETHEREUM_MAINNET_RPC " \
" ${ BROADCAST [@] } " \
-vvvv
)
elif [ [ " $UNW " = = "dodo_univ3" ] ] ; then
if [ [ -z " ${ DODO_PMM_INTEGRATION_MAINNET :- } " ] ] ; then
echo "[fail] DODO_PMM_INTEGRATION_MAINNET required for dodo_univ3 unwinder" >& 2
exit 1
fi
echo "Step 2/2: DeployDODOToUniswapV3MultiHopExternalUnwinder"
(
cd " $SMOM "
forge script script/deploy/DeployDODOToUniswapV3MultiHopExternalUnwinder.s.sol:DeployDODOToUniswapV3MultiHopExternalUnwinder \
--rpc-url " $ETHEREUM_MAINNET_RPC " \
" ${ BROADCAST [@] } " \
-vvvv
)
2026-04-13 21:38:57 -07:00
elif [ [ " $UNW " = = "two_hop_dodo_univ3" ] ] ; then
if [ [ -z " ${ DODO_PMM_INTEGRATION_MAINNET :- } " ] ] ; then
echo "[fail] DODO_PMM_INTEGRATION_MAINNET required for two_hop_dodo_univ3 unwinder" >& 2
exit 1
fi
echo "Step 2/2: DeployTwoHopDodoToUniswapV3MultiHopExternalUnwinder"
(
cd " $SMOM "
forge script script/deploy/DeployTwoHopDodoToUniswapV3MultiHopExternalUnwinder.s.sol:DeployTwoHopDodoToUniswapV3MultiHopExternalUnwinder \
--rpc-url " $ETHEREUM_MAINNET_RPC " \
" ${ BROADCAST [@] } " \
-vvvv
)
2026-04-12 06:12:20 -07:00
else
echo "Step 2/2: DeployUniswapV3ExternalUnwinder"
(
cd " $SMOM "
forge script script/deploy/DeployUniswapV3ExternalUnwinder.s.sol:DeployUniswapV3ExternalUnwinder \
--rpc-url " $ETHEREUM_MAINNET_RPC " \
" ${ BROADCAST [@] } " \
-vvvv
)
fi
echo
receiver_addr = " $( pick_latest_create_address "DeployAaveQuotePushFlashReceiver.s.sol" "AaveQuotePushFlashReceiver" || true ) "
unwinder_contract = "UniswapV3ExternalUnwinder"
unwinder_script = "DeployUniswapV3ExternalUnwinder.s.sol"
case " $UNW " in
dodo)
unwinder_contract = "DODOIntegrationExternalUnwinder"
unwinder_script = "DeployDODOIntegrationExternalUnwinder.s.sol"
; ;
two_hop_dodo)
unwinder_contract = "TwoHopDodoIntegrationUnwinder"
unwinder_script = "DeployTwoHopDodoIntegrationUnwinder.s.sol"
; ;
dodo_univ3)
unwinder_contract = "DODOToUniswapV3MultiHopExternalUnwinder"
unwinder_script = "DeployDODOToUniswapV3MultiHopExternalUnwinder.s.sol"
; ;
2026-04-13 21:38:57 -07:00
two_hop_dodo_univ3)
unwinder_contract = "TwoHopDodoToUniswapV3MultiHopExternalUnwinder"
unwinder_script = "DeployTwoHopDodoToUniswapV3MultiHopExternalUnwinder.s.sol"
; ;
2026-04-12 06:12:20 -07:00
esac
unwinder_addr = " $( pick_latest_create_address " $unwinder_script " " $unwinder_contract " || true ) "
echo "After --apply: copy deployed addresses into .env:"
echo " AAVE_QUOTE_PUSH_RECEIVER_MAINNET= ${ receiver_addr :- ... } "
echo " QUOTE_PUSH_EXTERNAL_UNWINDER_MAINNET= ${ unwinder_addr :- ... } "
2026-04-12 18:20:41 -07:00
echo "Optional retained-surplus manager:"
echo " QUOTE_PUSH_TREASURY_TAKE_RECEIVER_OWNERSHIP=1 bash scripts/deployment/deploy-mainnet-quote-push-treasury-manager.sh --apply"
2026-04-12 06:12:20 -07:00
echo " Or rerun immediately with QUOTE_PUSH_UNWINDER_TYPE= ${ UNW } so run-mainnet-aave-cwusdc-quote-push-once.sh can auto-pick the latest broadcast unwinder. "
echo "Then set FLASH_QUOTE_AMOUNT_RAW, UNWIND_MODE, UNWIND_V3_FEE_U24 (or UNWIND_DODO_POOL / two-hop vars) and run:"
echo " bash scripts/deployment/run-mainnet-aave-cwusdc-quote-push-once.sh --dry-run"