harb/onchain/CLAUDE.md
johba 2205ae719b feat: Optimize discovery position depth calculation
- Implement dynamic discovery depth based on anchor position share
- Add configurable discovery_max_multiple (1.5-4x) for flexible adjustment
- Update BullMarketOptimizer with new depth calculation logic
- Fix scenario visualizer floor position visibility
- Add comprehensive tests for discovery depth behavior

The discovery position now dynamically adjusts its depth based on the anchor
position's share of total liquidity, allowing for more effective price discovery
while maintaining protection against manipulation.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-16 16:45:24 +02:00

8.5 KiB

Smart Contracts - CLAUDE.md

This directory contains the core smart contracts for the KRAIKEN protocol.

Architecture Overview

Core Contracts

Kraiken.sol - ERC20 token contract with controlled minting/burning capabilities

  • Implements Harberger tax mechanism for staking positions
  • Controls minting rights exclusively for LiquidityManager
  • Handles tax collection and redistribution

LiquidityManager.sol - Dominant liquidity provider with three-position anti-arbitrage strategy

  • Uses Optimizer contract for dynamic parameter adjustment
  • Inherits from ThreePositionStrategy and PriceOracle (with VWAPTracker)
  • Key Feature: Asymmetric slippage profile prevents profitable trade-recenter-reverse attacks

VWAPTracker.sol - "Eternal memory" protection against dormant whale attacks

  • Volume-weighted average pricing with data compression (max 1000x)
  • Provides historical price memory to prevent manipulation

Optimizer.sol - Sentiment analysis and parameter optimization

  • Analyzes staking data (% staked, average tax rate)
  • Provides dynamic liquidity parameters
  • Upgradeable for future genetic algorithm implementation

Stake.sol - Harberger tax-based staking mechanism

  • Creates sentiment oracle through continuous auction
  • Limited to 20% of total supply (20,000 positions)
  • Self-assessed tax rates create prediction market

Position Strategy

Order: ANCHOR → DISCOVERY → FLOOR

  • ANCHOR: Shallow liquidity around current price for fast price movement (1-100% width range)
  • DISCOVERY: Proportional to KRAIKEN minted by anchor; borders anchor for fee capture (11000 tick spacing)
  • FLOOR: Deep liquidity using VWAP-adjusted pricing for historical price memory

Technical Specifications:

  • Fee Tier: 1% (10,000 basis points)
  • Tick Spacing: 200 (base), 11,000 (discovery)
  • Price Validation: 5-minute TWAP with 50-tick deviation tolerance
  • VWAP Compression: Maximum 1000x compression factor

Optimizer Parameters

All optimizers must return four key parameters that control the LiquidityManager's three-position strategy:

  1. capitalInefficiency (0 to 1e18):

    • Represents how much capital buffer the protocol maintains
    • 0 = aggressive (70% capital efficiency), 1e18 = conservative (170% backing)
    • Affects VWAP calculation: adjustedVWAP = 0.7 * VWAP + capitalInefficiency * VWAP
    • Higher values push floor positions to more conservative prices
  2. anchorShare (0 to 1e18):

    • Percentage of non-floor ETH allocated to the anchor position
    • Controls how much liquidity sits near current price
    • Higher values create more concentrated liquidity but mint more KRAIKEN tokens
    • Typical range: 30-95% (0.3e18 to 0.95e18)
  3. anchorWidth (0 to 100):

    • Width of the anchor position in percentage terms
    • Affects price impact of trades and speed of price movement
    • Lower values = tighter spreads, faster price discovery
    • Higher values = wider spreads, more stable prices
  4. discoveryDepth (0 to 1e18):

    • Controls the discovery position's liquidity density relative to anchor
    • Maps to internal multiplier range of 2x to 10x
    • At 0: discovery has 2x liquidity per tick vs anchor (minimal)
    • At 1e18: discovery has 10x liquidity per tick vs anchor (maximum)
    • Discovery amount formula: pulledHarb * DISCOVERY_SPACING * (200 + 800 * discoveryDepth/1e18) / anchorSpacing / 100
    • Higher values provide stronger anti-arbitrage protection but consume more minted tokens

Development Commands

# Build contracts
forge build

# Run all tests
forge test

# Run tests with gas reporting
forge test --gas-report

# Run specific test file
forge test --match-path test/LiquidityManager.t.sol

# Run fuzzing with more runs
forge test --fuzz-runs 10000

# Deploy contracts (see script/Deploy.s.sol)
forge script script/Deploy.s.sol --rpc-url $RPC_URL --broadcast

Testing Architecture

Test Helpers

  • test/helpers/UniswapTestBase.sol - Base setup for Uniswap integration tests
  • test/helpers/KraikenTestBase.sol - Common test utilities for KRAIKEN contracts
  • test/helpers/PositionRenderer.sol - Visualization tools for liquidity positions

Key Test Files

  • test/LiquidityManager.t.sol - Core liquidity management tests
  • test/abstracts/ThreePositionStrategy.t.sol - Position strategy validation
  • test/Stake.t.sol - Harberger tax mechanism tests
  • test/VWAPTracker.t.sol - Price memory and compression tests

Code Quality Guidelines

CRITICAL: Avoid Duplicate Code

  • ALWAYS check lib/uni-v3-lib for existing Uniswap math functions
  • NEVER reimplement standard math operations
  • Use test/helpers for common test patterns

Security Considerations

  • All external calls must be reentrancy protected
  • Price oracles must validate against manipulation
  • Tax calculations must handle edge cases (0 rates, max uint256)

Gas Optimization

  • Batch operations where possible
  • Use storage patterns that minimize SSTORE operations
  • Leverage Uniswap's existing math libraries

Analysis Tools

The analysis/ subdirectory contains critical tools for understanding and hardening the protocol:

  • Growth mechanism simulations
  • Attack vector analysis
  • Liquidity depth scenarios
  • See analysis/README.md for detailed usage

Uniswap V3 Math - Critical Learnings

Token Ordering and Price Representation

Price Direction Reference Table

Scenario token0 token1 Price Represents Lower Tick → Higher Tick
token0isETH = true ETH KRAIKEN ETH per KRAIKEN KRAIKEN cheap → expensive
token0isETH = false KRAIKEN ETH KRAIKEN per ETH ETH cheap → expensive

Understanding "Above" and "Below"

Critical distinction: "Price" in Uniswap V3 always refers to token1's price in units of token0.

When token0isETH = true (ETH is token0, KRAIKEN is token1):

  • Price = KRAIKEN price in ETH (how much ETH to buy 1 KRAIKEN)
  • Higher tick = Higher KRAIKEN price in ETH
  • Lower tick = Lower KRAIKEN price in ETH
  • "Price moved up" = KRAIKEN became more expensive = ETH became cheaper
  • "Price moved down" = KRAIKEN became cheaper = ETH became more expensive

When token0isETH = false (KRAIKEN is token0, ETH is token1):

  • Price = ETH price in KRAIKEN (how much KRAIKEN to buy 1 ETH)
  • Higher tick = Higher ETH price in KRAIKEN
  • Lower tick = Lower ETH price in KRAIKEN
  • "Price moved up" = ETH became more expensive = KRAIKEN became cheaper
  • "Price moved down" = ETH became cheaper = KRAIKEN became more expensive

This determines token composition:

Current Price vs Position Position Contains Why
Below range (tick < tickLower) 100% token1 Token0 is too expensive to hold
Within range (tickLower ≤ tick ≤ tickUpper) Both tokens Active liquidity range
Above range (tick > tickUpper) 100% token0 Token1 is too expensive to hold

Liquidity vs Token Amounts

Key Insight: Liquidity (L) is a mathematical constant representing capital efficiency, NOT token count.

  1. Liquidity is invariant: The liquidity value L doesn't change when price moves
  2. Token amounts are variable: Depend on liquidity L, price range, and current price location
  3. Same L, different ranges: Results in different token amounts due to price differences

Why Positions at Different Ranges Have Different Token Ratios

For the same liquidity value L:

  • Position at lower ticks: Higher token1 price → fewer token1, more token0 potential
  • Position at higher ticks: Lower token1 price → more token1, less token0 potential

This explains why a position with fewer tokens can have more liquidity (and thus more price impact resistance).

Liquidity Per Tick - The Critical Metric

When comparing positions of different widths, always normalize to liquidity per tick:

liquidityPerTick = totalLiquidity / (tickUpper - tickLower)

The discovery position maintains its target liquidity density through width adjustment:

// Ensure discovery has X times more liquidity per tick than anchor
discoveryLiquidity = anchorLiquidity * multiplier * discoveryWidth / anchorWidth

Key Takeaways

  1. Liquidity ≠ Token Count: Higher liquidity can mean fewer tokens at different price ranges
  2. Price Range Matters: Token composition depends on where positions sit relative to current price
  3. Normalize for Width: Always compare liquidity per tick when positions have different widths
  4. Token0 Ordering is Critical: Determines which direction is "up" or "down" in price