- Analysis: parameter sweep scripts, adversarial testing, 2D frontier maps - Research: KRAIKEN_RESEARCH_REPORT, SECURITY_REVIEW, STORAGE_LAYOUT - FuzzingBase: consolidated fuzzing helper, BackgroundLP simulation - Sweep results: CSV data for full 4D sweep (1050 combos), bull-bear, AS sweep, VWAP fix validation - Code quality: .gitignore for fuzz CSVs, gas snapshot, updated docs - Remove dead analysis helpers (CSVHelper, CSVManager, ScenarioRecorder) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
275 lines
8.9 KiB
Bash
Executable file
275 lines
8.9 KiB
Bash
Executable file
#!/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"
|