From 01471b70378b425dbcd1afe540dc5a4f446f4f4a Mon Sep 17 00:00:00 2001 From: johba Date: Mon, 18 Aug 2025 00:16:09 +0200 Subject: [PATCH] more docs --- CLAUDE.md | 3 +++ onchain/UNISWAP_V3_MATH.md | 15 ++++++++++++++ onchain/src/Kraiken.sol | 5 +++++ onchain/src/LiquidityManager.sol | 12 ++++++++++- onchain/src/Optimizer.sol | 17 ++++++++++++---- onchain/src/Stake.sol | 5 +++++ onchain/src/VWAPTracker.sol | 9 ++++++++- .../src/abstracts/ThreePositionStrategy.sol | 20 +++++++++++++++---- onchain/src/libraries/UniswapMath.sol | 5 ++++- 9 files changed, 80 insertions(+), 11 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 2e73a0f..68ad596 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -62,6 +62,9 @@ cd web && npm run dev - Never fall back to simpler implementations - Identify root causes, don't work around issues - Challenge technically unsound requests +- **Price Formats**: `_priceAtTick` returns price² (not sqrtPrice) in X96 format - this is intentional for capital calculations +- **ETH Scarcity**: Floor positions at extreme ticks (140k+) indicate ETH scarcity - this is correct behavior, not a bug +- **VWAP Recording**: VWAP stores price² from anchor midpoint for historical price memory ### Tool Usage - MCP browser screenshots: Keep under 8000px, use `fullPage: false` diff --git a/onchain/UNISWAP_V3_MATH.md b/onchain/UNISWAP_V3_MATH.md index 24828d8..f5ec9f0 100644 --- a/onchain/UNISWAP_V3_MATH.md +++ b/onchain/UNISWAP_V3_MATH.md @@ -1,5 +1,20 @@ # Uniswap V3 Math - Critical Learnings +## Critical Implementation Details + +### Price Representation in KRAIKEN +- `_priceAtTick(tick)` returns **price²** in X96 format, NOT regular price or sqrtPrice +- This is intentional: price² = (sqrtPrice)² / 2^96 +- Used for ETH requirement calculations in floor positioning +- To get regular price from price²: take sqrt and shift left by 48 bits +- VWAP stores price² for volume-weighted averaging + +### ETH Scarcity vs Abundance +- **Scarcity**: Floor ETH < Outstanding KRAIKEN * VWAP price → Floor moves to extreme ticks (140k+) +- **Abundance**: Sufficient ETH → Floor placed near VWAP tick +- Extreme floor positions (tick 141,200+) are CORRECT behavior in scarcity scenarios +- Scarcity protects protocol solvency by making KRAIKEN very cheap (ETH expensive) + ## Token Ordering and Price Representation ### Price Direction Reference Table diff --git a/onchain/src/Kraiken.sol b/onchain/src/Kraiken.sol index b2aa0ed..b722ec6 100644 --- a/onchain/src/Kraiken.sol +++ b/onchain/src/Kraiken.sol @@ -8,6 +8,11 @@ import {Math} from "@openzeppelin/utils/math/Math.sol"; /** * @title stakeable ERC20 Token * @notice This contract implements an ERC20 token with mechanisms for minting and burning in which a single account (staking Pool) is proportionally receiving a share. Only the liquidity manager has permission to manage token supply. + * @dev Key features: + * - Controlled minting exclusively by LiquidityManager + * - Tax collection and redistribution mechanism through staking pool + * - 20% supply cap for staking (20,000 positions max) + * - Staking pool receives proportional share of all mints/burns */ contract Kraiken is ERC20, ERC20Permit { using Math for uint256; diff --git a/onchain/src/LiquidityManager.sol b/onchain/src/LiquidityManager.sol index 12eff60..bd5a770 100644 --- a/onchain/src/LiquidityManager.sol +++ b/onchain/src/LiquidityManager.sol @@ -16,9 +16,19 @@ import "./abstracts/PriceOracle.sol"; * @title LiquidityManager * @notice Manages liquidity provisioning on Uniswap V3 using the three-position anti-arbitrage strategy * @dev Inherits from modular contracts for better separation of concerns and testability + * + * Key features: + * - Three-position anti-arbitrage strategy (ANCHOR, DISCOVERY, FLOOR) + * - Dynamic parameter adjustment via Optimizer contract + * - Asymmetric slippage profile prevents profitable arbitrage + * - Exclusive minting rights for KRAIKEN token + * + * Price Validation: + * - 5-minute TWAP with 50-tick tolerance + * - Prevents oracle manipulation attacks */ contract LiquidityManager is ThreePositionStrategy, PriceOracle { - /// @notice Uniswap V3 fee tier (1%) + /// @notice Uniswap V3 fee tier (1%) - 10,000 basis points uint24 internal constant FEE = uint24(10_000); /// @notice Immutable contract references diff --git a/onchain/src/Optimizer.sol b/onchain/src/Optimizer.sol index 87648bb..c0884f0 100644 --- a/onchain/src/Optimizer.sol +++ b/onchain/src/Optimizer.sol @@ -8,9 +8,18 @@ import {Initializable} from "@openzeppelin/proxy/utils/Initializable.sol"; /** * @title Optimizer - * @notice This contract (formerly Sentimenter) calculates a “sentiment” value and liquidity parameters + * @notice This contract (formerly Sentimenter) calculates a "sentiment" value and liquidity parameters * based on the tax rate and the percentage of Kraiken staked. * @dev It is upgradeable using UUPS. Only the admin (set during initialization) can upgrade. + * + * Key features: + * - Analyzes staking sentiment (% staked, average tax rate) + * - Returns four key parameters for liquidity management: + * 1. capitalInefficiency (0 to 1e18): Capital buffer level + * 2. anchorShare (0 to 1e18): % of non-floor ETH in anchor + * 3. anchorWidth (0 to 100): Anchor position width % + * 4. discoveryDepth (0 to 1e18): Discovery liquidity density (2x-10x) + * - Upgradeable for future algorithm improvements */ contract Optimizer is Initializable, UUPSUpgradeable { Kraiken private harberg; @@ -92,9 +101,9 @@ contract Optimizer is Initializable, UUPSUpgradeable { /** * @notice Returns liquidity parameters for the liquidity manager. - * @return capitalInefficiency Calculated as (1e18 - sentiment). - * @return anchorShare Set equal to the sentiment. - * @return anchorWidth Here set to a constant 100 (adjust as needed). + * @return capitalInefficiency Calculated as (1e18 - sentiment). Capital buffer level (0-1e18) + * @return anchorShare Set equal to the sentiment. % of non-floor ETH in anchor (0-1e18) + * @return anchorWidth Here set to a constant 100. Anchor position width % (1-100) * @return discoveryDepth Set equal to the sentiment. */ function getLiquidityParams() diff --git a/onchain/src/Stake.sol b/onchain/src/Stake.sol index 42eb804..e25f512 100644 --- a/onchain/src/Stake.sol +++ b/onchain/src/Stake.sol @@ -26,6 +26,11 @@ error TooMuchSnatch(address receiver, uint256 stakeWanted, uint256 availableStak * * Tax rates and staking positions are adjustable, with a mechanism to prevent snatch-grieving by * enforcing a minimum tax payment duration. + * + * @dev Harberger tax implementation: + * - Continuous auction mechanism + * - Self-assessed valuations create prediction market + * - Tax collection and redistribution through UBI */ contract Stake { using Math for uint256; diff --git a/onchain/src/VWAPTracker.sol b/onchain/src/VWAPTracker.sol index 30f086c..6f768bb 100644 --- a/onchain/src/VWAPTracker.sol +++ b/onchain/src/VWAPTracker.sol @@ -7,6 +7,12 @@ import "@openzeppelin/utils/math/Math.sol"; * @title VWAPTracker * @notice Abstract contract for tracking Volume Weighted Average Price (VWAP) data * @dev Provides VWAP calculation and storage functionality that can be inherited by other contracts + * + * Key features: + * - Volume-weighted average with data compression (max 1000x compression) + * - Prevents dormant whale manipulation through historical price memory + * - Stores price² (squared price) in X96 format for VWAP calculation + * - Automatic overflow protection by compressing historic data when needed */ abstract contract VWAPTracker { using Math for uint256; @@ -16,9 +22,10 @@ abstract contract VWAPTracker { /** * @notice Records volume and price data for VWAP calculation - * @param currentPriceX96 The current price in X96 format + * @param currentPriceX96 The current price in X96 format (actually price² from _priceAtTick) * @param fee The fee amount used to calculate volume * @dev Assumes fee represents 1% of volume, handles overflow by compressing historic data + * @dev IMPORTANT: currentPriceX96 is expected to be price² (squared price), not regular price */ function _recordVolumeAndPrice(uint256 currentPriceX96, uint256 fee) internal { // assuming FEE is 1% diff --git a/onchain/src/abstracts/ThreePositionStrategy.sol b/onchain/src/abstracts/ThreePositionStrategy.sol index 62a9166..f94925f 100644 --- a/onchain/src/abstracts/ThreePositionStrategy.sol +++ b/onchain/src/abstracts/ThreePositionStrategy.sol @@ -12,13 +12,21 @@ import "../VWAPTracker.sol"; * @title ThreePositionStrategy * @notice Abstract contract implementing the three-position liquidity strategy (Floor, Anchor, Discovery) * @dev Provides the core logic for anti-arbitrage asymmetric slippage profile + * + * Three-Position Strategy: + * - ANCHOR: Near current price, fast price discovery (1-100% width) + * - DISCOVERY: Borders anchor, captures fees (11000 tick spacing) + * - FLOOR: Deep liquidity at VWAP-adjusted prices + * + * The asymmetric slippage profile prevents profitable arbitrage by making + * buys progressively more expensive while sells remain liquid */ abstract contract ThreePositionStrategy is UniswapMath, VWAPTracker { using Math for uint256; - /// @notice Tick spacing for the pool + /// @notice Tick spacing for the pool (base spacing) int24 internal constant TICK_SPACING = 200; - /// @notice Discovery spacing (3x current price in ticks) + /// @notice Discovery spacing (3x current price in ticks - 11000 ticks = ~3x price) int24 internal constant DISCOVERY_SPACING = 11000; /// @notice Minimum discovery depth multiplier uint128 internal constant MIN_DISCOVERY_DEPTH = 200; @@ -165,11 +173,15 @@ abstract contract ThreePositionStrategy is UniswapMath, VWAPTracker { } /// @notice Sets the floor position using VWAP for historical price memory (deep edge liquidity) + /// @dev Floor position placement depends on ETH scarcity vs abundance: + /// - Scarcity: Floor moves to extreme ticks (140k+) where KRAIKEN is very cheap + /// - Abundance: Floor placed near VWAP-adjusted price + /// Extreme floor positions are CORRECT behavior protecting protocol solvency /// @param currentTick Current market tick - /// @param floorEthBalance ETH allocated to floor position + /// @param floorEthBalance ETH allocated to floor position (75% of total) /// @param pulledHarb HARB amount from anchor position /// @param discoveryAmount HARB amount from discovery position - /// @param params Position parameters + /// @param params Position parameters including capital inefficiency function _setFloorPosition( int24 currentTick, uint256 floorEthBalance, diff --git a/onchain/src/libraries/UniswapMath.sol b/onchain/src/libraries/UniswapMath.sol index 5c089ef..6e009c3 100644 --- a/onchain/src/libraries/UniswapMath.sol +++ b/onchain/src/libraries/UniswapMath.sol @@ -43,8 +43,11 @@ abstract contract UniswapMath { } /// @notice Calculates the price ratio from a given Uniswap V3 tick as HARB/ETH + /// @dev IMPORTANT: Returns price² (squared price) in X96 format, NOT regular price + /// This is intentional for capital requirement calculations + /// To get regular price: sqrt(priceRatioX96) * 2^48 /// @param tick The tick for which to calculate the price ratio - /// @return priceRatioX96 The price ratio corresponding to the given tick + /// @return priceRatioX96 The price² (squared price) corresponding to the given tick function _priceAtTick(int24 tick) internal pure returns (uint256 priceRatioX96) { uint256 sqrtRatioX96 = TickMath.getSqrtRatioAtTick(tick); priceRatioX96 = sqrtRatioX96.mulDiv(sqrtRatioX96, (1 << 96));