// Package uniswap provides mathematical functions for Uniswap V3 calculations. package uniswap import ( "math" "math/big" "github.com/holiman/uint256" ) // SqrtPriceX96ToPriceOptimized converts sqrtPriceX96 to a price using uint256 operations // This is a more optimized version that avoids big.Float operations where possible func SqrtPriceX96ToPriceOptimized(sqrtPriceX96 *uint256.Int) *big.Float { // price = (sqrtPriceX96 / 2^96)^2 // price = sqrtPriceX96^2 / 2^192 // Calculate sqrtPriceX96^2 using uint256 sqrtPriceSquared := new(uint256.Int).Mul(sqrtPriceX96, sqrtPriceX96) // Convert to big.Float for division price := new(big.Float).SetInt(sqrtPriceSquared.ToBig()) // Divide by 2^192 (which is (2^96)^2) // We can use a precomputed value for 2^192 q192 := new(big.Float).SetInt(new(big.Int).Exp(big.NewInt(2), big.NewInt(192), nil)) price.Quo(price, q192) return price } // PriceToSqrtPriceX96Optimized converts a price to sqrtPriceX96 using optimized operations func PriceToSqrtPriceX96Optimized(price *big.Float) *uint256.Int { // sqrtPriceX96 = sqrt(price) * 2^96 // Calculate sqrt(price) sqrtPrice := new(big.Float).Sqrt(price) // Multiply by 2^96 q96Int := new(big.Int) q96Int.SetString(Q96, 10) q96 := new(big.Float).SetInt(q96Int) sqrtPrice.Mul(sqrtPrice, q96) // Convert to uint256 sqrtPriceX96Int := sqrtPriceX96Big(sqrtPrice) sqrtPriceX96 := uint256.MustFromBig(sqrtPriceX96Int) return sqrtPriceX96 } // Helper function to convert big.Float to big.Int func sqrtPriceX96Big(f *big.Float) *big.Int { i, _ := f.Int(nil) return i } // TickToSqrtPriceX96Optimized converts a tick to sqrtPriceX96 using optimized operations func TickToSqrtPriceX96Optimized(tick int) *uint256.Int { // sqrtPriceX96 = 1.0001^(tick/2) * 2^96 // Using logarithms: 1.0001^(tick/2) = e^(ln(1.0001) * tick/2) lnBase := math.Log(1.0001) // ln(1.0001) ≈ 9.999500016666e-05 logResult := lnBase * float64(tick) / 2.0 result := math.Exp(logResult) // Convert to big.Float price := new(big.Float).SetFloat64(result) // Multiply by 2^96 q96Int := new(big.Int) q96Int.SetString(Q96, 10) q96 := new(big.Float).SetInt(q96Int) price.Mul(price, q96) // Convert to uint256 sqrtPriceX96Int := sqrtPriceX96Big(price) sqrtPriceX96 := uint256.MustFromBig(sqrtPriceX96Int) return sqrtPriceX96 }