#!/bin/bash # Parameter sweep for finding safe/unsafe optimizer parameter boundaries # # Usage: ./analysis/run-parameter-sweep.sh [mode] # Modes: # quick - Small focused grid (~5 min) # standard - Medium grid (~30 min) # boundary - Focused on exploitation boundary (~20 min) # # Run from onchain/ directory set -euo pipefail RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' MODE=${1:-standard} # Common: uncapped swaps for realistic exploitation testing UNCAPPED="true" MINBUY="20" MAXBUY="80" case $MODE in quick) CI="0,500000000000000000,1000000000000000000" AS="100000000000000000,500000000000000000,1000000000000000000" AW="30,50,80" DD="200000000000000000,1000000000000000000" BB="80,100" RUNS=3 TRADES=20 ;; standard) CI="0,200000000000000000,500000000000000000,800000000000000000,1000000000000000000" AS="50000000000000000,100000000000000000,200000000000000000,500000000000000000,700000000000000000,1000000000000000000" AW="20,50,80" DD="200000000000000000,500000000000000000,1000000000000000000" BB="80,100" RUNS=5 TRADES=30 ;; boundary) # Focused sweep around known exploitation boundary: # Bull (exploitable): CI=0, AS=1e18, AW=50, DD=1e18 # Bear (mostly safe): CI=0.8e18, AS=0.2e18, AW=80+, DD=0.2e18 # Key: anchorShare transition between 0.2 and 0.7 CI="0,300000000000000000,500000000000000000,800000000000000000" AS="100000000000000000,200000000000000000,300000000000000000,400000000000000000,500000000000000000,700000000000000000,1000000000000000000" AW="30,50,80" DD="200000000000000000,500000000000000000,1000000000000000000" BB="80" RUNS=5 TRADES=30 ;; *) echo "Unknown mode: $MODE (use: quick, standard, boundary)" exit 1 ;; esac echo -e "${GREEN}=== KRAIKEN Parameter Sweep ($MODE mode) ===${NC}" echo "Runs per combo: $RUNS | Trades per run: $TRADES" echo "Uncapped: $UNCAPPED | Trade range: ${MINBUY}-${MAXBUY} ETH" # Master results SUMMARY_FILE="analysis/sweep-FULL-summary.csv" echo "ci,anchor_share,anchor_width,discovery_depth,buy_bias,max_trader_pnl,min_trader_pnl,any_lm_loss,lm_eth_delta" > "$SUMMARY_FILE" # Split into small batches: one forge call per (CI, AS, AW) triple # Each call handles DD*BB combos to stay within gas limits batch=0 total_combos=0 start_time=$(date +%s) for ci_val in $(echo "$CI" | tr ',' ' '); do for as_val in $(echo "$AS" | tr ',' ' '); do for aw_val in $(echo "$AW" | tr ',' ' '); do batch=$((batch + 1)) ci_pct=$(python3 -c "print(f'{int(\"$ci_val\")/1e18:.0%}')" 2>/dev/null || echo "$ci_val") as_pct=$(python3 -c "print(f'{int(\"$as_val\")/1e18:.1%}')" 2>/dev/null || echo "$as_val") echo -ne "\r${BLUE}[$batch] CI=$ci_pct AS=$as_pct AW=$aw_val${NC} " CI_VALUES="$ci_val" \ AS_VALUES="$as_val" \ AW_VALUES="$aw_val" \ DD_VALUES="$DD" \ BB_VALUES="$BB" \ RUNS_PER_COMBO="$RUNS" \ TRADES_PER_RUN="$TRADES" \ UNCAPPED_SWAPS="$UNCAPPED" \ MIN_BUY_ETH="$MINBUY" \ MAX_BUY_ETH="$MAXBUY" \ SWEEP_TAG="B${batch}" \ forge script analysis/ParameterSweepFuzzing.s.sol:ParameterSweepFuzzing \ --skip-simulation --gas-estimate-multiplier 300 -vv 2>&1 | grep "UNSAFE" || true batch_csv="analysis/sweep-B${batch}-summary.csv" if [ -f "$batch_csv" ]; then new_lines=$(tail -n +2 "$batch_csv" | wc -l) total_combos=$((total_combos + new_lines)) tail -n +2 "$batch_csv" >> "$SUMMARY_FILE" rm "$batch_csv" fi done done done elapsed=$(($(date +%s) - start_time)) echo "" echo "" echo -e "${GREEN}=== ANALYSIS ===${NC}" echo "Elapsed: ${elapsed}s" # Analyze results total_tested=$(tail -n +2 "$SUMMARY_FILE" | wc -l | tr -d ' ') unsafe_combos=$(tail -n +2 "$SUMMARY_FILE" | grep -c ',true,' || true) unsafe_combos=${unsafe_combos:-0} safe_combos=$((total_tested - unsafe_combos)) echo "Total tested: $total_tested" echo -e "Safe: ${GREEN}$safe_combos${NC}" echo -e "Unsafe: ${RED}$unsafe_combos${NC}" # Generate report RESULTS_FILE="analysis/PARAMETER_SEARCH_RESULTS.md" cat > "$RESULTS_FILE" << EOF # KRAIKEN Parameter Search Results ## Objective Find optimizer parameters where the LiquidityManager NEVER loses ETH regardless of trade sequence. ## Methodology - **Mode**: $MODE - **Runs per parameter combination**: $RUNS - **Trades per run**: $TRADES - **Uncapped swaps**: $UNCAPPED (trades push through position boundaries) - **Trade size range**: ${MINBUY}-${MAXBUY} ETH (vs 100 ETH LM balance) - **VWAP accumulation**: Environment reused across runs per combo - **Buy biases tested**: $(echo $BB | tr ',' ', ')% - **Total combinations tested**: $total_tested - **Elapsed time**: ${elapsed}s ### Parameters Searched | Parameter | Values | Description | |-----------|--------|-------------| | capitalInefficiency | $(python3 -c "print(', '.join(f'{int(x)/1e18:.0%}' for x in '$CI'.split(',')))" 2>/dev/null || echo "$CI") | Capital buffer (0=aggressive, 1e18=conservative) | | anchorShare | $(python3 -c "print(', '.join(f'{int(x)/1e18:.1%}' for x in '$AS'.split(',')))" 2>/dev/null || echo "$AS") | ETH allocation to anchor vs floor | | anchorWidth | $(echo $AW | tr ',' ', ') | Anchor position width (1-100) | | discoveryDepth | $(python3 -c "print(', '.join(f'{int(x)/1e18:.0%}' for x in '$DD'.split(',')))" 2>/dev/null || echo "$DD") | Discovery liquidity density | | buyBias | $(echo $BB | tr ',' ', ')% | Adversarial trade mix (80=buy-heavy, 100=buy-only) | ### Key Metrics - **Trader PnL < 0**: LM gained ETH (SAFE). Trader lost money. - **Trader PnL > 0**: LM lost ETH (UNSAFE). Trader extracted ETH. ## Results Summary - **Safe combinations**: $safe_combos / $total_tested - **Unsafe combinations**: $unsafe_combos / $total_tested EOF if [ "$unsafe_combos" -gt 0 ]; then { echo "" echo "## UNSAFE Parameters (Trader Profited = LM Lost ETH)" echo "" echo "| CI | AnchorShare | AnchorWidth | DiscoveryDepth | BuyBias | Max Trader PnL (ETH) |" echo "|-----|-------------|-------------|----------------|---------|----------------------|" while IFS=, read -r ci as aw dd bb maxpnl minpnl loss lmdelta; do if [[ "$loss" == "true" ]]; then ci_pct=$(python3 -c "print(f'{int(\"$ci\")/1e18:.0%}')" 2>/dev/null || echo "$ci") as_pct=$(python3 -c "print(f'{int(\"$as\")/1e18:.1%}')" 2>/dev/null || echo "$as") dd_pct=$(python3 -c "print(f'{int(\"$dd\")/1e18:.0%}')" 2>/dev/null || echo "$dd") maxpnl_eth=$(python3 -c "print(f'{int(\"$maxpnl\")/1e18:+.4f}')" 2>/dev/null || echo "$maxpnl") echo "| $ci_pct | $as_pct | $aw | $dd_pct | $bb | $maxpnl_eth |" fi done < <(tail -n +2 "$SUMMARY_FILE") } >> "$RESULTS_FILE" fi { echo "" echo "## SAFE Parameters" echo "" } >> "$RESULTS_FILE" if [ "$safe_combos" -gt 0 ]; then { echo "All tested parameter combinations where the LM never lost ETH:" echo "" echo "### Safe Ranges by Buy Bias" echo "" } >> "$RESULTS_FILE" for bb_val in $(echo "$BB" | tr ',' ' '); do safe_at_bb=$(tail -n +2 "$SUMMARY_FILE" | grep ",$bb_val," | grep -c ',false,' || true) safe_at_bb=${safe_at_bb:-0} total_at_bb=$(tail -n +2 "$SUMMARY_FILE" | grep -c ",$bb_val," || true) total_at_bb=${total_at_bb:-0} echo "- **BuyBias=${bb_val}%**: ${safe_at_bb}/${total_at_bb} safe" >> "$RESULTS_FILE" done { echo "" echo "### Top 20 Safest Combinations (most negative max trader PnL = hardest to exploit)" echo "" echo "| CI | AnchorShare | AnchorWidth | DiscoveryDepth | BuyBias | Max Trader PnL (ETH) |" echo "|-----|-------------|-------------|----------------|---------|----------------------|" } >> "$RESULTS_FILE" tail -n +2 "$SUMMARY_FILE" | grep ',false,' | sort -t, -k6 -n | head -20 | while IFS=, read -r ci as aw dd bb maxpnl minpnl loss lmdelta; do ci_pct=$(python3 -c "print(f'{int(\"$ci\")/1e18:.0%}')" 2>/dev/null || echo "$ci") as_pct=$(python3 -c "print(f'{int(\"$as\")/1e18:.1%}')" 2>/dev/null || echo "$as") dd_pct=$(python3 -c "print(f'{int(\"$dd\")/1e18:.0%}')" 2>/dev/null || echo "$dd") maxpnl_eth=$(python3 -c "print(f'{int(\"$maxpnl\")/1e18:+.4f}')" 2>/dev/null || echo "$maxpnl") echo "| $ci_pct | $as_pct | $aw | $dd_pct | $bb | $maxpnl_eth |" done >> "$RESULTS_FILE" else echo "No safe parameter combinations found." >> "$RESULTS_FILE" fi { echo "" echo "## Recommendations" echo "" } >> "$RESULTS_FILE" if [ "$unsafe_combos" -eq 0 ]; then cat >> "$RESULTS_FILE" << 'RECO' **All tested parameter combinations are SAFE.** The three-position strategy's asymmetric slippage profile effectively prevents profitable arbitrage across all tested parameters. RECO else cat >> "$RESULTS_FILE" << 'RECO' **Some parameter combinations are UNSAFE.** The exploitation boundary depends primarily on: 1. **anchorShare**: Higher values allocate more ETH to the thin anchor position, reducing floor protection 2. **capitalInefficiency**: Lower values (0%) make the floor position more aggressive, increasing exploit risk 3. **anchorWidth**: Narrower widths concentrate anchor liquidity, making it cheaper to push through ### Safe Zone Parameters where the trader never profited across all tested scenarios. ### Unsafe Zone Parameters where at least one test run showed trader profit (= LM ETH loss). The exploitation pattern is: buy→recenter→sell→recenter repeated over many cycles, where VWAP accumulates at inflated prices and the floor gets positioned too high. RECO fi { echo "" echo "---" echo "*Generated: $(date -u +%Y-%m-%dT%H:%M:%SZ)*" } >> "$RESULTS_FILE" echo "" echo -e "${GREEN}Report: $RESULTS_FILE${NC}" echo -e "${GREEN}Data: $SUMMARY_FILE${NC}"