-
Notifications
You must be signed in to change notification settings - Fork 4
Description
add a public function to the util package for helping users of the sdk convert a partial list of sorted tick data into valid sorted tick data for the base pool
we need this because sometimes users query pool state using a quote data fetcher lens contract that only returns some of the tick data and the min/max tick range that it searched for initialized ticks
the min/max tick are not necessarily multiples of tick spacing, so make sure to account for that by rounding to the next valid tick (down for min tick and up for max tick)
the function should take a sorted tick array, min/max tick searched, tick spacing, liquidity, current tick, and return a new vector that has additional entries that ensure the array of sorted ticks is valid (all liquidity deltas add up to zero, current liquidity is the sum of liquidity deltas from MIN_TICK to current active tick index)
in addition, add a helper constructor from_partial_data to the basepool that takes this partial data and forms the arguments to call the other basepool constructor
for reference there are two implementations that handle adding an additional tick entry from the quote data fetcher:
func (s *BasePoolState) AddLiquidityCutoffs() {
currentLiquidity := new(big.Int)
belowActiveTick := true
var activeTickIndex int
// The liquidity added/removed by out-of-range initialized ticks (i.e. lower than the min checked tick number)
liquidityDeltaMin := new(big.Int)
for i, tick := range s.SortedTicks {
if belowActiveTick && s.ActiveTick < tick.Number {
belowActiveTick = false
activeTickIndex = i - 1
liquidityDeltaMin.Sub(s.Liquidity, currentLiquidity)
// We now need to switch to tracking the liquidity that needs to be cut off at the max checked tick number, therefore reset to the actual liquidity
currentLiquidity.Set(s.Liquidity)
}
currentLiquidity.Add(currentLiquidity, tick.LiquidityDelta)
}
if belowActiveTick {
activeTickIndex = len(s.SortedTicks) - 1
liquidityDeltaMin.Sub(s.Liquidity, currentLiquidity)
currentLiquidity.Set(s.Liquidity)
}
s.ActiveTickIndex = activeTickIndex
s.UpdateTick(s.TickBounds[0], liquidityDeltaMin, false, true)
s.UpdateTick(s.TickBounds[1], currentLiquidity, true, true)
} export function addLiquidityCutoffs(state: BasePoolState.Object) {
const { sortedTicks, liquidity, activeTick } = state;
let activeTickIndex = undefined;
let currentLiquidity = 0n;
// The liquidity added/removed by out-of-range initialized ticks (i.e. lower than minCheckedTickNumber)
let liquidityDeltaMin = 0n;
for (let i = 0; i < sortedTicks.length; i++) {
const tick = sortedTicks[i];
if (typeof activeTickIndex === 'undefined' && activeTick < tick.number) {
activeTickIndex = i === 0 ? null : i - 1;
liquidityDeltaMin = liquidity - currentLiquidity;
// We now need to switch to tracking the liquidity that needs to be cut off at maxCheckedTickNumber, therefore reset to the actual liquidity
currentLiquidity = liquidity;
}
currentLiquidity += tick.liquidityDelta;
}
if (typeof activeTickIndex === 'undefined') {
activeTickIndex = sortedTicks.length > 0 ? sortedTicks.length - 1 : null;
liquidityDeltaMin = liquidity - currentLiquidity;
currentLiquidity = liquidity;
}
state.activeTickIndex = activeTickIndex;
BasePoolState.updateTick(
state,
state.checkedTicksBounds[0],
liquidityDeltaMin,
false,
true,
);
BasePoolState.updateTick(
state,
state.checkedTicksBounds[1],
currentLiquidity,
true,
true,
);
}