whale mode

This commit is contained in:
johba 2025-08-10 16:37:58 +02:00
parent c2d7c3c6c3
commit bcec691bbb
6 changed files with 103 additions and 12 deletions

View file

@ -6,6 +6,44 @@ Tools for testing the KRAIKEN LiquidityManager's resilience against various trad
## Quick Start
### Using run-fuzzing.sh (Recommended)
The `run-fuzzing.sh` script provides an easy way to run fuzzing campaigns with different market optimizers:
```bash
# Basic usage - run with specific optimizer
./analysis/run-fuzzing.sh BullMarketOptimizer
# Specify number of runs (default: 50)
./analysis/run-fuzzing.sh WhaleOptimizer runs=100
# Specify trades per run (default: 20, actual will be ±5)
./analysis/run-fuzzing.sh BearMarketOptimizer runs=10 trades=50
# Debug mode - generates position tracking CSV (forces runs=1)
./analysis/run-fuzzing.sh NeutralMarketOptimizer debugCSV
# Multiple parameters
./analysis/run-fuzzing.sh BullMarketOptimizer runs=25 trades=30
```
**Available optimizers:**
- `BullMarketOptimizer` - Biased towards buying
- `NeutralMarketOptimizer` - Balanced trading
- `BearMarketOptimizer` - Biased towards selling
- `WhaleOptimizer` - Large position trading
- `MockOptimizer` - Test optimizer
- `RandomScenarioOptimizer` - Random behavior
**Features:**
- Automatic results aggregation and summary generation
- Progress tracking with colored output
- Cumulative P&L calculation across all runs
- Automatic visualization launch for profitable scenarios
- Organized output in timestamped directories
### Manual Fuzzing (Advanced)
```bash
# Run fuzzing analysis with default settings (100 runs per market)
forge script analysis/FuzzingAnalysis.s.sol --ffi --via-ir
@ -19,8 +57,18 @@ TRACK_POSITIONS=true FUZZING_RUNS=50 forge script analysis/FuzzingAnalysis.s.sol
## Configuration
### run-fuzzing.sh Parameters
- **optimizer_class**: Required. The optimizer class to use (e.g., BullMarketOptimizer)
- **runs=N**: Optional. Number of fuzzing runs (default: 50)
- **trades=N**: Optional. Trades per run (default: 20, actual will be ±5)
- **debugCSV**: Optional. Enable debug mode with position tracking CSV (forces runs=1)
### Environment Variables (Manual Mode)
- **FUZZING_RUNS**: Number of random trading scenarios per market type (default: 100)
- **TRACK_POSITIONS**: Enable detailed position tracking CSV output (default: false)
- **OPTIMIZER_CLASS**: The optimizer to use (default: BullMarketOptimizer)
- **TRADES_PER_RUN**: Number of trades per run (default: 20)
- **SEED_OFFSET**: Starting seed for random number generation (default: 0)
## How It Works
@ -32,6 +80,15 @@ TRACK_POSITIONS=true FUZZING_RUNS=50 forge script analysis/FuzzingAnalysis.s.sol
## Output Files
### Using run-fuzzing.sh
Each campaign creates a timestamped directory: `fuzzing_results_[optimizer]_[timestamp]/`
- `config.txt` - Campaign configuration
- `run_*.log` - Individual run logs
- `merged_profitable_scenarios.csv` - All profitable scenarios combined
- `summary.txt` - Campaign summary with statistics
- `debug_positions_*.csv` - Position tracking data (when debugCSV is used)
### Manual Mode
- `profitable_scenarios_[timestamp].csv` - Details of all profitable trading sequences
- `positions_[scenario]_[seed].csv` - Liquidity position data (only with TRACK_POSITIONS=true)
@ -54,7 +111,22 @@ python3 -m http.server 8000
## Components
- `FuzzingAnalysis.s.sol` - Main fuzzing script
- `run-fuzzing.sh` - Main campaign runner with automatic visualization
- `FuzzingAnalysis.s.sol` - Core fuzzing script
- `helpers/SwapExecutor.sol` - Shared swap execution logic
- `CSVManager.sol` - CSV generation utilities
- `CSVHelper.sol` - CSV formatting helpers
- `helpers/CSVManager.sol` - CSV generation utilities
- `helpers/CSVHelper.sol` - CSV formatting helpers
## Example Campaign Comparison
To run fuzzing campaigns comparing different market optimizers:
```bash
# Run campaigns for all three market conditions
./analysis/run-fuzzing.sh BullMarketOptimizer runs=100
./analysis/run-fuzzing.sh NeutralMarketOptimizer runs=100
./analysis/run-fuzzing.sh BearMarketOptimizer runs=100
# Check results
cat fuzzing_results_*/summary.txt | grep -E "(Optimizer:|Success rate:|Average P&L)"
```

View file

@ -331,7 +331,11 @@ contract FuzzingAnalysis is Test, CSVManager {
}
function _recordPositionData(string memory label) internal {
(uint160 sqrtPriceX96,int24 currentTick,,,,,) = pool.slot0();
(,int24 currentTick,,,,,) = pool.slot0();
// Cap currentTick to avoid overflow in extreme cases
if (currentTick > 887000) currentTick = 887000;
if (currentTick < -887000) currentTick = -887000;
// Get each position
(uint128 floorLiq, int24 floorLower, int24 floorUpper) = lm.positions(ThreePositionStrategy.Stage.FLOOR);
@ -375,6 +379,7 @@ contract FuzzingAnalysis is Test, CSVManager {
floorHarb = 0;
} else {
// Current price is within the position
uint160 sqrtPriceX96 = TickMath.getSqrtRatioAtTick(currentTick);
floorEth = LiquidityAmounts.getAmount0ForLiquidity(sqrtPriceX96, sqrtRatioBX96, floorLiq);
floorHarb = LiquidityAmounts.getAmount1ForLiquidity(sqrtRatioAX96, sqrtPriceX96, floorLiq);
}
@ -389,6 +394,7 @@ contract FuzzingAnalysis is Test, CSVManager {
floorEth = LiquidityAmounts.getAmount1ForLiquidity(sqrtRatioAX96, sqrtRatioBX96, floorLiq);
} else {
// Current price is within the position
uint160 sqrtPriceX96 = TickMath.getSqrtRatioAtTick(currentTick);
floorHarb = LiquidityAmounts.getAmount0ForLiquidity(sqrtPriceX96, sqrtRatioBX96, floorLiq);
floorEth = LiquidityAmounts.getAmount1ForLiquidity(sqrtRatioAX96, sqrtPriceX96, floorLiq);
}
@ -407,6 +413,7 @@ contract FuzzingAnalysis is Test, CSVManager {
anchorEth = LiquidityAmounts.getAmount0ForLiquidity(sqrtRatioAX96, sqrtRatioBX96, anchorLiq);
anchorHarb = 0;
} else {
uint160 sqrtPriceX96 = TickMath.getSqrtRatioAtTick(currentTick);
anchorEth = LiquidityAmounts.getAmount0ForLiquidity(sqrtPriceX96, sqrtRatioBX96, anchorLiq);
anchorHarb = LiquidityAmounts.getAmount1ForLiquidity(sqrtRatioAX96, sqrtPriceX96, anchorLiq);
}
@ -418,6 +425,7 @@ contract FuzzingAnalysis is Test, CSVManager {
anchorHarb = 0;
anchorEth = LiquidityAmounts.getAmount1ForLiquidity(sqrtRatioAX96, sqrtRatioBX96, anchorLiq);
} else {
uint160 sqrtPriceX96 = TickMath.getSqrtRatioAtTick(currentTick);
anchorHarb = LiquidityAmounts.getAmount0ForLiquidity(sqrtPriceX96, sqrtRatioBX96, anchorLiq);
anchorEth = LiquidityAmounts.getAmount1ForLiquidity(sqrtRatioAX96, sqrtPriceX96, anchorLiq);
}
@ -436,6 +444,7 @@ contract FuzzingAnalysis is Test, CSVManager {
discoveryEth = LiquidityAmounts.getAmount0ForLiquidity(sqrtRatioAX96, sqrtRatioBX96, discoveryLiq);
discoveryHarb = 0;
} else {
uint160 sqrtPriceX96 = TickMath.getSqrtRatioAtTick(currentTick);
discoveryEth = LiquidityAmounts.getAmount0ForLiquidity(sqrtPriceX96, sqrtRatioBX96, discoveryLiq);
discoveryHarb = LiquidityAmounts.getAmount1ForLiquidity(sqrtRatioAX96, sqrtPriceX96, discoveryLiq);
}
@ -447,6 +456,7 @@ contract FuzzingAnalysis is Test, CSVManager {
discoveryHarb = 0;
discoveryEth = LiquidityAmounts.getAmount1ForLiquidity(sqrtRatioAX96, sqrtRatioBX96, discoveryLiq);
} else {
uint160 sqrtPriceX96 = TickMath.getSqrtRatioAtTick(currentTick);
discoveryHarb = LiquidityAmounts.getAmount0ForLiquidity(sqrtPriceX96, sqrtRatioBX96, discoveryLiq);
discoveryEth = LiquidityAmounts.getAmount1ForLiquidity(sqrtRatioAX96, sqrtPriceX96, discoveryLiq);
}

View file

@ -23,16 +23,18 @@ OPTIMIZER_CLASS=""
TOTAL_RUNS=50
TRADES_PER_RUN=20
DEBUG_CSV=false
WHALE_MODE=false
# Function to show usage
show_usage() {
echo "Usage: $0 <optimizer_class> [runs=N] [trades=N] [debugCSV]"
echo "Usage: $0 <optimizer_class> [runs=N] [trades=N] [debugCSV] [whaleMode]"
echo ""
echo "Parameters:"
echo " optimizer_class Required. The optimizer class to use"
echo " runs=N Optional. Number of fuzzing runs (default: 50)"
echo " trades=N Optional. Trades per run (default: 20, actual will be ±5)"
echo " debugCSV Optional. Enable debug mode with position tracking CSV (forces runs=1)"
echo " whaleMode Optional. Enable whale-sized trades (20-80% of balance, 50-500 ETH funding)"
echo ""
echo "Examples:"
echo " $0 BullMarketOptimizer"
@ -40,6 +42,7 @@ show_usage() {
echo " $0 BearMarketOptimizer runs=10 trades=50"
echo " $0 NeutralMarketOptimizer trades=30 runs=25"
echo " $0 BullMarketOptimizer debugCSV"
echo " $0 WhaleOptimizer whaleMode runs=20"
echo ""
echo "Available optimizers:"
echo " - BullMarketOptimizer"
@ -82,6 +85,9 @@ for arg in "$@"; do
DEBUG_CSV=true
TOTAL_RUNS=1
;;
whaleMode)
WHALE_MODE=true
;;
*)
echo "Error: Unknown parameter '$arg'"
show_usage
@ -106,6 +112,9 @@ echo "Trades per run: $TRADES_PER_RUN (±5)"
if [ "$DEBUG_CSV" = true ]; then
echo -e "${YELLOW}Debug mode: ENABLED (position tracking CSV will be generated)${NC}"
fi
if [ "$WHALE_MODE" = true ]; then
echo -e "${YELLOW}Whale mode: ENABLED (20-80% trades, 50-500 ETH funding)${NC}"
fi
echo "Output directory: $OUTPUT_DIR"
echo ""
@ -161,9 +170,9 @@ for i in $(seq 1 $TOTAL_RUNS); do
# Use iteration number as seed offset to ensure different scenarios
# Enable position tracking if debugCSV is set
if [ "$DEBUG_CSV" = true ]; then
TRACK_POSITIONS=true SEED_OFFSET=$((i - 1)) OPTIMIZER_CLASS="$OPTIMIZER_CLASS" TRADES_PER_RUN="$TRADES_PER_RUN" FUZZING_RUNS=1 forge script FuzzingAnalysis.s.sol --ffi --via-ir --gas-limit 200000000 > "$OUTPUT_DIR/run_$i.log" 2>&1
WHALE_MODE="$WHALE_MODE" TRACK_POSITIONS=true SEED_OFFSET=$((i - 1)) OPTIMIZER_CLASS="$OPTIMIZER_CLASS" TRADES_PER_RUN="$TRADES_PER_RUN" FUZZING_RUNS=1 forge script FuzzingAnalysis.s.sol --ffi --via-ir --gas-limit 200000000 > "$OUTPUT_DIR/run_$i.log" 2>&1
else
SEED_OFFSET=$((i - 1)) OPTIMIZER_CLASS="$OPTIMIZER_CLASS" TRADES_PER_RUN="$TRADES_PER_RUN" FUZZING_RUNS=1 forge script FuzzingAnalysis.s.sol --ffi --via-ir --gas-limit 200000000 > "$OUTPUT_DIR/run_$i.log" 2>&1
WHALE_MODE="$WHALE_MODE" SEED_OFFSET=$((i - 1)) OPTIMIZER_CLASS="$OPTIMIZER_CLASS" TRADES_PER_RUN="$TRADES_PER_RUN" FUZZING_RUNS=1 forge script FuzzingAnalysis.s.sol --ffi --via-ir --gas-limit 200000000 > "$OUTPUT_DIR/run_$i.log" 2>&1
fi
if [ $? -eq 0 ]; then