more docs

This commit is contained in:
johba 2025-08-18 00:16:09 +02:00
parent 50eac74b18
commit 01471b7037
9 changed files with 80 additions and 11 deletions

View file

@ -62,6 +62,9 @@ cd web && npm run dev
- Never fall back to simpler implementations - Never fall back to simpler implementations
- Identify root causes, don't work around issues - Identify root causes, don't work around issues
- Challenge technically unsound requests - 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 ### Tool Usage
- MCP browser screenshots: Keep under 8000px, use `fullPage: false` - MCP browser screenshots: Keep under 8000px, use `fullPage: false`

View file

@ -1,5 +1,20 @@
# Uniswap V3 Math - Critical Learnings # 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 ## Token Ordering and Price Representation
### Price Direction Reference Table ### Price Direction Reference Table

View file

@ -8,6 +8,11 @@ import {Math} from "@openzeppelin/utils/math/Math.sol";
/** /**
* @title stakeable ERC20 Token * @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. * @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 { contract Kraiken is ERC20, ERC20Permit {
using Math for uint256; using Math for uint256;

View file

@ -16,9 +16,19 @@ import "./abstracts/PriceOracle.sol";
* @title LiquidityManager * @title LiquidityManager
* @notice Manages liquidity provisioning on Uniswap V3 using the three-position anti-arbitrage strategy * @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 * @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 { 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); uint24 internal constant FEE = uint24(10_000);
/// @notice Immutable contract references /// @notice Immutable contract references

View file

@ -8,9 +8,18 @@ import {Initializable} from "@openzeppelin/proxy/utils/Initializable.sol";
/** /**
* @title Optimizer * @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. * 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. * @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 { contract Optimizer is Initializable, UUPSUpgradeable {
Kraiken private harberg; Kraiken private harberg;
@ -92,9 +101,9 @@ contract Optimizer is Initializable, UUPSUpgradeable {
/** /**
* @notice Returns liquidity parameters for the liquidity manager. * @notice Returns liquidity parameters for the liquidity manager.
* @return capitalInefficiency Calculated as (1e18 - sentiment). * @return capitalInefficiency Calculated as (1e18 - sentiment). Capital buffer level (0-1e18)
* @return anchorShare Set equal to the sentiment. * @return anchorShare Set equal to the sentiment. % of non-floor ETH in anchor (0-1e18)
* @return anchorWidth Here set to a constant 100 (adjust as needed). * @return anchorWidth Here set to a constant 100. Anchor position width % (1-100)
* @return discoveryDepth Set equal to the sentiment. * @return discoveryDepth Set equal to the sentiment.
*/ */
function getLiquidityParams() function getLiquidityParams()

View file

@ -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 * Tax rates and staking positions are adjustable, with a mechanism to prevent snatch-grieving by
* enforcing a minimum tax payment duration. * 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 { contract Stake {
using Math for uint256; using Math for uint256;

View file

@ -7,6 +7,12 @@ import "@openzeppelin/utils/math/Math.sol";
* @title VWAPTracker * @title VWAPTracker
* @notice Abstract contract for tracking Volume Weighted Average Price (VWAP) data * @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 * @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 { abstract contract VWAPTracker {
using Math for uint256; using Math for uint256;
@ -16,9 +22,10 @@ abstract contract VWAPTracker {
/** /**
* @notice Records volume and price data for VWAP calculation * @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 * @param fee The fee amount used to calculate volume
* @dev Assumes fee represents 1% of volume, handles overflow by compressing historic data * @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 { function _recordVolumeAndPrice(uint256 currentPriceX96, uint256 fee) internal {
// assuming FEE is 1% // assuming FEE is 1%

View file

@ -12,13 +12,21 @@ import "../VWAPTracker.sol";
* @title ThreePositionStrategy * @title ThreePositionStrategy
* @notice Abstract contract implementing the three-position liquidity strategy (Floor, Anchor, Discovery) * @notice Abstract contract implementing the three-position liquidity strategy (Floor, Anchor, Discovery)
* @dev Provides the core logic for anti-arbitrage asymmetric slippage profile * @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 { abstract contract ThreePositionStrategy is UniswapMath, VWAPTracker {
using Math for uint256; using Math for uint256;
/// @notice Tick spacing for the pool /// @notice Tick spacing for the pool (base spacing)
int24 internal constant TICK_SPACING = 200; 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; int24 internal constant DISCOVERY_SPACING = 11000;
/// @notice Minimum discovery depth multiplier /// @notice Minimum discovery depth multiplier
uint128 internal constant MIN_DISCOVERY_DEPTH = 200; 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) /// @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 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 pulledHarb HARB amount from anchor position
/// @param discoveryAmount HARB amount from discovery position /// @param discoveryAmount HARB amount from discovery position
/// @param params Position parameters /// @param params Position parameters including capital inefficiency
function _setFloorPosition( function _setFloorPosition(
int24 currentTick, int24 currentTick,
uint256 floorEthBalance, uint256 floorEthBalance,

View file

@ -43,8 +43,11 @@ abstract contract UniswapMath {
} }
/// @notice Calculates the price ratio from a given Uniswap V3 tick as HARB/ETH /// @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 /// @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) { function _priceAtTick(int24 tick) internal pure returns (uint256 priceRatioX96) {
uint256 sqrtRatioX96 = TickMath.getSqrtRatioAtTick(tick); uint256 sqrtRatioX96 = TickMath.getSqrtRatioAtTick(tick);
priceRatioX96 = sqrtRatioX96.mulDiv(sqrtRatioX96, (1 << 96)); priceRatioX96 = sqrtRatioX96.mulDiv(sqrtRatioX96, (1 << 96));