148 lines
4.7 KiB
Bash
148 lines
4.7 KiB
Bash
|
|
#!/bin/bash
|
|||
|
|
set -uo pipefail
|
|||
|
|
|
|||
|
|
# Adversarial fuzzing: try to break the safe config (CI=0 AS=10% AW=20)
|
|||
|
|
# All batches use the safe config, varying only attack patterns
|
|||
|
|
|
|||
|
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|||
|
|
cd "$SCRIPT_DIR/.."
|
|||
|
|
source analysis/run-deep-search.sh 2>/dev/null || true
|
|||
|
|
|
|||
|
|
# Source the run_batch function from run-deep-search.sh
|
|||
|
|
# Actually, just inline the batch runner
|
|||
|
|
|
|||
|
|
LOG="analysis/FUZZING_LOG.md"
|
|||
|
|
|
|||
|
|
echo "" >> "$LOG"
|
|||
|
|
echo "## Adversarial Attack Campaign — $(date -u '+%Y-%m-%d %H:%M UTC')" >> "$LOG"
|
|||
|
|
echo "Target: CI=0 AS=10% AW=20 DD=50% (safe config)" >> "$LOG"
|
|||
|
|
echo "" >> "$LOG"
|
|||
|
|
|
|||
|
|
# Safe config params
|
|||
|
|
CI=0
|
|||
|
|
AS=100000000000000000
|
|||
|
|
AW=20
|
|||
|
|
DD=500000000000000000
|
|||
|
|
|
|||
|
|
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
|
|||
|
|
echo "Disk: ${disk_pct}%"
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
run_single() {
|
|||
|
|
local buybias=$1 trades=$2
|
|||
|
|
local seed=$RANDOM$RANDOM$RANDOM
|
|||
|
|
|
|||
|
|
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 | tail -5
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
run_attack_batch() {
|
|||
|
|
local batch_num=$1 buybias=$2 trades=$3 runs=$4 note=$5
|
|||
|
|
|
|||
|
|
echo "=== ATTACK $batch_num: $note ($runs runs × $trades trades) ==="
|
|||
|
|
echo "### Attack $batch_num: $note" >> "$LOG"
|
|||
|
|
echo "Params: buybias=$buybias trades=$trades runs=$runs" >> "$LOG"
|
|||
|
|
|
|||
|
|
local profitable=0
|
|||
|
|
local total=0
|
|||
|
|
|
|||
|
|
for i in $(seq 1 $runs); do
|
|||
|
|
printf " Run $i/$runs... \n"
|
|||
|
|
|
|||
|
|
local output=$(run_single $buybias $trades)
|
|||
|
|
|
|||
|
|
# Find generated CSV
|
|||
|
|
local csv_prefix=$(echo "$output" | grep "prefix:" | sed 's/.*prefix: //')
|
|||
|
|
local csv_file="analysis/fuzz-${csv_prefix}-000.csv"
|
|||
|
|
|
|||
|
|
if [ -f "$csv_file" ]; then
|
|||
|
|
# Check if profitable (use python3 to avoid bash integer overflow on >9.2e18)
|
|||
|
|
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=$(python3 -c "
|
|||
|
|
init=$init_eth; final=$final_eth
|
|||
|
|
pnl = (final - init) / 1e18
|
|||
|
|
print(f'{'PROFIT' if pnl > 0 else 'SAFE'} {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))
|
|||
|
|
cp "$csv_file" "analysis/fuzz-a${batch_num}-$(printf '%03d' $i).csv"
|
|||
|
|
echo "PROFITABLE (+${pnl_eth} ETH)"
|
|||
|
|
else
|
|||
|
|
echo "safe (${pnl_eth} ETH)"
|
|||
|
|
rm -f "$csv_file"
|
|||
|
|
fi
|
|||
|
|
fi
|
|||
|
|
fi
|
|||
|
|
|
|||
|
|
total=$((total + 1))
|
|||
|
|
|
|||
|
|
# Check disk every 10 runs
|
|||
|
|
if [ $((i % 10)) -eq 0 ]; then
|
|||
|
|
check_resources
|
|||
|
|
fi
|
|||
|
|
done
|
|||
|
|
|
|||
|
|
if [ "$profitable" -gt 0 ]; then
|
|||
|
|
echo "*** ATTACK $batch_num: $profitable/$total PROFITABLE ***"
|
|||
|
|
echo "Result: **$profitable/$total PROFITABLE** ❌" >> "$LOG"
|
|||
|
|
else
|
|||
|
|
echo "Attack $batch_num: 0/$total profitable"
|
|||
|
|
echo "Result: 0/$total profitable ✅" >> "$LOG"
|
|||
|
|
fi
|
|||
|
|
echo "" >> "$LOG"
|
|||
|
|
check_resources
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
echo ""
|
|||
|
|
echo "=== ADVERSARIAL FUZZING: SAFE CONFIG ==="
|
|||
|
|
echo "Target: CI=0 AS=10% AW=20 DD=50%"
|
|||
|
|
echo ""
|
|||
|
|
|
|||
|
|
# Attack 1: Extreme sell-heavy (90% sells)
|
|||
|
|
run_attack_batch 1 10 2000 30 "extreme sell-heavy buybias=10"
|
|||
|
|
|
|||
|
|
# Attack 2: Moderate sell-heavy with longer sequences
|
|||
|
|
run_attack_batch 2 30 3000 20 "sell-bias=30 trades=3000 with staking"
|
|||
|
|
|
|||
|
|
# Attack 3: Very long sequences (5000 trades)
|
|||
|
|
run_attack_batch 3 50 5000 15 "balanced 5000 trades"
|
|||
|
|
|
|||
|
|
# Attack 4: Sell bias=20 (80% sells)
|
|||
|
|
run_attack_batch 4 20 2000 30 "sell-bias=20"
|
|||
|
|
|
|||
|
|
# Attack 5: Buy-then-dump pattern (70% buy = accumulate, then sells happen)
|
|||
|
|
run_attack_batch 5 70 4000 15 "buy-heavy 4000 trades (accumulate then dump)"
|
|||
|
|
|
|||
|
|
# Attack 6: Extreme sell with maximum trades
|
|||
|
|
run_attack_batch 6 15 4000 10 "sell-bias=15 trades=4000"
|
|||
|
|
|
|||
|
|
# Attack 7: Near-balanced with slight sell pressure
|
|||
|
|
run_attack_batch 7 45 3000 20 "near-balanced buybias=45 trades=3000"
|
|||
|
|
|
|||
|
|
echo ""
|
|||
|
|
echo "=== ALL ATTACKS COMPLETE ==="
|
|||
|
|
echo "Check analysis/fuzz-a*.csv for any profitable runs"
|
|||
|
|
echo "" >> "$LOG"
|
|||
|
|
echo "### Campaign Complete: $(date -u '+%Y-%m-%d %H:%M UTC')" >> "$LOG"
|