Skip to content

Commit

Permalink
feat(CL): Support Next Tick (#3079)
Browse files Browse the repository at this point in the history
* bez: updates

* bez: updates

* bez: updates

* bez: updates

* bez: updates

* bez: updates

* bez: updates

* bez: updates

* bez: updates

* bez: updates

* bez: updates

* bez: updates

* Update x/concentrated-liquidity/tick_test.go

Co-authored-by: Matt, Park <45252226+mattverse@users.noreply.github.com>

* Update x/concentrated-liquidity/tick.go

Co-authored-by: Matt, Park <45252226+mattverse@users.noreply.github.com>

* bez: updates

* bez: updates

* bez: updates

* bez: updates

* bez: updates

* bez: updates

* bez: updates

* Fix lint

Co-authored-by: Matt, Park <45252226+mattverse@users.noreply.github.com>
Co-authored-by: mattverse <mattpark1028@gmail.com>
  • Loading branch information
3 people authored Oct 22, 2022
1 parent 1c1ad09 commit 331b8f4
Show file tree
Hide file tree
Showing 8 changed files with 301 additions and 118 deletions.
105 changes: 31 additions & 74 deletions concentratedPool.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 14 additions & 4 deletions lp.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,17 @@ import (
types "github.com/osmosis-labs/osmosis/v12/x/concentrated-liquidity/types"
)

func (k Keeper) Mint(ctx sdk.Context, poolId uint64, owner sdk.AccAddress, liquidityIn sdk.Int, lowerTick sdk.Int, upperTick sdk.Int) (amtDenom0, amtDenom1 sdk.Int, err error) {
// ensure that lower tick is always smaller than upper tick
if lowerTick.GTE(types.MaxTick) || lowerTick.LT(types.MinTick) || upperTick.GT(types.MaxTick) {
return sdk.Int{}, sdk.Int{}, fmt.Errorf("validation fail")
func (k Keeper) Mint(ctx sdk.Context, poolId uint64, owner sdk.AccAddress, liquidityIn sdk.Int, lowerTick, upperTick int64) (amtDenom0, amtDenom1 sdk.Int, err error) {
// ensure types.MinTick <= lowerTick < types.MaxTick
// TODO (bez): Add unit tests.
if lowerTick < types.MinTick || lowerTick >= types.MaxTick {
return sdk.Int{}, sdk.Int{}, fmt.Errorf("invalid lower tick: %d", lowerTick)
}

// ensure types.MaxTick < upperTick <= types.MinTick
// TODO (bez): Add unit tests.
if upperTick > types.MaxTick || upperTick <= types.MinTick {
return sdk.Int{}, sdk.Int{}, fmt.Errorf("invalid upper tick: %d", upperTick)
}

if liquidityIn.IsZero() {
Expand Down Expand Up @@ -44,12 +51,15 @@ func (k Keeper) Mint(ctx sdk.Context, poolId uint64, owner sdk.AccAddress, liqui
func (k Keeper) JoinPoolNoSwap(ctx sdk.Context, tokensIn sdk.Coins, swapFee sdk.Dec) (numShares sdk.Int, err error) {
return sdk.Int{}, nil
}

func (k Keeper) CalcJoinPoolShares(ctx sdk.Context, tokensIn sdk.Coins, swapFee sdk.Dec) (numShares sdk.Int, newLiquidity sdk.Coins, err error) {
return sdk.Int{}, sdk.Coins{}, nil
}

func (k Keeper) CalcJoinPoolNoSwapShares(ctx sdk.Context, tokensIn sdk.Coins, swapFee sdk.Dec) (numShares sdk.Int, newLiquidity sdk.Coins, err error) {
return sdk.Int{}, sdk.Coins{}, nil
}

func (k Keeper) ExitPool(ctx sdk.Context, numShares sdk.Int, exitFee sdk.Dec) (exitedCoins sdk.Coins, err error) {
return sdk.Coins{}, nil
}
Expand Down
4 changes: 2 additions & 2 deletions lp_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ func (s *KeeperTestSuite) TestMint() {
// denom1: usdc
poolId := uint64(1)
currentTick := sdk.NewInt(85176)
lowerTick := sdk.NewInt(84222)
upperTick := sdk.NewInt(86129)
lowerTick := int64(84222)
upperTick := int64(86129)
liquidity, ok := sdk.NewIntFromString("1517882343751509868544")
s.Require().True(ok)
currentSqrtP, ok := sdk.NewIntFromString("5602277097478614198912276234240")
Expand Down
21 changes: 12 additions & 9 deletions position.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,10 @@ import (
// nolint: unused
func (k Keeper) updatePositionWithLiquidity(ctx sdk.Context,
poolId uint64,
owner string,
lowerTick, upperTick sdk.Int,
liquidityDelta sdk.Int) {
owner sdk.AccAddress,
lowerTick, upperTick int64,
liquidityDelta sdk.Int,
) {
position := k.getPosition(ctx, poolId, owner, lowerTick, upperTick)

liquidityBefore := position.Liquidity
Expand All @@ -23,22 +24,24 @@ func (k Keeper) updatePositionWithLiquidity(ctx sdk.Context,
}

// nolint: unused
func (k Keeper) getPosition(ctx sdk.Context, poolId uint64, owner string, lowerTick, upperTick sdk.Int) Position {
func (k Keeper) getPosition(ctx sdk.Context, poolId uint64, owner sdk.AccAddress, lowerTick, upperTick int64) Position {
store := ctx.KVStore(k.storeKey)
position := Position{}

var position Position
key := types.KeyPosition(poolId, owner, lowerTick, upperTick)
osmoutils.MustGet(store, key, &position)

return position
}

// nolint: unused
func (k Keeper) setPosition(ctx sdk.Context,
poolId uint64,
owner string,
lowerTick, upperTick sdk.Int,
position Position) {
owner sdk.AccAddress,
lowerTick, upperTick int64,
position Position,
) {
store := ctx.KVStore(k.storeKey)

key := types.KeyPosition(poolId, owner, lowerTick, upperTick)
osmoutils.MustSet(store, key, &position)
}
69 changes: 60 additions & 9 deletions tick.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
package concentrated_liquidity

import (
fmt "fmt"

"github.com/cosmos/cosmos-sdk/store/prefix"
sdk "github.com/cosmos/cosmos-sdk/types"
db "github.com/tendermint/tm-db"

"github.com/osmosis-labs/osmosis/v12/osmomath"
"github.com/osmosis-labs/osmosis/v12/osmoutils"
types "github.com/osmosis-labs/osmosis/v12/x/concentrated-liquidity/types"
)

func (k Keeper) getSqrtRatioAtTick(tickIndex sdk.Int) (sdk.Dec, error) {
sqrtRatio, err := sdk.NewDecWithPrec(10001, 4).Power(tickIndex.Uint64()).ApproxSqrt()
func (k Keeper) getSqrtRatioAtTick(tickIndex int64) (sdk.Dec, error) {
sqrtRatio, err := sdk.NewDecWithPrec(10001, 4).Power(uint64(tickIndex)).ApproxSqrt()
if err != nil {
return sdk.Dec{}, nil
}
Expand All @@ -21,30 +26,76 @@ func (k Keeper) getSqrtRatioAtTick(tickIndex sdk.Int) (sdk.Dec, error) {
// return sdk.Int{}
// }

func (k Keeper) UpdateTickWithNewLiquidity(ctx sdk.Context, poolId uint64, tickIndex sdk.Int, liquidityDelta sdk.Int) {
func (k Keeper) UpdateTickWithNewLiquidity(ctx sdk.Context, poolId uint64, tickIndex int64, liquidityDelta sdk.Int) {
tickInfo := k.getTickInfo(ctx, poolId, tickIndex)

liquidityBefore := tickInfo.Liquidity
liquidityAfter := liquidityBefore.Add(liquidityDelta)

tickInfo.Liquidity = liquidityAfter

if liquidityBefore == sdk.ZeroInt() {
tickInfo.Initialized = true
k.setTickInfo(ctx, poolId, tickIndex, tickInfo)
}

// NextInitializedTick returns the next initialized tick index based on the
// current or provided tick index. If no initialized tick exists, <0, false>
// will be returned. The lte argument indicates if we need to find the next
// initialized tick to the left or right of the current tick index, where true
// indicates searching to the left.
func (k Keeper) NextInitializedTick(ctx sdk.Context, poolId uint64, tickIndex int64, lte bool) (next int64, initialized bool) {
store := ctx.KVStore(k.storeKey)

// Construct a prefix store with a prefix of <TickPrefix | poolID>, allowing
// us to retrieve the next initialized tick without having to scan all ticks.
prefixBz := types.KeyTickPrefix(poolId)
prefixStore := prefix.NewStore(store, prefixBz)

var startKey []byte
if lte {
// When looking to the left of the current tick, we need to evaluate the
// current tick as well. The end cursor for reverse iteration is non-inclusive
// so must add one and handle overflow.
startKey = types.TickIndexToBytes(osmomath.Max(tickIndex, tickIndex+1))
} else {
startKey = types.TickIndexToBytes(tickIndex)
}

k.setTickInfo(ctx, poolId, tickIndex, tickInfo)
var iter db.Iterator
if lte {
iter = prefixStore.ReverseIterator(nil, startKey)
} else {
iter = prefixStore.Iterator(startKey, nil)
}

defer iter.Close()

for ; iter.Valid(); iter.Next() {
// Since, we constructed our prefix store with <TickPrefix | poolID>, the
// key is the encoding of a tick index.
tick, err := types.TickIndexFromBytes(iter.Key())
if err != nil {
panic(fmt.Errorf("invalid tick index (%s): %v", string(iter.Key()), err))
}

if !lte && tick > tickIndex {
return tick, true
}
if lte && tick <= tickIndex {
return tick, true
}
}

return 0, false
}

func (k Keeper) getTickInfo(ctx sdk.Context, poolId uint64, tickIndex sdk.Int) TickInfo {
func (k Keeper) getTickInfo(ctx sdk.Context, poolId uint64, tickIndex int64) TickInfo {
store := ctx.KVStore(k.storeKey)
tickInfo := TickInfo{}
key := types.KeyTick(poolId, tickIndex)
osmoutils.MustGet(store, key, &tickInfo)
return tickInfo
}

func (k Keeper) setTickInfo(ctx sdk.Context, poolId uint64, tickIndex sdk.Int, tickInfo TickInfo) {
func (k Keeper) setTickInfo(ctx sdk.Context, poolId uint64, tickIndex int64, tickInfo TickInfo) {
store := ctx.KVStore(k.storeKey)
key := types.KeyTick(poolId, tickIndex)
osmoutils.MustSet(store, key, &tickInfo)
Expand Down
Loading

0 comments on commit 331b8f4

Please sign in to comment.