132 lines
4.5 KiB
Bash
132 lines
4.5 KiB
Bash
|
|
#!/bin/bash
|
|||
|
|
set -uo pipefail
|
|||
|
|
|
|||
|
|
# Map the full (AS, AW) safe frontier
|
|||
|
|
# Find which combos are safe AND measure fee revenue
|
|||
|
|
# CI=0 always, DD=0.5e18, buybias=10, 3 runs per combo
|
|||
|
|
|
|||
|
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|||
|
|
cd "$SCRIPT_DIR/.."
|
|||
|
|
|
|||
|
|
LOG="analysis/2D_FRONTIER_LOG.md"
|
|||
|
|
CSV="analysis/2d-frontier-results.csv"
|
|||
|
|
|
|||
|
|
echo "# 2D Safe Frontier: AS × AW — $(date -u '+%Y-%m-%d %H:%M UTC')" > "$LOG"
|
|||
|
|
echo "as_pct,aw,profitable,total,avg_pnl,avg_weth_fees,avg_krk_fees" > "$CSV"
|
|||
|
|
|
|||
|
|
run_combo() {
|
|||
|
|
local as_pct=$1 aw=$2 runs=${3:-3} buybias=${4:-10}
|
|||
|
|
local AS_VALUE=$(python3 -c "print(int($as_pct * 1e18 / 100))")
|
|||
|
|
|
|||
|
|
printf "AS=%3d%% AW=%3d: " $as_pct $aw
|
|||
|
|
|
|||
|
|
local profitable=0
|
|||
|
|
local pnl_sum=0 fw_sum=0 fk_sum=0 count=0
|
|||
|
|
|
|||
|
|
for i in $(seq 1 $runs); do
|
|||
|
|
local seed=$RANDOM$RANDOM$RANDOM
|
|||
|
|
local output
|
|||
|
|
output=$(CI_VALUE=0 AS_VALUE=$AS_VALUE AW_VALUE=$aw DD_VALUE=500000000000000000 \
|
|||
|
|
BATCH_SEED=$seed OPTIMIZER_CLASS=ConfigurableOptimizer \
|
|||
|
|
UNCAPPED_SWAPS=true FUZZING_RUNS=1 BUY_BIAS=$buybias \
|
|||
|
|
TRADES_PER_RUN=2000 BG_LP_ETH_PER_LAYER=0 \
|
|||
|
|
forge script analysis/StreamlinedFuzzing.s.sol:StreamlinedFuzzing \
|
|||
|
|
--skip-simulation --gas-estimate-multiplier 300 -vv 2>&1)
|
|||
|
|
|
|||
|
|
local csv_prefix=$(echo "$output" | grep "prefix:" | sed 's/.*prefix: //')
|
|||
|
|
local csv_file="analysis/fuzz-${csv_prefix}-000.csv"
|
|||
|
|
|
|||
|
|
if [ -f "$csv_file" ]; then
|
|||
|
|
local result=$(python3 -c "
|
|||
|
|
import csv
|
|||
|
|
rows = list(csv.reader(open('$csv_file')))
|
|||
|
|
header = rows[0]
|
|||
|
|
cols = {h: i for i, h in enumerate(header)}
|
|||
|
|
first, last = rows[1], rows[-1]
|
|||
|
|
init = float(first[cols.get('trader_weth', 12)])
|
|||
|
|
final = float(last[cols.get('trader_weth', 12)])
|
|||
|
|
pnl = (final - init) / 1e18
|
|||
|
|
fw = float(last[cols.get('fee_dest_weth', -2)]) / 1e18 if 'fee_dest_weth' in cols else 0
|
|||
|
|
fk = float(last[cols.get('fee_dest_krk', -1)]) / 1e18 if 'fee_dest_krk' in cols else 0
|
|||
|
|
print(f'{1 if pnl > 0 else 0} {pnl:.1f} {fw:.1f} {fk:.0f}')
|
|||
|
|
" 2>/dev/null || echo "0 0 0 0")
|
|||
|
|
|
|||
|
|
local is_profit=$(echo $result | cut -d' ' -f1)
|
|||
|
|
local pnl=$(echo $result | cut -d' ' -f2)
|
|||
|
|
local fw=$(echo $result | cut -d' ' -f3)
|
|||
|
|
local fk=$(echo $result | cut -d' ' -f4)
|
|||
|
|
|
|||
|
|
profitable=$((profitable + is_profit))
|
|||
|
|
pnl_sum=$(python3 -c "print($pnl_sum + $pnl)")
|
|||
|
|
fw_sum=$(python3 -c "print($fw_sum + $fw)")
|
|||
|
|
fk_sum=$(python3 -c "print($fk_sum + $fk)")
|
|||
|
|
count=$((count + 1))
|
|||
|
|
rm -f "$csv_file"
|
|||
|
|
fi
|
|||
|
|
done
|
|||
|
|
|
|||
|
|
if [ "$count" -gt 0 ]; then
|
|||
|
|
local avgs=$(python3 -c "print(f'{$pnl_sum/$count:.1f} {$fw_sum/$count:.1f} {$fk_sum/$count:.0f}')")
|
|||
|
|
local avg_pnl=$(echo $avgs | cut -d' ' -f1)
|
|||
|
|
local avg_fw=$(echo $avgs | cut -d' ' -f2)
|
|||
|
|
local avg_fk=$(echo $avgs | cut -d' ' -f3)
|
|||
|
|
|
|||
|
|
local emoji="✅"; [ "$profitable" -gt 0 ] && emoji="❌"
|
|||
|
|
echo "$emoji $profitable/$count | PnL=${avg_pnl} | fees: ${avg_fw} WETH + ${avg_fk} KRK"
|
|||
|
|
echo "$as_pct,$aw,$profitable,$count,$avg_pnl,$avg_fw,$avg_fk" >> "$CSV"
|
|||
|
|
echo "| ${as_pct}% | ${aw} | ${profitable}/${count} ${emoji} | ${avg_pnl} | ${avg_fw} | ${avg_fk} |" >> "$LOG"
|
|||
|
|
fi
|
|||
|
|
|
|||
|
|
# Disk check
|
|||
|
|
local disk_pct=$(df / --output=pcent | tail -1 | tr -d ' %')
|
|||
|
|
[ "$disk_pct" -gt 85 ] && { echo "DISK FULL"; exit 1; }
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
echo "" >> "$LOG"
|
|||
|
|
echo "| AS | AW | Safe? | Avg PnL | WETH Fees | KRK Fees |" >> "$LOG"
|
|||
|
|
echo "|----|----|-------|---------|-----------|----------|" >> "$LOG"
|
|||
|
|
|
|||
|
|
# Known safe corners: (AS≤30, AW=100) and (AS=100, AW=20)
|
|||
|
|
# Strategy: sweep the frontier between them to find the safe boundary
|
|||
|
|
|
|||
|
|
echo "=== Phase 1: Refine AW=100 boundary ==="
|
|||
|
|
run_combo 35 100 3
|
|||
|
|
|
|||
|
|
echo "=== Phase 2: AW=90 sweep ==="
|
|||
|
|
for as in 20 30 40 50; do
|
|||
|
|
run_combo $as 90 3
|
|||
|
|
done
|
|||
|
|
|
|||
|
|
echo "=== Phase 3: AW=80 sweep ==="
|
|||
|
|
for as in 20 30 40 50; do
|
|||
|
|
run_combo $as 80 3
|
|||
|
|
done
|
|||
|
|
|
|||
|
|
echo "=== Phase 4: AW=60 sweep ==="
|
|||
|
|
for as in 20 30 40 50; do
|
|||
|
|
run_combo $as 60 3
|
|||
|
|
done
|
|||
|
|
|
|||
|
|
echo "=== Phase 5: AW=40 sweep ==="
|
|||
|
|
for as in 30 40 50 60 70 80; do
|
|||
|
|
run_combo $as 40 3
|
|||
|
|
done
|
|||
|
|
|
|||
|
|
echo "=== Phase 6: AW=30 sweep ==="
|
|||
|
|
for as in 50 60 70 80 90; do
|
|||
|
|
run_combo $as 30 3
|
|||
|
|
done
|
|||
|
|
|
|||
|
|
echo "=== Phase 7: AW=20 fill ==="
|
|||
|
|
for as in 50 60 70 80 90; do
|
|||
|
|
run_combo $as 20 3
|
|||
|
|
done
|
|||
|
|
|
|||
|
|
echo "" >> "$LOG"
|
|||
|
|
echo "### Complete: $(date -u '+%Y-%m-%d %H:%M UTC')" >> "$LOG"
|
|||
|
|
|
|||
|
|
echo ""
|
|||
|
|
echo "=== FRONTIER MAPPED ==="
|
|||
|
|
echo "Results: analysis/2D_FRONTIER_LOG.md"
|
|||
|
|
echo "CSV: analysis/2d-frontier-results.csv"
|