#!/bin/bash set -uo pipefail # Adversarial fuzzing for OptimizerV3 configurations # V3 uses direct 2D mapping with binary step: # staked <= 91% → BEAR (AS=30%, AW=100, DD=0.3e18) # staked > 91% + low tax → BULL (AS=100%, AW=20, DD=1e18) # # This script tests both configs and staking scenarios. # # Usage: # ./analysis/run-v3-adversarial.sh # Full campaign # ./analysis/run-v3-adversarial.sh bear # Bear only # ./analysis/run-v3-adversarial.sh bull # Bull only # ./analysis/run-v3-adversarial.sh staking # Staking scenarios only SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" cd "$SCRIPT_DIR/.." FORGE="${HOME}/.foundry/bin/forge" LOG="analysis/V3_FUZZING_LOG.md" echo "# OptimizerV3 Adversarial Fuzzing — $(date -u '+%Y-%m-%d %H:%M UTC')" > "$LOG" echo "" >> "$LOG" check_resources() { local disk_pct=$(df / --output=pcent | tail -1 | tr -d ' %') if [ "$disk_pct" -gt 85 ]; then echo "DISK FULL ($disk_pct%) — stopping" exit 1 fi } # Run with ConfigurableOptimizer (direct param control) run_config() { local config_name=$1 local config=$2 # "bear" or "bull" local buybias=$3 local runs=$4 local trades=${5:-2000} local CI=0 local AS AW DD desc if [ "$config" = "bear" ]; then AS=300000000000000000 # 30% = 3e17 AW=100 DD=300000000000000000 # 0.3e18 desc="AS=30% AW=100" elif [ "$config" = "bull" ]; then AS=1000000000000000000 # 100% = 1e18 AW=20 DD=1000000000000000000 # 1e18 desc="AS=100% AW=20" else echo "Unknown config: $config" return 1 fi echo "=== $config_name ($desc) buybias=$buybias ===" echo "### $config_name ($desc, buybias=$buybias)" >> "$LOG" echo "Params: CI=$CI AS=$AS AW=$AW DD=$DD trades=$trades runs=$runs" >> "$LOG" local profitable=0 local total=0 for i in $(seq 1 $runs); do printf " Run $i/$runs... " local seed=$RANDOM$RANDOM$RANDOM local output output=$(CI_VALUE=$CI \ AS_VALUE=$AS \ AW_VALUE=$AW \ DD_VALUE=$DD \ BATCH_SEED=$seed \ OPTIMIZER_CLASS=ConfigurableOptimizer \ UNCAPPED_SWAPS=true \ FUZZING_RUNS=1 \ BUY_BIAS=$buybias \ TRADES_PER_RUN=$trades \ "$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 init_eth=$(head -2 "$csv_file" | tail -1 | cut -d',' -f13) local final_eth=$(tail -1 "$csv_file" | cut -d',' -f13) if [ -n "$init_eth" ] && [ -n "$final_eth" ]; then local pnl_result pnl_result=$(python3 -c " init=$init_eth; final=$final_eth pnl = (final - init) / 1e18 status = 'PROFIT' if pnl > 0 else 'SAFE' print(f'{status} {pnl:.1f}') " 2>/dev/null || echo "SAFE 0.0") local pnl_status=$(echo "$pnl_result" | cut -d' ' -f1) local pnl_eth=$(echo "$pnl_result" | cut -d' ' -f2) if [ "$pnl_status" = "PROFIT" ]; then profitable=$((profitable + 1)) echo "❌ PROFIT +${pnl_eth} ETH" cp "$csv_file" "analysis/fuzz-v3-${config_name// /-}-$(printf '%03d' $i).csv" else echo "✅ safe ${pnl_eth} ETH" fi rm -f "$csv_file" else echo "⚠️ parse error" rm -f "$csv_file" fi else echo "⚠️ no CSV" fi total=$((total + 1)) done local result_emoji="✅" [ "$profitable" -gt 0 ] && result_emoji="❌" echo "$result_emoji Result: $profitable/$total profitable" echo "Result: **$profitable/$total** ${result_emoji}" >> "$LOG" echo "" >> "$LOG" check_resources } # Run with staking scenario (uses ConfigurableOptimizer but pre-seeds staking) run_staking_scenario() { local config_name=$1 local staking_level=$2 # 0-100 local tax_rate=$3 # tax rate index 0-29 local config=$4 # "bear" or "bull" (expected config from V3) local buybias=$5 local runs=$6 local trades=${7:-2000} local CI=0 local AS AW DD desc if [ "$config" = "bear" ]; then AS=300000000000000000 AW=100 DD=300000000000000000 desc="BEAR AS=30% AW=100" else AS=1000000000000000000 AW=20 DD=1000000000000000000 desc="BULL AS=100% AW=20" fi echo "=== $config_name (staked=${staking_level}% tax_idx=$tax_rate → $desc) buybias=$buybias ===" echo "### $config_name (staked=${staking_level}%, tax_idx=$tax_rate → $desc, buybias=$buybias)" >> "$LOG" local profitable=0 local total=0 for i in $(seq 1 $runs); do printf " Run $i/$runs... " local seed=$RANDOM$RANDOM$RANDOM local output output=$(CI_VALUE=$CI \ AS_VALUE=$AS \ AW_VALUE=$AW \ DD_VALUE=$DD \ BATCH_SEED=$seed \ OPTIMIZER_CLASS=ConfigurableOptimizer \ UNCAPPED_SWAPS=true \ FUZZING_RUNS=1 \ BUY_BIAS=$buybias \ TRADES_PER_RUN=$trades \ STAKING_LEVEL=$staking_level \ STAKING_TAX_RATE=$tax_rate \ "$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 init_eth=$(head -2 "$csv_file" | tail -1 | cut -d',' -f13) local final_eth=$(tail -1 "$csv_file" | cut -d',' -f13) if [ -n "$init_eth" ] && [ -n "$final_eth" ]; then local pnl_result pnl_result=$(python3 -c " init=$init_eth; final=$final_eth pnl = (final - init) / 1e18 status = 'PROFIT' if pnl > 0 else 'SAFE' print(f'{status} {pnl:.1f}') " 2>/dev/null || echo "SAFE 0.0") local pnl_status=$(echo "$pnl_result" | cut -d' ' -f1) local pnl_eth=$(echo "$pnl_result" | cut -d' ' -f2) if [ "$pnl_status" = "PROFIT" ]; then profitable=$((profitable + 1)) echo "❌ PROFIT +${pnl_eth} ETH" cp "$csv_file" "analysis/fuzz-v3-${config_name// /-}-$(printf '%03d' $i).csv" else echo "✅ safe ${pnl_eth} ETH" fi rm -f "$csv_file" else echo "⚠️ parse error" rm -f "$csv_file" fi else echo "⚠️ no CSV" fi total=$((total + 1)) done local result_emoji="✅" [ "$profitable" -gt 0 ] && result_emoji="❌" echo "$result_emoji Result: $profitable/$total profitable" echo "Result: **$profitable/$total** ${result_emoji}" >> "$LOG" echo "" >> "$LOG" check_resources } MODE="${1:-all}" echo "Starting V3 adversarial campaign (mode=$MODE)..." echo "" if [ "$MODE" = "all" ] || [ "$MODE" = "bear" ]; then echo "## Bear Config (AS=30% AW=100) — V3 default for staked ≤ 91%" >> "$LOG" echo "" >> "$LOG" run_config "bear-sellheavy" bear 10 5 run_config "bear-modsell" bear 30 5 run_config "bear-balanced" bear 50 5 fi if [ "$MODE" = "all" ] || [ "$MODE" = "bull" ]; then echo "## Bull Config (AS=100% AW=20) — V3 for euphoric staking" >> "$LOG" echo "" >> "$LOG" run_config "bull-sellheavy" bull 10 5 run_config "bull-modsell" bull 30 5 run_config "bull-balanced" bull 50 5 fi if [ "$MODE" = "all" ] || [ "$MODE" = "staking" ]; then echo "## Staking Scenarios — V3 boundary validation" >> "$LOG" echo "" >> "$LOG" # 50% staked → always bear regardless of tax run_staking_scenario "50pct-bear" 50 0 bear 10 5 # 95% staked, low tax → should be bull (deltaS=5, effIdx=0, penalty=0) run_staking_scenario "95pct-lowtax-bull" 95 0 bull 10 5 # 95% staked, high tax → should be bear (deltaS=5, effIdx=8+, penalty>=50) run_staking_scenario "95pct-hightax-bear" 95 8 bear 10 5 # 97% staked, low tax → bull (deltaS=3, penalty always < 50) run_staking_scenario "97pct-lowtax-bull" 97 0 bull 10 5 # 97% staked, max tax → still bull (deltaS=3, effIdx=29, penalty=39) run_staking_scenario "97pct-maxtax-bull" 97 29 bull 10 5 fi echo "" >> "$LOG" echo "### Campaign Complete: $(date -u '+%Y-%m-%d %H:%M UTC')" >> "$LOG" echo "" echo "=== ALL CONFIGS TESTED ===" echo "Results: analysis/V3_FUZZING_LOG.md" echo "Profitable CSVs: analysis/fuzz-v3-*.csv"