Skip to content

Commit

Permalink
[CL] Change calcOutAmtGivenIn and calcInAmtGivenOut to be non-mut…
Browse files Browse the repository at this point in the history
…ative (#3910)

* Use CacheCtx for Calc method

* WIP: used cachedctx

* Revert "WIP: used cachedctx"

This reverts commit da1c910.

* WIP:Write

* Return WriteCtx for all calc methods

* Update x/concentrated-liquidity/swaps_test.go

* Update x/concentrated-liquidity/swaps.go

Co-authored-by: Roman <roman@osmosis.team>

* Update x/concentrated-liquidity/swaps.go

Co-authored-by: Roman <roman@osmosis.team>

* Add simple spec for calcInAmtGivenOut

* Fix lint

Co-authored-by: Roman <roman@osmosis.team>
  • Loading branch information
mattverse and p0mvn authored Jan 12, 2023
1 parent 9cc4599 commit fa47daa
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 41 deletions.
4 changes: 2 additions & 2 deletions x/concentrated-liquidity/export_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}

Expand Down
4 changes: 2 additions & 2 deletions x/concentrated-liquidity/internal/math/tick.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ func TicksToPrice(lowerTick, upperTick int64, exponentAtPriceOne sdk.Int) (sdk.D
}

// TickToPrice returns the price given the following two arguments:
// - tickIndex: the tick index to calculate the price for
// - exponentAtPriceOne: the value of the exponent (and therefore the precision) at which the starting price of 1 is set
// - tickIndex: the tick index to calculate the price for
// - exponentAtPriceOne: the value of the exponent (and therefore the precision) at which the starting price of 1 is set
//
// If tickIndex is zero, the function returns sdk.OneDec().
func TickToPrice(tickIndex, exponentAtPriceOne sdk.Int) (price sdk.Dec, err error) {
Expand Down
7 changes: 4 additions & 3 deletions x/concentrated-liquidity/model/pool.go
Original file line number Diff line number Diff line change
Expand Up @@ -173,9 +173,10 @@ func (p *Pool) UpdateLiquidityIfActivePosition(ctx sdk.Context, lowerTick, upper
// lower and upper ticks.
// There are 3 possible cases:
// -The position is active ( lowerTick <= p.CurrentTick < upperTick).
// * The provided liquidity is distributed in both tokens.
// * Actual amounts might differ from desired because we recalculate them from liquidity delta and sqrt price.
// the calculations lead to amounts being off. // TODO: confirm logic is correct
// - The provided liquidity is distributed in both tokens.
// - Actual amounts might differ from desired because we recalculate them from liquidity delta and sqrt price.
// the calculations lead to amounts being off. // TODO: confirm logic is correct
//
// - Current tick is below the position ( p.CurrentTick < lowerTick).
// - The provided liquidity is distributed in token0 only.
//
Expand Down
77 changes: 47 additions & 30 deletions x/concentrated-liquidity/swaps.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,11 +138,16 @@ 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
}

// N.B. making the call below ensures that any mutations done inside calcOutAmtGivenIn
// are written to store. If this call were skipped, calcOutAmtGivenIn would be non-mutative.
// An example of a store write done in calcOutAmtGivenIn is updating ticks as we cross them.
writeCtx()

err = k.applySwap(ctx, tokenIn, tokenOut, poolId, newLiquidity, newCurrentTick, newSqrtPrice)
if err != nil {
return sdk.Coin{}, sdk.Coin{}, sdk.Int{}, sdk.Dec{}, sdk.Dec{}, err
Expand All @@ -159,11 +164,16 @@ 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
}

// N.B. making the call below ensures that any mutations done inside calcInAmtGivenOut
// are written to store. If this call were skipped, calcInAmtGivenOut would be non-mutative.
// An example of a store write done in calcInAmtGivenOut is updating ticks as we cross them.
writeCtx()

err = k.applySwap(ctx, tokenIn, tokenOut, poolId, newLiquidity, newCurrentTick, newSqrtPrice)
if err != nil {
return sdk.Coin{}, sdk.Coin{}, sdk.Int{}, sdk.Dec{}, sdk.Dec{}, err
Expand All @@ -179,7 +189,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
}
Expand All @@ -193,7 +203,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
}
Expand All @@ -203,16 +213,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.
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()
Expand All @@ -231,7 +243,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
Expand All @@ -240,20 +252,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:
Expand All @@ -280,19 +292,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
Expand All @@ -317,7 +329,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
Expand All @@ -331,7 +343,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
}
}
}
Expand All @@ -344,20 +356,25 @@ 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
}

// calcInAmtGivenOut calculates tokens to be swapped in given the desired token out 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 calcInAmtGivenOut 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.
func (k Keeper) calcInAmtGivenOut(
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) {
) (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()
Expand All @@ -375,7 +392,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
Expand All @@ -385,20 +402,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:
Expand All @@ -423,19 +440,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
Expand All @@ -458,7 +475,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
Expand All @@ -472,7 +489,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
}
}

Expand All @@ -485,7 +502,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.
Expand Down
Loading

0 comments on commit fa47daa

Please sign in to comment.