// Package lookup provides lookup tables for frequently used Uniswap V3 calculations. package lookup import ( "math/big" "sync" ) var ( // Lookup tables for frequently used values sqrt10001Table map[int]*big.Float q96Table *big.Int q192Table *big.Int // Once variables for initializing lookup tables sqrt10001Once sync.Once q96Once sync.Once ) // initSqrt10001Table initializes the lookup table for sqrt(1.0001^n) func initSqrt10001Table() { sqrt10001Once.Do(func() { sqrt10001Table = make(map[int]*big.Float) // Use a more practical range for ticks // This covers the range most commonly encountered in Uniswap V3 // Most Uniswap V3 pools have ticks in the range of approx. -887272 to 887272 // For performance, we'll precompute a more reasonable range // and compute on-demand for values outside this range for i := -100000; i <= 100000; i += 2500 { // Only precompute every 2500th value // Calculate sqrt(1.0001^(i/2)) base := 1.0001 power := float64(i) / 2.0 result := pow(base, power) // Store in lookup table sqrt10001Table[i] = new(big.Float).SetFloat64(result) } }) } // initQTables initializes the lookup tables for Q96 and Q192 func initQTables() { q96Once.Do(func() { // Q96 = 2^96 q96Table = new(big.Int).Exp(big.NewInt(2), big.NewInt(96), nil) // Q192 = 2^192 = (2^96)^2 q192Table = new(big.Int).Exp(big.NewInt(2), big.NewInt(192), nil) }) } // GetSqrt10001 retrieves the precomputed sqrt(1.0001^n) value func GetSqrt10001(n int) *big.Float { initSqrt10001Table() // Check if value is in lookup table if val, ok := sqrt10001Table[n]; ok { return val } // For values not in the lookup table, find the closest precomputed value // and calculate the difference to reduce computation base := 1.0001 power := float64(n) / 2.0 result := pow(base, power) // Add to lookup table for future use if it's within a reasonable range // to prevent memory overflow if n >= -500000 && n <= 500000 { sqrt10001Table[n] = new(big.Float).SetFloat64(result) } return new(big.Float).SetFloat64(result) } // GetQ96 retrieves the precomputed Q96 value (2^96) func GetQ96() *big.Int { initQTables() return q96Table } // GetQ192 retrieves the precomputed Q192 value (2^192) func GetQ192() *big.Int { initQTables() return q192Table } // Helper function for computing powers efficiently func pow(base, exp float64) float64 { if exp == 0 { return 1 } if exp == 1 { return base } if exp == 2 { return base * base } // For other values, use exponentiation by squaring return powInt(base, int(exp)) } // Integer power function using exponentiation by squaring func powInt(base float64, exp int) float64 { if exp < 0 { return 1.0 / powInt(base, -exp) } result := 1.0 for exp > 0 { if exp&1 == 1 { result *= base } base *= base exp >>= 1 } return result }