Unverified Commit 17012c2b authored by Adam Tucker's avatar Adam Tucker Committed by GitHub
Browse files

Merge branch 'concentrated-liquidity-main' into mattverse/cl-4-slippage

parents 0a67e75c 6a08016c
Showing with 414 additions and 28 deletions
+414 -28
......@@ -18,3 +18,43 @@ func (k Keeper) CreatePosition(ctx sdk.Context, poolId uint64, owner sdk.AccAddr
func GetLiquidityFromAmounts(sqrtPrice, sqrtPriceA, sqrtPriceB sdk.Dec, amount0, amount1 sdk.Int) (liquidity sdk.Dec) {
return getLiquidityFromAmounts(sqrtPrice, sqrtPriceA, sqrtPriceB, amount0, amount1)
}
func PriceToTick(price sdk.Dec) sdk.Int {
return priceToTick(price)
}
func (k Keeper) TickToSqrtPrice(tickIndex sdk.Int) (sdk.Dec, error) {
return k.tickToSqrtPrice(tickIndex)
}
func (k Keeper) SetTickInfo(ctx sdk.Context, poolId uint64, tickIndex int64, tickInfo TickInfo) {
k.setTickInfo(ctx, poolId, tickIndex, tickInfo)
}
func GetNextSqrtPriceFromAmount0RoundingUp(sqrtPriceCurrent, liquidity, amountRemaining sdk.Dec) (sqrtPriceNext sdk.Dec) {
return getNextSqrtPriceFromAmount0RoundingUp(sqrtPriceCurrent, liquidity, amountRemaining)
}
func GetNextSqrtPriceFromAmount1RoundingDown(sqrtPriceCurrent, liquidity, amountRemaining sdk.Dec) (sqrtPriceNext sdk.Dec) {
return getNextSqrtPriceFromAmount1RoundingDown(sqrtPriceCurrent, liquidity, amountRemaining)
}
func CalcAmount0Delta(liq, sqrtPriceA, sqrtPriceB sdk.Dec) sdk.Dec {
return calcAmount0Delta(liq, sqrtPriceA, sqrtPriceB)
}
func CalcAmount1Delta(liq, sqrtPriceA, sqrtPriceB sdk.Dec) sdk.Dec {
return calcAmount1Delta(liq, sqrtPriceA, sqrtPriceB)
}
func ComputeSwapStep(sqrtPriceCurrent, sqrtPriceTarget, liquidity, amountRemaining sdk.Dec, zeroForOne bool) (sqrtPriceNext, amountIn, amountOut sdk.Dec) {
return computeSwapStep(sqrtPriceCurrent, sqrtPriceTarget, liquidity, amountRemaining, zeroForOne)
}
func Liquidity0(amount sdk.Int, sqrtPriceA, sqrtPriceB sdk.Dec) sdk.Dec {
return liquidity0(amount, sqrtPriceA, sqrtPriceB)
}
func Liquidity1(amount sdk.Int, sqrtPriceA, sqrtPriceB sdk.Dec) sdk.Dec {
return liquidity1(amount, sqrtPriceA, sqrtPriceB)
}
......@@ -3,6 +3,7 @@ package concentrated_liquidity_test
import (
"testing"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/stretchr/testify/suite"
"github.com/osmosis-labs/osmosis/v12/app/apptesting"
......@@ -19,3 +20,15 @@ func TestKeeperTestSuite(t *testing.T) {
func (suite *KeeperTestSuite) SetupTest() {
suite.Setup()
}
func (s *KeeperTestSuite) SetupPosition(poolId uint64) {
lowerTick := int64(84222)
upperTick := int64(86129)
amount0Desired := sdk.NewInt(1)
amount1Desired := sdk.NewInt(5000)
asset0, asset1, _, err := s.App.ConcentratedLiquidityKeeper.CreatePosition(s.Ctx, poolId, s.TestAccs[0], amount0Desired, amount1Desired, sdk.ZeroInt(), sdk.ZeroInt(), lowerTick, upperTick)
s.Require().NoError(err)
s.Require().Equal(amount0Desired.String(), asset0.String())
s.Require().Equal(amount1Desired.String(), asset1.String())
}
......@@ -7,6 +7,7 @@ import (
// liquidity0 takes an amount of asset0 in the pool as well as the sqrtpCur and the nextPrice
// sqrtPriceA is the smaller of sqrtpCur and the nextPrice
// sqrtPriceB is the larger of sqrtpCur and the nextPrice
// liquidity0 = amount0 * (sqrtPriceA * sqrtPriceB) / (sqrtPriceB - sqrtPriceA)
func liquidity0(amount sdk.Int, sqrtPriceA, sqrtPriceB sdk.Dec) sdk.Dec {
if sqrtPriceA.GT(sqrtPriceB) {
sqrtPriceA, sqrtPriceB = sqrtPriceB, sqrtPriceA
......@@ -19,7 +20,7 @@ func liquidity0(amount sdk.Int, sqrtPriceA, sqrtPriceB sdk.Dec) sdk.Dec {
// liquidity1 takes an amount of asset1 in the pool as well as the sqrtpCur and the nextPrice
// sqrtPriceA is the smaller of sqrtpCur and the nextPrice
// sqrtPriceB is the larger of sqrtpCur and the nextPrice
// liquidity1 = amount / (sqrtPriceB - sqrtPriceA)
// liquidity1 = amount1 / (sqrtPriceB - sqrtPriceA)
func liquidity1(amount sdk.Int, sqrtPriceA, sqrtPriceB sdk.Dec) sdk.Dec {
if sqrtPriceA.GT(sqrtPriceB) {
sqrtPriceA, sqrtPriceB = sqrtPriceB, sqrtPriceA
......@@ -28,10 +29,10 @@ func liquidity1(amount sdk.Int, sqrtPriceA, sqrtPriceB sdk.Dec) sdk.Dec {
return amount.ToDec().Quo(diff)
}
// calcAmount0 takes the asset with the smaller liqudity in the pool as well as the sqrtpCur and the nextPrice and calculates the amount of asset 0
// calcAmount0 takes the asset with the smaller liquidity in the pool as well as the sqrtpCur and the nextPrice and calculates the amount of asset 0
// sqrtPriceA is the smaller of sqrtpCur and the nextPrice
// sqrtPriceB is the larger of sqrtpCur and the nextPrice
// calcAmount0Delta = (liquidity * (sqrtPriceA - sqrtPriceB)) / (sqrtPriceA * sqrtPriceB)
// calcAmount0Delta = (liquidity * (sqrtPriceB - sqrtPriceA)) / (sqrtPriceB * sqrtPriceA)
func calcAmount0Delta(liq, sqrtPriceA, sqrtPriceB sdk.Dec) sdk.Dec {
if sqrtPriceA.GT(sqrtPriceB) {
sqrtPriceA, sqrtPriceB = sqrtPriceB, sqrtPriceA
......@@ -41,10 +42,10 @@ func calcAmount0Delta(liq, sqrtPriceA, sqrtPriceB sdk.Dec) sdk.Dec {
return (mult.Mul(diff)).Quo(sqrtPriceB).Quo(sqrtPriceA)
}
// calcAmount1 takes the asset with the smaller liqudity in the pool as well as the sqrtpCur and the nextPrice and calculates the amount of asset 1
// calcAmount1 takes the asset with the smaller liquidity in the pool as well as the sqrtpCur and the nextPrice and calculates the amount of asset 1
// sqrtPriceA is the smaller of sqrtpCur and the nextPrice
// sqrtPriceB is the larger of sqrtpCur and the nextPrice
// calcAmount1Delta = liq * (sqrtPriceA - sqrtPriceB)
// calcAmount1Delta = liq * (sqrtPriceB - sqrtPriceA)
func calcAmount1Delta(liq, sqrtPriceA, sqrtPriceB sdk.Dec) sdk.Dec {
if sqrtPriceA.GT(sqrtPriceB) {
sqrtPriceA, sqrtPriceB = sqrtPriceB, sqrtPriceA
......@@ -88,6 +89,12 @@ func getNextSqrtPriceFromInput(sqrtPriceCurrent, liquidity, amountRemaining sdk.
return sqrtPriceNext
}
// getNextSqrtPriceFromAmount0RoundingUp utilizes the current squareRootPrice, liquidity of denom0, and amount of denom0 that still needs
// to be swapped in order to determine the next squareRootPrice
// if (amountRemaining * sqrtPriceCurrent) / amountRemaining == sqrtPriceCurrent AND (liquidity * 2) + (amountRemaining * sqrtPriceCurrent) >= (liquidity * 2)
// sqrtPriceNext = (liquidity * 2 * sqrtPriceCurrent) / ((liquidity * 2) + (amountRemaining * sqrtPriceCurrent))
// else
// sqrtPriceNext = ((liquidity * 2)) / (((liquidity * 2) / (sqrtPriceCurrent)) + (amountRemaining))
func getNextSqrtPriceFromAmount0RoundingUp(sqrtPriceCurrent, liquidity, amountRemaining sdk.Dec) (sqrtPriceNext sdk.Dec) {
numerator := liquidity.Mul(sdk.NewDec(2))
product := amountRemaining.Mul(sqrtPriceCurrent)
......@@ -105,6 +112,9 @@ func getNextSqrtPriceFromAmount0RoundingUp(sqrtPriceCurrent, liquidity, amountRe
return sqrtPriceNext
}
// getNextSqrtPriceFromAmount1RoundingDown utilizes the current squareRootPrice, liquidity of denom1, and amount of denom1 that still needs
// to be swapped in order to determine the next squareRootPrice
// sqrtPriceNext = sqrtPriceCurrent + (amount1Remaining / liquidity1)
func getNextSqrtPriceFromAmount1RoundingDown(sqrtPriceCurrent, liquidity, amountRemaining sdk.Dec) (sqrtPriceNext sdk.Dec) {
return sqrtPriceCurrent.Add(amountRemaining.Quo(liquidity))
}
......
......@@ -6,17 +6,283 @@ import (
cl "github.com/osmosis-labs/osmosis/v12/x/concentrated-liquidity"
)
func (s *KeeperTestSuite) TestGetLiquidityFromAmounts() {
currentSqrtP, err := sdk.NewDecFromStr("70.710678")
sqrtPLow, err := sdk.NewDecFromStr("67.082039")
sqrtPHigh, err := sdk.NewDecFromStr("74.161984")
s.Require().NoError(err)
func (suite *KeeperTestSuite) TestGetLiquidityFromAmounts() {
testCases := []struct {
name string
currentSqrtP sdk.Dec
sqrtPHigh sdk.Dec
sqrtPLow sdk.Dec
amount0Desired sdk.Int
amount1Desired sdk.Int
expectedLiquidity string
}{
{
"happy path",
sdk.MustNewDecFromStr("70.710678"),
sdk.MustNewDecFromStr("74.161984"),
sdk.MustNewDecFromStr("67.082039"),
sdk.NewInt(1),
sdk.NewInt(5000),
"1377.927096082029653542",
},
}
amount0Desired := sdk.NewInt(1)
amount1Desired := sdk.NewInt(5000)
for _, tc := range testCases {
tc := tc
s.SetupTest()
suite.Run(tc.name, func() {
liquidity := cl.GetLiquidityFromAmounts(tc.currentSqrtP, tc.sqrtPLow, tc.sqrtPHigh, tc.amount0Desired, tc.amount1Desired)
suite.Require().Equal(tc.expectedLiquidity, liquidity.String())
liq0 := cl.Liquidity0(tc.amount0Desired, tc.currentSqrtP, tc.sqrtPHigh)
liq1 := cl.Liquidity1(tc.amount1Desired, tc.currentSqrtP, tc.sqrtPLow)
liq := sdk.MinDec(liq0, liq1)
suite.Require().Equal(liq.String(), liquidity.String())
liquidity := cl.GetLiquidityFromAmounts(currentSqrtP, sqrtPLow, sqrtPHigh, amount0Desired, amount1Desired)
s.Require().Equal("1377.927096082029653542", liquidity.String())
})
}
}
// liquidity1 takes an amount of asset1 in the pool as well as the sqrtpCur and the nextPrice
// sqrtPriceA is the smaller of sqrtpCur and the nextPrice
// sqrtPriceB is the larger of sqrtpCur and the nextPrice
// liquidity1 = amount1 / (sqrtPriceB - sqrtPriceA)
func (suite *KeeperTestSuite) TestLiquidity1() {
testCases := []struct {
name string
currentSqrtP sdk.Dec
sqrtPLow sdk.Dec
amount1Desired sdk.Int
expectedLiquidity string
}{
{
"happy path",
sdk.NewDecWithPrec(70710678, 6),
sdk.NewDecWithPrec(67082039, 6),
sdk.NewInt(5000),
"1377.927096082029653542",
// https://www.wolframalpha.com/input?i=5000+%2F+%2870.710678+-+67.082039%29
},
}
for _, tc := range testCases {
tc := tc
suite.Run(tc.name, func() {
liquidity := cl.Liquidity1(tc.amount1Desired, tc.currentSqrtP, tc.sqrtPLow)
suite.Require().Equal(tc.expectedLiquidity, liquidity.String())
})
}
}
// TestLiquidity0 tests that liquidity0 takes an amount of asset0 in the pool as well as the sqrtpCur and the nextPrice
// sqrtPriceA is the smaller of sqrtpCur and the nextPrice
// sqrtPriceB is the larger of sqrtpCur and the nextPrice
// liquidity0 = amount0 * (sqrtPriceA * sqrtPriceB) / (sqrtPriceB - sqrtPriceA)
func (suite *KeeperTestSuite) TestLiquidity0() {
testCases := []struct {
name string
currentSqrtP sdk.Dec
sqrtPHigh sdk.Dec
amount0Desired sdk.Int
expectedLiquidity string
}{
{
"happy path",
sdk.MustNewDecFromStr("70.710678"),
sdk.MustNewDecFromStr("74.161984"),
sdk.NewInt(1),
"1519.437618821730672389",
// https://www.wolframalpha.com/input?i=1+*+%2870.710678+*+74.161984%29+%2F+%2874.161984+-+70.710678%29
},
}
for _, tc := range testCases {
tc := tc
suite.Run(tc.name, func() {
liquidity := cl.Liquidity0(tc.amount0Desired, tc.currentSqrtP, tc.sqrtPHigh)
suite.Require().Equal(tc.expectedLiquidity, liquidity.String())
})
}
}
// TestGetNextSqrtPriceFromAmount0RoundingUp tests that getNextSqrtPriceFromAmount0RoundingUp utilizes
// the current squareRootPrice, liquidity of denom0, and amount of denom0 that still needs
// to be swapped in order to determine the next squareRootPrice
// PATH 1
// if (amountRemaining * sqrtPriceCurrent) / amountRemaining == sqrtPriceCurrent AND (liquidity * 2) + (amountRemaining * sqrtPriceCurrent) >= (liquidity * 2)
// sqrtPriceNext = (liquidity * 2 * sqrtPriceCurrent) / ((liquidity * 2) + (amountRemaining * sqrtPriceCurrent))
// PATH 2
// else
// sqrtPriceNext = ((liquidity * 2)) / (((liquidity * 2) / (sqrtPriceCurrent)) + (amountRemaining))
func (suite *KeeperTestSuite) TestGetNextSqrtPriceFromAmount0RoundingUp() {
testCases := []struct {
name string
liquidity sdk.Dec
sqrtPCurrent sdk.Dec
amount0Remaining sdk.Dec
sqrtPriceNextExpected string
}{
{
"happy path 1",
sdk.NewDec(1377927219),
sdk.NewDecWithPrec(70710678, 6),
sdk.NewDec(133700),
"70.468932817327539027",
// https://www.wolframalpha.com/input?i=%281377927219+*+2+*+70.710678%29+%2F+%28%281377927219+*+2%29+%2B+%28133700+*+70.710678%29%29
},
}
for _, tc := range testCases {
tc := tc
suite.Run(tc.name, func() {
sqrtPriceNext := cl.GetNextSqrtPriceFromAmount0RoundingUp(tc.sqrtPCurrent, tc.liquidity, tc.amount0Remaining)
suite.Require().Equal(tc.sqrtPriceNextExpected, sqrtPriceNext.String())
})
}
}
// TestGetNextSqrtPriceFromAmount1RoundingDown tests that getNextSqrtPriceFromAmount1RoundingDown
// utilizes the current squareRootPrice, liquidity of denom1, and amount of denom1 that still needs
// to be swapped in order to determine the next squareRootPrice
// sqrtPriceNext = sqrtPriceCurrent + (amount1Remaining / liquidity1)
func (suite *KeeperTestSuite) TestGetNextSqrtPriceFromAmount1RoundingDown() {
testCases := []struct {
name string
liquidity sdk.Dec
sqrtPCurrent sdk.Dec
amount1Remaining sdk.Dec
sqrtPriceNextExpected string
}{
{
"happy path",
sdk.NewDec(1377927219),
sdk.NewDecWithPrec(70710678, 6),
sdk.NewDec(42000000),
"70.741158564880981569",
// https://www.wolframalpha.com/input?i=70.710678+%2B+%2842000000+%2F+1377927219%29
},
}
for _, tc := range testCases {
tc := tc
suite.Run(tc.name, func() {
sqrtPriceNext := cl.GetNextSqrtPriceFromAmount1RoundingDown(tc.sqrtPCurrent, tc.liquidity, tc.amount1Remaining)
suite.Require().Equal(tc.sqrtPriceNextExpected, sqrtPriceNext.String())
})
}
}
// TestCalcAmount0Delta tests that calcAmount0 takes the asset with the smaller liquidity in the pool as well as the sqrtpCur and the nextPrice and calculates the amount of asset 0
// sqrtPriceA is the smaller of sqrtpCur and the nextPrice
// sqrtPriceB is the larger of sqrtpCur and the nextPrice
// calcAmount0Delta = (liquidity * (sqrtPriceB - sqrtPriceA)) / (sqrtPriceB * sqrtPriceA)
func (suite *KeeperTestSuite) TestCalcAmount0Delta() {
testCases := []struct {
name string
liquidity sdk.Dec
sqrtPCurrent sdk.Dec
sqrtPUpper sdk.Dec
amount0Expected string
}{
{
"happy path",
sdk.NewDec(1377927219),
sdk.MustNewDecFromStr("70.710678"),
sdk.MustNewDecFromStr("74.161984"),
"906866",
// https://www.wolframalpha.com/input?i=%281377927219+*+%2874.161984+-+70.710678+%29%29+%2F+%2870.710678+*+74.161984%29
},
}
for _, tc := range testCases {
tc := tc
suite.Run(tc.name, func() {
amount0 := cl.CalcAmount0Delta(tc.liquidity, tc.sqrtPCurrent, tc.sqrtPUpper)
suite.Require().Equal(tc.amount0Expected, amount0.TruncateInt().String())
})
}
}
// TestCalcAmount1Delta tests that calcAmount1 takes the asset with the smaller liquidity in the pool as well as the sqrtpCur and the nextPrice and calculates the amount of asset 1
// sqrtPriceA is the smaller of sqrtpCur and the nextPrice
// sqrtPriceB is the larger of sqrtpCur and the nextPrice
// calcAmount1Delta = liq * (sqrtPriceB - sqrtPriceA)
func (suite *KeeperTestSuite) TestCalcAmount1Delta() {
testCases := []struct {
name string
liquidity sdk.Dec
sqrtPCurrent sdk.Dec
sqrtPLower sdk.Dec
amount1Expected string
}{
{
"happy path",
sdk.NewDec(1377927219),
sdk.NewDecWithPrec(70710678, 6),
sdk.NewDecWithPrec(67082039, 6),
"5000000446",
// https://www.wolframalpha.com/input?i=1377927219+*+%2870.710678+-+67.082039%29
},
}
for _, tc := range testCases {
tc := tc
suite.Run(tc.name, func() {
amount1 := cl.CalcAmount1Delta(tc.liquidity, tc.sqrtPCurrent, tc.sqrtPLower)
suite.Require().Equal(tc.amount1Expected, amount1.TruncateInt().String())
})
}
}
func (suite *KeeperTestSuite) TestComputeSwapState() {
testCases := []struct {
name string
sqrtPCurrent sdk.Dec
sqrtPTarget sdk.Dec
liquidity sdk.Dec
amountRemaining sdk.Dec
zeroForOne bool
expectedSqrtPriceNext string
expectedAmountIn string
expectedAmountOut string
}{
{
"happy path: trade asset0 for asset1",
sdk.NewDecWithPrec(70710678, 6),
sdk.OneDec(),
sdk.NewDec(1377927219),
sdk.NewDec(133700),
true,
"70.468932817327539027",
"66849.999999999999897227",
"333107267.266511136411924087",
},
{
"happy path: trade asset1 for asset0",
sdk.NewDecWithPrec(70710678, 6),
sdk.OneDec(),
sdk.NewDec(1377927219),
sdk.NewDec(4199999999),
false,
"73.758734487372429211",
"4199999998.999999999987594209",
"805287.266898087447354318",
},
}
for _, tc := range testCases {
tc := tc
suite.Run(tc.name, func() {
sqrtPriceNext, amountIn, amountOut := cl.ComputeSwapStep(tc.sqrtPCurrent, tc.sqrtPTarget, tc.liquidity, tc.amountRemaining, tc.zeroForOne)
suite.Require().Equal(tc.expectedSqrtPriceNext, sqrtPriceNext.String())
suite.Require().Equal(tc.expectedAmountIn, amountIn.String())
suite.Require().Equal(tc.expectedAmountOut, amountOut.String())
})
}
}
......@@ -36,6 +36,7 @@ func (k Keeper) GetPool(ctx sdk.Context, poolId uint64) (types.PoolI, error) {
return nil, errors.New("not implemented")
}
// priceToTick takes a price and returns the corresponding tick index
func priceToTick(price sdk.Dec) sdk.Int {
logOfPrice := osmomath.BigDecFromSDKDec(price).LogBase2()
logInt := osmomath.NewDecWithPrec(10001, 4)
......@@ -125,12 +126,11 @@ func (k Keeper) CalcOutAmtGivenIn(ctx sdk.Context, tokenIn sdk.Coin, tokenOutDen
// TODO: This should be GT 0 but some instances have very small remainder
// need to look into fixing this
for swapState.amountSpecifiedRemaining.GT(sdk.NewDecWithPrec(1, 6)) && !swapState.sqrtPrice.Equal(priceLimit) {
nextTick, _ := k.NextInitializedTick(ctx, poolId, swapState.tick.Int64(), zeroForOne)
// TODO: we can enable this error checking once we fix tick initialization
// if !ok {
// return sdk.Coin{}, sdk.Coin{}, fmt.Errorf("there are no more ticks initialized to fill the swap")
// }
for swapState.amountSpecifiedRemaining.GT(sdk.NewDecWithPrec(1, 6)) {
nextTick, ok := k.NextInitializedTick(ctx, poolId, swapState.tick.Int64(), zeroForOne)
if !ok {
return sdk.Coin{}, sdk.Coin{}, fmt.Errorf("there are no more ticks initialized to fill the swap")
}
nextSqrtPrice, err := k.tickToSqrtPrice(sdk.NewInt(nextTick))
if err != nil {
return sdk.Coin{}, sdk.Coin{}, fmt.Errorf("could not convert next tick (%v) to nextSqrtPrice", sdk.NewInt(nextTick))
......
......@@ -3,6 +3,7 @@ package concentrated_liquidity_test
import (
sdk "github.com/cosmos/cosmos-sdk/types"
cl "github.com/osmosis-labs/osmosis/v12/x/concentrated-liquidity"
cltypes "github.com/osmosis-labs/osmosis/v12/x/concentrated-liquidity/types"
)
......@@ -10,6 +11,7 @@ func (s *KeeperTestSuite) TestCalcOutAmtGivenIn() {
ctx := s.Ctx
pool, err := s.App.ConcentratedLiquidityKeeper.CreateNewConcentratedLiquidityPool(ctx, 1, "eth", "usdc", sdk.MustNewDecFromStr("70.710678"), sdk.NewInt(85176))
s.Require().NoError(err)
s.SetupPosition(pool.Id)
// test asset a to b logic
tokenIn := sdk.NewCoin("eth", sdk.NewInt(133700))
......@@ -54,6 +56,7 @@ func (s *KeeperTestSuite) TestCalcInAmtGivenOut() {
ctx := s.Ctx
pool, err := s.App.ConcentratedLiquidityKeeper.CreateNewConcentratedLiquidityPool(s.Ctx, 1, "eth", "usdc", sdk.MustNewDecFromStr("70.710678"), sdk.NewInt(85176))
s.Require().NoError(err)
s.SetupPosition(pool.Id)
// test asset a to b logic
tokenOut := sdk.NewCoin("usdc", sdk.NewInt(4199999999))
......@@ -100,3 +103,26 @@ func (s *KeeperTestSuite) TestOrderInitialPoolDenoms() {
s.Require().Error(err)
}
func (suite *KeeperTestSuite) TestPriceToTick() {
testCases := []struct {
name string
price sdk.Dec
tickExpected string
}{
{
"happy path",
sdk.NewDec(5000),
"85176",
},
}
for _, tc := range testCases {
tc := tc
suite.Run(tc.name, func() {
tick := cl.PriceToTick(tc.price)
suite.Require().Equal(tc.tickExpected, tick.String())
})
}
}
......@@ -12,6 +12,7 @@ import (
types "github.com/osmosis-labs/osmosis/v12/x/concentrated-liquidity/types"
)
// tickToSqrtPrice takes the tick index and returns the corresponding sqrt of the price
func (k Keeper) tickToSqrtPrice(tickIndex sdk.Int) (sdk.Dec, error) {
price, err := sdk.NewDecWithPrec(10001, 4).Power(tickIndex.Uint64()).ApproxSqrt()
if err != nil {
......
package concentrated_liquidity
package concentrated_liquidity_test
import (
"testing"
......@@ -8,6 +8,7 @@ import (
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/stretchr/testify/require"
cl "github.com/osmosis-labs/osmosis/v12/x/concentrated-liquidity"
types "github.com/osmosis-labs/osmosis/v12/x/concentrated-liquidity/types"
)
......@@ -16,14 +17,14 @@ func TestKeeper_TickOrdering(t *testing.T) {
tKey := sdk.NewTransientStoreKey("transient_test")
ctx := testutil.DefaultContext(storeKey, tKey)
k := Keeper{storeKey: storeKey}
k := cl.NewKeeper(storeKey)
liquidityTicks := []int64{-200, -55, -4, 70, 78, 84, 139, 240, 535}
for _, t := range liquidityTicks {
k.setTickInfo(ctx, 1, t, TickInfo{})
k.SetTickInfo(ctx, 1, t, cl.TickInfo{})
}
store := ctx.KVStore(k.storeKey)
store := ctx.KVStore(storeKey)
prefixBz := types.KeyTickPrefix(1)
prefixStore := prefix.NewStore(store, prefixBz)
......@@ -65,11 +66,11 @@ func TestKeeper_NextInitializedTick(t *testing.T) {
tKey := sdk.NewTransientStoreKey("transient_test")
ctx := testutil.DefaultContext(storeKey, tKey)
k := Keeper{storeKey: storeKey}
k := cl.NewKeeper(storeKey)
liquidityTicks := []int64{-200, -55, -4, 70, 78, 84, 139, 240, 535}
for _, t := range liquidityTicks {
k.setTickInfo(ctx, 1, t, TickInfo{})
k.SetTickInfo(ctx, 1, t, cl.TickInfo{})
}
t.Run("lte=true", func(t *testing.T) {
......@@ -99,7 +100,7 @@ func TestKeeper_NextInitializedTick(t *testing.T) {
require.True(t, initd)
})
t.Run("returns the next initialized tick from the next word", func(t *testing.T) {
k.setTickInfo(ctx, 1, 340, TickInfo{})
k.SetTickInfo(ctx, 1, 340, cl.TickInfo{})
n, initd := k.NextInitializedTick(ctx, 1, 328, true)
require.Equal(t, int64(340), n)
......@@ -125,3 +126,32 @@ func TestKeeper_NextInitializedTick(t *testing.T) {
})
})
}
func (suite *KeeperTestSuite) TestTickToSqrtPrice() {
testCases := []struct {
name string
tickIndex sdk.Int
sqrtPriceExpected string
expectErr bool
}{
{
"happy path",
sdk.NewInt(85176),
"70.710004849206351867",
false,
},
}
for _, tc := range testCases {
tc := tc
suite.Run(tc.name, func() {
sqrtPrice, err := suite.App.ConcentratedLiquidityKeeper.TickToSqrtPrice(tc.tickIndex)
if tc.expectErr {
suite.Require().Error(err)
} else {
suite.Require().Equal(tc.sqrtPriceExpected, sqrtPrice.String())
}
})
}
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment