Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[CL] Change calcOutAmtGivenIn and calcInAmtGivenOut to be non-mutative #3910

Merged
merged 12 commits into from
Jan 12, 2023
4 changes: 2 additions & 2 deletions x/concentrated-liquidity/export_test.go
Original file line number Diff line number Diff line change
@@ -55,11 +55,11 @@ func (k Keeper) SendCoinsBetweenPoolAndUser(ctx sdk.Context, denom0, denom1 stri
return k.sendCoinsBetweenPoolAndUser(ctx, denom0, denom1, amount0, amount1, sender, receiver)
}

func (k Keeper) CalcInAmtGivenOutInternal(ctx sdk.Context, desiredTokenOut sdk.Coin, tokenInDenom string, swapFee sdk.Dec, priceLimit sdk.Dec, poolId uint64) (tokenIn, tokenOut sdk.Coin, updatedTick sdk.Int, updatedLiquidity, updatedSqrtPrice sdk.Dec, err error) {
func (k Keeper) CalcInAmtGivenOutInternal(ctx sdk.Context, desiredTokenOut sdk.Coin, tokenInDenom string, swapFee sdk.Dec, priceLimit sdk.Dec, poolId uint64) (writeCtx func(), tokenIn, tokenOut sdk.Coin, updatedTick sdk.Int, updatedLiquidity, updatedSqrtPrice sdk.Dec, err error) {
return k.calcInAmtGivenOut(ctx, desiredTokenOut, tokenInDenom, swapFee, priceLimit, poolId)
}

func (k Keeper) CalcOutAmtGivenInInternal(ctx sdk.Context, tokenInMin sdk.Coin, tokenOutDenom string, swapFee sdk.Dec, priceLimit sdk.Dec, poolId uint64) (tokenIn, tokenOut sdk.Coin, updatedTick sdk.Int, updatedLiquidity, updatedSqrtPrice sdk.Dec, err error) {
func (k Keeper) CalcOutAmtGivenInInternal(ctx sdk.Context, tokenInMin sdk.Coin, tokenOutDenom string, swapFee sdk.Dec, priceLimit sdk.Dec, poolId uint64) (writeCtx func(), tokenIn, tokenOut sdk.Coin, updatedTick sdk.Int, updatedLiquidity, updatedSqrtPrice sdk.Dec, err error) {
return k.calcOutAmtGivenIn(ctx, tokenInMin, tokenOutDenom, swapFee, priceLimit, poolId)
}

65 changes: 35 additions & 30 deletions x/concentrated-liquidity/swaps.go
Original file line number Diff line number Diff line change
@@ -138,10 +138,11 @@ func (k Keeper) SwapOutAmtGivenIn(
priceLimit sdk.Dec,
poolId uint64,
) (calcTokenIn, calcTokenOut sdk.Coin, currentTick sdk.Int, liquidity, sqrtPrice sdk.Dec, err error) {
tokenIn, tokenOut, newCurrentTick, newLiquidity, newSqrtPrice, err := k.calcOutAmtGivenIn(ctx, tokenIn, tokenOutDenom, swapFee, priceLimit, poolId)
writeCtx, tokenIn, tokenOut, newCurrentTick, newLiquidity, newSqrtPrice, err := k.calcOutAmtGivenIn(ctx, tokenIn, tokenOutDenom, swapFee, priceLimit, poolId)
if err != nil {
return sdk.Coin{}, sdk.Coin{}, sdk.Int{}, sdk.Dec{}, sdk.Dec{}, err
}
writeCtx()
mattverse marked this conversation as resolved.
Show resolved Hide resolved

err = k.applySwap(ctx, tokenIn, tokenOut, poolId, newLiquidity, newCurrentTick, newSqrtPrice)
if err != nil {
@@ -159,10 +160,11 @@ func (k *Keeper) SwapInAmtGivenOut(
priceLimit sdk.Dec,
poolId uint64,
) (calcTokenIn, calcTokenOut sdk.Coin, currentTick sdk.Int, liquidity, sqrtPrice sdk.Dec, err error) {
tokenIn, tokenOut, newCurrentTick, newLiquidity, newSqrtPrice, err := k.calcInAmtGivenOut(ctx, desiredTokenOut, tokenInDenom, swapFee, priceLimit, poolId)
writeCtx, tokenIn, tokenOut, newCurrentTick, newLiquidity, newSqrtPrice, err := k.calcInAmtGivenOut(ctx, desiredTokenOut, tokenInDenom, swapFee, priceLimit, poolId)
if err != nil {
return sdk.Coin{}, sdk.Coin{}, sdk.Int{}, sdk.Dec{}, sdk.Dec{}, err
}
writeCtx()
mattverse marked this conversation as resolved.
Show resolved Hide resolved

err = k.applySwap(ctx, tokenIn, tokenOut, poolId, newLiquidity, newCurrentTick, newSqrtPrice)
if err != nil {
@@ -179,7 +181,7 @@ func (k Keeper) CalcOutAmtGivenIn(
tokenOutDenom string,
swapFee sdk.Dec,
) (tokenOut sdk.Coin, err error) {
_, tokenOut, _, _, _, err = k.calcOutAmtGivenIn(ctx, tokenIn, tokenOutDenom, swapFee, sdk.ZeroDec(), poolI.GetId())
_, _, tokenOut, _, _, _, err = k.calcOutAmtGivenIn(ctx, tokenIn, tokenOutDenom, swapFee, sdk.ZeroDec(), poolI.GetId())
if err != nil {
return sdk.Coin{}, err
}
@@ -193,7 +195,7 @@ func (k Keeper) CalcInAmtGivenOut(
tokenInDenom string,
swapFee sdk.Dec,
) (tokenIn sdk.Coin, err error) {
tokenIn, _, _, _, _, err = k.calcInAmtGivenOut(ctx, tokenOut, tokenInDenom, swapFee, sdk.ZeroDec(), poolI.GetId())
_, tokenIn, _, _, _, _, err = k.calcInAmtGivenOut(ctx, tokenOut, tokenInDenom, swapFee, sdk.ZeroDec(), poolI.GetId())
if err != nil {
return sdk.Coin{}, err
}
@@ -203,16 +205,18 @@ func (k Keeper) CalcInAmtGivenOut(
// calcOutAmtGivenIn calculates tokens to be swapped out given the provided amount and fee deducted. It also returns
// what the updated tick, liquidity, and currentSqrtPrice for the pool would be after this swap.
// Note this method is non-mutative, so the values returned by CalcOutAmtGivenIn do not get stored
// Instead, we return writeCtx function so that the caller of this method can decide to write the cached ctx to store or not.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mind adding spec for calcInAmtGivenOut as a drive by change in this PR please?

Just noticed it's missing

func (k Keeper) calcOutAmtGivenIn(ctx sdk.Context,
tokenInMin sdk.Coin,
tokenOutDenom string,
swapFee sdk.Dec,
priceLimit sdk.Dec,
poolId uint64,
) (tokenIn, tokenOut sdk.Coin, updatedTick sdk.Int, updatedLiquidity, updatedSqrtPrice sdk.Dec, err error) {
) (writeCtx func(), tokenIn, tokenOut sdk.Coin, updatedTick sdk.Int, updatedLiquidity, updatedSqrtPrice sdk.Dec, err error) {
ctx, writeCtx = ctx.CacheContext()
p, err := k.getPoolById(ctx, poolId)
if err != nil {
return sdk.Coin{}, sdk.Coin{}, sdk.Int{}, sdk.Dec{}, sdk.Dec{}, err
return writeCtx, sdk.Coin{}, sdk.Coin{}, sdk.Int{}, sdk.Dec{}, sdk.Dec{}, err
}
asset0 := p.GetToken0()
asset1 := p.GetToken1()
@@ -231,7 +235,7 @@ func (k Keeper) calcOutAmtGivenIn(ctx sdk.Context,
// take provided price limit and turn this into a sqrt price limit since formulas use sqrtPrice
sqrtPriceLimit, err := priceLimit.ApproxSqrt()
if err != nil {
return sdk.Coin{}, sdk.Coin{}, sdk.Int{}, sdk.Dec{}, sdk.Dec{}, fmt.Errorf("issue calculating square root of price limit")
return writeCtx, sdk.Coin{}, sdk.Coin{}, sdk.Int{}, sdk.Dec{}, sdk.Dec{}, fmt.Errorf("issue calculating square root of price limit")
}

// set the swap strategy
@@ -240,20 +244,20 @@ func (k Keeper) calcOutAmtGivenIn(ctx sdk.Context,
// get current sqrt price from pool
curSqrtPrice := p.GetCurrentSqrtPrice()
if err := swapStrategy.ValidatePriceLimit(sqrtPriceLimit, curSqrtPrice); err != nil {
return sdk.Coin{}, sdk.Coin{}, sdk.Int{}, sdk.Dec{}, sdk.Dec{}, err
return writeCtx, sdk.Coin{}, sdk.Coin{}, sdk.Int{}, sdk.Dec{}, sdk.Dec{}, err
}

// check that the specified tokenIn matches one of the assets in the specified pool
if tokenInMin.Denom != asset0 && tokenInMin.Denom != asset1 {
return sdk.Coin{}, sdk.Coin{}, sdk.Int{}, sdk.Dec{}, sdk.Dec{}, types.TokenInDenomNotInPoolError{TokenInDenom: tokenInMin.Denom}
return writeCtx, sdk.Coin{}, sdk.Coin{}, sdk.Int{}, sdk.Dec{}, sdk.Dec{}, types.TokenInDenomNotInPoolError{TokenInDenom: tokenInMin.Denom}
}
// check that the specified tokenOut matches one of the assets in the specified pool
if tokenOutDenom != asset0 && tokenOutDenom != asset1 {
return sdk.Coin{}, sdk.Coin{}, sdk.Int{}, sdk.Dec{}, sdk.Dec{}, types.TokenOutDenomNotInPoolError{TokenOutDenom: tokenOutDenom}
return writeCtx, sdk.Coin{}, sdk.Coin{}, sdk.Int{}, sdk.Dec{}, sdk.Dec{}, types.TokenOutDenomNotInPoolError{TokenOutDenom: tokenOutDenom}
}
// check that token in and token out are different denominations
if tokenInMin.Denom == tokenOutDenom {
return sdk.Coin{}, sdk.Coin{}, sdk.Int{}, sdk.Dec{}, sdk.Dec{}, types.DenomDuplicatedError{TokenInDenom: tokenInMin.Denom, TokenOutDenom: tokenOutDenom}
return writeCtx, sdk.Coin{}, sdk.Coin{}, sdk.Int{}, sdk.Dec{}, sdk.Dec{}, types.DenomDuplicatedError{TokenInDenom: tokenInMin.Denom, TokenOutDenom: tokenOutDenom}
}

// initialize swap state with the following parameters:
@@ -280,19 +284,19 @@ func (k Keeper) calcOutAmtGivenIn(ctx sdk.Context,
// if no ticks are initialized (no users have created liquidity positions) then we return an error
nextTick, ok := swapStrategy.NextInitializedTick(ctx, poolId, swapState.tick.Int64())
if !ok {
return sdk.Coin{}, sdk.Coin{}, sdk.Int{}, sdk.Dec{}, sdk.Dec{}, fmt.Errorf("there are no more ticks initialized to fill the swap")
return writeCtx, sdk.Coin{}, sdk.Coin{}, sdk.Int{}, sdk.Dec{}, sdk.Dec{}, fmt.Errorf("there are no more ticks initialized to fill the swap")
}

// utilizing the next initialized tick, we find the corresponding nextPrice (the target price)
nextPrice, err := math.TickToPrice(nextTick, p.GetPrecisionFactorAtPriceOne())
if err != nil {
return sdk.Coin{}, sdk.Coin{}, sdk.Int{}, sdk.Dec{}, sdk.Dec{}, fmt.Errorf("could not convert next tick (%v) to nextPrice", nextTick)
return writeCtx, sdk.Coin{}, sdk.Coin{}, sdk.Int{}, sdk.Dec{}, sdk.Dec{}, fmt.Errorf("could not convert next tick (%v) to nextSqrtPrice", nextTick)
}

// transform to sqrtPrice
nextSqrtPrice, err := nextPrice.ApproxSqrt()
if err != nil {
return sdk.Coin{}, sdk.Coin{}, sdk.Int{}, sdk.Dec{}, sdk.Dec{}, fmt.Errorf("could not convert next price (%v) to nextSqrtPrice", nextPrice)
return writeCtx, sdk.Coin{}, sdk.Coin{}, sdk.Int{}, sdk.Dec{}, sdk.Dec{}, fmt.Errorf("could not convert next tick (%v) to nextSqrtPrice", nextSqrtPrice)
}

// utilizing the bucket's liquidity and knowing the price target, we calculate the how much tokenOut we get from the tokenIn
@@ -317,7 +321,7 @@ func (k Keeper) calcOutAmtGivenIn(ctx sdk.Context,
// retrieve the liquidity held in the next closest initialized tick
liquidityNet, err := k.crossTick(ctx, p.GetId(), nextTick.Int64())
if err != nil {
return sdk.Coin{}, sdk.Coin{}, sdk.Int{}, sdk.Dec{}, sdk.Dec{}, err
return writeCtx, sdk.Coin{}, sdk.Coin{}, sdk.Int{}, sdk.Dec{}, sdk.Dec{}, err
}
liquidityNet = swapStrategy.SetLiquidityDeltaSign(liquidityNet)
// update the swapState's liquidity with the new tick's liquidity
@@ -331,7 +335,7 @@ func (k Keeper) calcOutAmtGivenIn(ctx sdk.Context,
// beginning of this iteration, we set the swapState tick to the corresponding tick of the sqrtPrice calculated from computeSwapStep
swapState.tick, err = math.PriceToTick(sqrtPrice.Power(2), p.GetPrecisionFactorAtPriceOne())
if err != nil {
return sdk.Coin{}, sdk.Coin{}, sdk.Int{}, sdk.Dec{}, sdk.Dec{}, err
return writeCtx, sdk.Coin{}, sdk.Coin{}, sdk.Int{}, sdk.Dec{}, sdk.Dec{}, err
}
}
}
@@ -344,7 +348,7 @@ func (k Keeper) calcOutAmtGivenIn(ctx sdk.Context,
tokenIn = sdk.NewCoin(tokenInMin.Denom, amt0)
tokenOut = sdk.NewCoin(tokenOutDenom, amt1)

return tokenIn, tokenOut, swapState.tick, swapState.liquidity, swapState.sqrtPrice, nil
return writeCtx, tokenIn, tokenOut, swapState.tick, swapState.liquidity, swapState.sqrtPrice, nil
}

func (k Keeper) calcInAmtGivenOut(
@@ -354,10 +358,11 @@ func (k Keeper) calcInAmtGivenOut(
swapFee sdk.Dec,
priceLimit sdk.Dec,
poolId uint64,
) (tokenIn, tokenOut sdk.Coin, updatedTick sdk.Int, updatedLiquidity, updatedSqrtPrice sdk.Dec, err error) {
) (writeCtx func(), tokenIn, tokenOut sdk.Coin, updatedTick sdk.Int, updatedLiquidity, updatedSqrtPrice sdk.Dec, err error) {
ctx, writeCtx = ctx.CacheContext()
p, err := k.getPoolById(ctx, poolId)
if err != nil {
return sdk.Coin{}, sdk.Coin{}, sdk.Int{}, sdk.Dec{}, sdk.Dec{}, err
return writeCtx, sdk.Coin{}, sdk.Coin{}, sdk.Int{}, sdk.Dec{}, sdk.Dec{}, err
}
asset0 := p.GetToken0()
asset1 := p.GetToken1()
@@ -375,7 +380,7 @@ func (k Keeper) calcInAmtGivenOut(
// take provided price limit and turn this into a sqrt price limit since formulas use sqrtPrice
sqrtPriceLimit, err := priceLimit.ApproxSqrt()
if err != nil {
return sdk.Coin{}, sdk.Coin{}, sdk.Int{}, sdk.Dec{}, sdk.Dec{}, fmt.Errorf("issue calculating square root of price limit")
return writeCtx, sdk.Coin{}, sdk.Coin{}, sdk.Int{}, sdk.Dec{}, sdk.Dec{}, fmt.Errorf("issue calculating square root of price limit")
}

// set the swap strategy
@@ -385,20 +390,20 @@ func (k Keeper) calcInAmtGivenOut(
curSqrtPrice := p.GetCurrentSqrtPrice()

if err := swapStrategy.ValidatePriceLimit(sqrtPriceLimit, curSqrtPrice); err != nil {
return sdk.Coin{}, sdk.Coin{}, sdk.Int{}, sdk.Dec{}, sdk.Dec{}, err
return writeCtx, sdk.Coin{}, sdk.Coin{}, sdk.Int{}, sdk.Dec{}, sdk.Dec{}, err
}

// check that the specified tokenOut matches one of the assets in the specified pool
if desiredTokenOut.Denom != asset0 && desiredTokenOut.Denom != asset1 {
return sdk.Coin{}, sdk.Coin{}, sdk.Int{}, sdk.Dec{}, sdk.Dec{}, types.TokenOutDenomNotInPoolError{TokenOutDenom: desiredTokenOut.Denom}
return writeCtx, sdk.Coin{}, sdk.Coin{}, sdk.Int{}, sdk.Dec{}, sdk.Dec{}, types.TokenOutDenomNotInPoolError{TokenOutDenom: desiredTokenOut.Denom}
}
// check that the specified tokenIn matches one of the assets in the specified pool
if tokenInDenom != asset0 && tokenInDenom != asset1 {
return sdk.Coin{}, sdk.Coin{}, sdk.Int{}, sdk.Dec{}, sdk.Dec{}, types.TokenInDenomNotInPoolError{TokenInDenom: tokenInDenom}
return writeCtx, sdk.Coin{}, sdk.Coin{}, sdk.Int{}, sdk.Dec{}, sdk.Dec{}, types.TokenInDenomNotInPoolError{TokenInDenom: tokenInDenom}
}
// check that token in and token out are different denominations
if desiredTokenOut.Denom == tokenInDenom {
return sdk.Coin{}, sdk.Coin{}, sdk.Int{}, sdk.Dec{}, sdk.Dec{}, types.DenomDuplicatedError{TokenInDenom: tokenInDenom, TokenOutDenom: desiredTokenOut.Denom}
return writeCtx, sdk.Coin{}, sdk.Coin{}, sdk.Int{}, sdk.Dec{}, sdk.Dec{}, types.DenomDuplicatedError{TokenInDenom: tokenInDenom, TokenOutDenom: desiredTokenOut.Denom}
}

// initialize swap state with the following parameters:
@@ -423,19 +428,19 @@ func (k Keeper) calcInAmtGivenOut(
// if no ticks are initialized (no users have created liquidity positions) then we return an error
nextTick, ok := swapStrategy.NextInitializedTick(ctx, poolId, swapState.tick.Int64())
if !ok {
return sdk.Coin{}, sdk.Coin{}, sdk.Int{}, sdk.Dec{}, sdk.Dec{}, fmt.Errorf("there are no more ticks initialized to fill the swap")
return writeCtx, sdk.Coin{}, sdk.Coin{}, sdk.Int{}, sdk.Dec{}, sdk.Dec{}, fmt.Errorf("there are no more ticks initialized to fill the swap")
}

// utilizing the next initialized tick, we find the corresponding nextPrice (the target price)
nextPrice, err := math.TickToPrice(nextTick, p.GetPrecisionFactorAtPriceOne())
if err != nil {
return sdk.Coin{}, sdk.Coin{}, sdk.Int{}, sdk.Dec{}, sdk.Dec{}, fmt.Errorf("could not convert next tick (%v) to nextPrice", nextTick)
return writeCtx, sdk.Coin{}, sdk.Coin{}, sdk.Int{}, sdk.Dec{}, sdk.Dec{}, fmt.Errorf("could not convert next tick (%v) to nextSqrtPrice", nextTick)
}

// transform to sqrtPrice
nextSqrtPrice, err := nextPrice.ApproxSqrt()
if err != nil {
return sdk.Coin{}, sdk.Coin{}, sdk.Int{}, sdk.Dec{}, sdk.Dec{}, fmt.Errorf("could not convert nextPrice (%v) to nextSqrtPrice", nextPrice)
return writeCtx, sdk.Coin{}, sdk.Coin{}, sdk.Int{}, sdk.Dec{}, sdk.Dec{}, fmt.Errorf("could not convert next tick (%v) to nextSqrtPrice", nextSqrtPrice)
}

// utilizing the bucket's liquidity and knowing the price target, we calculate the how much tokenOut we get from the tokenIn
@@ -458,7 +463,7 @@ func (k Keeper) calcInAmtGivenOut(
// retrieve the liquidity held in the next closest initialized tick
liquidityNet, err := k.crossTick(ctx, p.GetId(), nextTick.Int64())
if err != nil {
return sdk.Coin{}, sdk.Coin{}, sdk.Int{}, sdk.Dec{}, sdk.Dec{}, err
return writeCtx, sdk.Coin{}, sdk.Coin{}, sdk.Int{}, sdk.Dec{}, sdk.Dec{}, err
}
liquidityNet = swapStrategy.SetLiquidityDeltaSign(liquidityNet)
// update the swapState's liquidity with the new tick's liquidity
@@ -472,7 +477,7 @@ func (k Keeper) calcInAmtGivenOut(
// beginning of this iteration, we set the swapState tick to the corresponding tick of the sqrtPrice calculated from computeSwapStep
swapState.tick, err = math.PriceToTick(sqrtPrice.Power(2), p.GetPrecisionFactorAtPriceOne())
if err != nil {
return sdk.Coin{}, sdk.Coin{}, sdk.Int{}, sdk.Dec{}, sdk.Dec{}, err
return writeCtx, sdk.Coin{}, sdk.Coin{}, sdk.Int{}, sdk.Dec{}, sdk.Dec{}, err
}
}

@@ -485,7 +490,7 @@ func (k Keeper) calcInAmtGivenOut(
tokenOut = sdk.NewCoin(desiredTokenOut.Denom, amt1)
}

return tokenIn, tokenOut, swapState.tick, swapState.liquidity, swapState.sqrtPrice, nil
return writeCtx, tokenIn, tokenOut, swapState.tick, swapState.liquidity, swapState.sqrtPrice, nil
}

// applySwap persists the swap state and charges gas fees.
32 changes: 28 additions & 4 deletions x/concentrated-liquidity/swaps_test.go
Original file line number Diff line number Diff line change
@@ -503,9 +503,11 @@ func (s *KeeperTestSuite) TestCalcAndSwapOutAmtGivenIn() {
// add positions
test.addPositions(s.Ctx, pool.GetId())

poolBeforeCalc, err := s.App.ConcentratedLiquidityKeeper.GetPoolById(s.Ctx, pool.GetId())
s.Require().NoError(err)

// perform calc
// TODO: Add sqrtPrice check
tokenIn, tokenOut, updatedTick, updatedLiquidity, _, err := s.App.ConcentratedLiquidityKeeper.CalcOutAmtGivenInInternal(
_, tokenIn, tokenOut, updatedTick, updatedLiquidity, _, err := s.App.ConcentratedLiquidityKeeper.CalcOutAmtGivenInInternal(
s.Ctx,
test.tokenIn, test.tokenOutDenom,
DefaultZeroSwapFee, test.priceLimit, pool.GetId())
@@ -546,6 +548,16 @@ func (s *KeeperTestSuite) TestCalcAndSwapOutAmtGivenIn() {
// check that liquidity is what we expected
expectedLiquidity := math.GetLiquidityFromAmounts(DefaultCurrSqrtPrice, lowerSqrtPrice, upperSqrtPrice, test.poolLiqAmount0, test.poolLiqAmount1)
s.Require().Equal(expectedLiquidity.String(), updatedLiquidity.String())

// check that the pool has not been modified after performing calc
poolAfterCalc, err := s.App.ConcentratedLiquidityKeeper.GetPoolById(s.Ctx, pool.GetId())
s.Require().NoError(err)

s.Require().Equal(poolBeforeCalc.GetCurrentSqrtPrice(), poolAfterCalc.GetCurrentSqrtPrice())
s.Require().Equal(poolBeforeCalc.GetCurrentTick(), poolAfterCalc.GetCurrentTick())
s.Require().Equal(poolBeforeCalc.GetTotalShares(), poolAfterCalc.GetTotalShares())
s.Require().Equal(poolBeforeCalc.GetLiquidity(), poolAfterCalc.GetLiquidity())
s.Require().Equal(poolBeforeCalc.GetTickSpacing(), poolAfterCalc.GetTickSpacing())
}

// perform swap
@@ -957,9 +969,11 @@ func (s *KeeperTestSuite) TestCalcAndSwapInAmtGivenOut() {
// add positions
test.addPositions(s.Ctx, pool.GetId())

poolBeforeCalc, err := s.App.ConcentratedLiquidityKeeper.GetPoolById(s.Ctx, pool.GetId())
s.Require().NoError(err)

// perform calc
// TODO: Add sqrtPrice check
tokenIn, tokenOut, updatedTick, updatedLiquidity, _, err := s.App.ConcentratedLiquidityKeeper.CalcInAmtGivenOutInternal(
_, tokenIn, tokenOut, updatedTick, updatedLiquidity, _, err := s.App.ConcentratedLiquidityKeeper.CalcInAmtGivenOutInternal(
s.Ctx,
test.tokenOut, test.tokenInDenom,
DefaultZeroSwapFee, test.priceLimit, pool.GetId())
@@ -1000,6 +1014,16 @@ func (s *KeeperTestSuite) TestCalcAndSwapInAmtGivenOut() {
// check that liquidity is what we expected
expectedLiquidity := math.GetLiquidityFromAmounts(DefaultCurrSqrtPrice, lowerSqrtPrice, upperSqrtPrice, test.poolLiqAmount0, test.poolLiqAmount1)
s.Require().Equal(expectedLiquidity.String(), updatedLiquidity.String())

// // check that the pool has not been modified after performing calc
mattverse marked this conversation as resolved.
Show resolved Hide resolved
poolAfterCalc, err := s.App.ConcentratedLiquidityKeeper.GetPoolById(s.Ctx, pool.GetId())
s.Require().NoError(err)

s.Require().Equal(poolBeforeCalc.GetCurrentSqrtPrice(), poolAfterCalc.GetCurrentSqrtPrice())
s.Require().Equal(poolBeforeCalc.GetCurrentTick(), poolAfterCalc.GetCurrentTick())
s.Require().Equal(poolBeforeCalc.GetTotalShares(), poolAfterCalc.GetTotalShares())
s.Require().Equal(poolBeforeCalc.GetLiquidity(), poolAfterCalc.GetLiquidity())
s.Require().Equal(poolBeforeCalc.GetTickSpacing(), poolAfterCalc.GetTickSpacing())
}

// perform swap