harb/onchain/analysis/run-fuzzing.sh
2025-08-23 22:32:41 +02:00

193 lines
No EOL
6.1 KiB
Bash
Executable file

#!/bin/bash
# Usage: ./run-fuzzing.sh [optimizer] [runs=N] [staking=on|off] [buybias=N] [trades=N] [stakingbias=N] [debugCSV]
# Examples:
# ./run-fuzzing.sh BullMarketOptimizer runs=50
# ./run-fuzzing.sh WhaleOptimizer runs=20 staking=off
# ./run-fuzzing.sh BullMarketOptimizer runs=200 staking=on buybias=100 trades=30 stakingbias=95
# ./run-fuzzing.sh BullMarketOptimizer debugCSV # Opens HTML visualizer after generating CSVs
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
BOLD='\033[1m'
# Configuration
OPTIMIZER=${1:-BullMarketOptimizer}
# Check if second parameter is debugCSV
DEBUG_CSV=false
if [[ "$2" == "debugCSV" ]]; then
DEBUG_CSV=true
RUNS="runs=3"
STAKING="staking=on"
BUYBIAS="buybias=50"
TRADES="trades=5"
STAKINGBIAS="stakingbias=80"
else
RUNS=${2:-runs=20}
STAKING=${3:-staking=on}
BUYBIAS=${4:-buybias=50}
TRADES=${5:-trades=15}
STAKINGBIAS=${6:-stakingbias=80}
fi
# Parse runs parameter
if [[ $RUNS == runs=* ]]; then
RUNS_VALUE=${RUNS#runs=}
else
RUNS_VALUE=$RUNS
fi
# Parse staking parameter
STAKING_ENABLED="true"
if [[ $STAKING == staking=* ]]; then
STAKING_VALUE=${STAKING#staking=}
if [[ $STAKING_VALUE == "off" ]] || [[ $STAKING_VALUE == "false" ]] || [[ $STAKING_VALUE == "0" ]]; then
STAKING_ENABLED="false"
fi
fi
# Parse buy bias parameter
BUYBIAS_VALUE="50"
if [[ $BUYBIAS == buybias=* ]]; then
BUYBIAS_VALUE=${BUYBIAS#buybias=}
fi
# Parse trades parameter
TRADES_VALUE="15"
if [[ $TRADES == trades=* ]]; then
TRADES_VALUE=${TRADES#trades=}
fi
# Parse staking bias parameter
STAKINGBIAS_VALUE="80"
if [[ $STAKINGBIAS == stakingbias=* ]]; then
STAKINGBIAS_VALUE=${STAKINGBIAS#stakingbias=}
fi
# Ensure we're in the onchain directory (script should be run from there)
echo -e "${GREEN}=== Fuzzing Analysis ===${NC}"
echo "Optimizer: $OPTIMIZER"
echo "Total runs: $RUNS_VALUE"
echo "Trades per run: $TRADES_VALUE"
echo "Staking: $([ "$STAKING_ENABLED" = "true" ] && echo "enabled" || echo "disabled")"
if [ "$STAKING_ENABLED" = "true" ]; then
echo "Staking bias: $STAKINGBIAS_VALUE%"
fi
echo "Buy bias: $BUYBIAS_VALUE%"
echo ""
# Validate optimizer
case $OPTIMIZER in
BullMarketOptimizer|BearMarketOptimizer|NeutralMarketOptimizer|WhaleOptimizer|ExtremeOptimizer|MaliciousOptimizer)
echo "Optimizer validation passed"
;;
*)
echo -e "${RED}Error: Invalid optimizer class${NC}"
echo "Valid options: BullMarketOptimizer, BearMarketOptimizer, NeutralMarketOptimizer, WhaleOptimizer, ExtremeOptimizer, MaliciousOptimizer"
exit 1
;;
esac
# Run the streamlined fuzzing analysis
echo -e "${YELLOW}Starting fuzzing analysis...${NC}"
echo ""
# Record existing CSV files in analysis folder before running
EXISTING_CSVS=$(ls -1 analysis/fuzz-????-???.csv 2>/dev/null | sort)
FUZZING_RUNS=$RUNS_VALUE \
OPTIMIZER_CLASS=$OPTIMIZER \
ENABLE_STAKING=$STAKING_ENABLED \
BUY_BIAS=$BUYBIAS_VALUE \
TRADES_PER_RUN=$TRADES_VALUE \
STAKING_BIAS=$STAKINGBIAS_VALUE \
forge script analysis/StreamlinedFuzzing.s.sol:StreamlinedFuzzing --skip-simulation --gas-estimate-multiplier 300 -vv 2>&1
# Analysis complete
echo ""
echo -e "${GREEN}=== ANALYSIS COMPLETE ===${NC}"
# Find newly generated CSV files in analysis folder
NEW_CSVS=$(ls -1 analysis/fuzz-????-???.csv 2>/dev/null | sort)
# Get the scenario code from the first new file
if [ "$EXISTING_CSVS" != "$NEW_CSVS" ]; then
SCENARIO_CODE=$(echo "$NEW_CSVS" | grep -v -F "$EXISTING_CSVS" | head -1 | sed 's/fuzz-\(....\).*/\1/')
else
SCENARIO_CODE="UNKN"
fi
# Count generated CSV files for this run
CSV_COUNT=$(ls -1 analysis/fuzz-${SCENARIO_CODE}-*.csv 2>/dev/null | wc -l)
echo "Generated $CSV_COUNT CSV files with scenario ID: ${SCENARIO_CODE}"
# Check for profitable scenarios
echo ""
echo -e "${YELLOW}=== Checking for Profitable Scenarios ===${NC}"
PROFITABLE_COUNT=0
for csv in analysis/fuzz-${SCENARIO_CODE}-*.csv; do
if [ -f "$csv" ]; then
# Get INIT and FINAL rows
INIT_ETH=$(grep "^INIT," "$csv" | cut -d',' -f13)
FINAL_ETH=$(grep "^FINAL," "$csv" | cut -d',' -f13)
if [ ! -z "$INIT_ETH" ] && [ ! -z "$FINAL_ETH" ]; then
if [ "$FINAL_ETH" -gt "$INIT_ETH" ]; then
PROFIT_PCT=$(echo "scale=1; ($FINAL_ETH - $INIT_ETH) * 100 / $INIT_ETH" | bc -l 2>/dev/null || echo "0")
echo -e "${GREEN} $csv: PROFITABLE (+${PROFIT_PCT}%)${NC}"
((PROFITABLE_COUNT++))
fi
fi
fi
done
if [ $PROFITABLE_COUNT -eq 0 ]; then
echo " No profitable scenarios found"
else
echo -e "${GREEN}Found $PROFITABLE_COUNT profitable scenarios${NC}"
fi
echo ""
echo -e "${GREEN}CSV files generated with scenario ID: ${SCENARIO_CODE}${NC}"
# Launch HTML visualizer if debugCSV mode
if [ "$DEBUG_CSV" = true ]; then
echo ""
echo -e "${YELLOW}Launching HTML visualizer...${NC}"
# Check if Python3 is available
if command -v python3 &> /dev/null; then
echo "Starting local server from analysis folder at http://localhost:8000"
echo "Open http://localhost:8000/run-visualizer.html to view results"
# Start server from analysis directory so CSV files are directly accessible
cd analysis
python3 -m http.server 8000 --bind 127.0.0.1 &
SERVER_PID=$!
# Try to open browser (cross-platform)
sleep 1
if command -v open &> /dev/null; then
# macOS
open "http://localhost:8000/run-visualizer.html"
elif command -v xdg-open &> /dev/null; then
# Linux
xdg-open "http://localhost:8000/run-visualizer.html"
elif command -v wslview &> /dev/null; then
# WSL
wslview "http://localhost:8000/run-visualizer.html"
fi
echo ""
echo "Press Ctrl+C to stop the server"
wait $SERVER_PID
else
echo "Python3 not found. To view results:"
echo " cd analysis && python3 -m http.server 8000"
echo " Then open http://localhost:8000/run-visualizer.html in your browser"
fi
fi