Skip to content Search Apps Documentation Source Content File Folder Download Copy Actions State String Boolean Number Struct Map Slice Pointer Function Closure Reference Nil Package Type Interface Unknown

type.gno

6.59 Kb · 188 lines
  1package pool
  2
  3import (
  4	"gno.land/p/gnoswap/gnsmath/v1"
  5	i256 "gno.land/p/gnoswap/int256/v1"
  6	u256 "gno.land/p/gnoswap/uint256/v1"
  7
  8	pl "gno.land/r/gnoswap/pool"
  9)
 10
 11// ModifyPositionParams repersents the parameters for modifying a liquidity position.
 12// This structure is used internally both `Mint` and `Burn` operation to manage
 13// the liquidity positions.
 14type ModifyPositionParams struct {
 15	// owner is the address that owns the position
 16	owner address
 17
 18	// tickLower and atickUpper define the price range
 19	// The actual price range is calculated as 1.0001^tick
 20	// This allows for precision in price range while using integer math.
 21
 22	tickLower int32 // lower tick of the position
 23	tickUpper int32 // upper tick of the position
 24
 25	// liquidityDelta represents the change in liquidity
 26	// Positive for minting, negative for burning
 27	liquidityDelta *i256.Int
 28}
 29
 30// newModifyPositionParams creates a new `ModifyPositionParams` instance.
 31// This is used to preare parameters for the `modifyPosition` function,
 32// which handles both minting and burning of liquidity positions.
 33//
 34// Parameters:
 35//   - owner: address that will own (or owns) the position
 36//   - tickLower: lower tick bound of the position
 37//   - tickUpper: upper tick bound of the position
 38//   - liquidityDelta: amount of liquidity to add (positive) or remove (negative)
 39//
 40// The tick parameters represent prices as powers of 1.0001:
 41// - actual_price = 1.0001^tick
 42// - For example, tick = 100 means price = 1.0001^100
 43//
 44// Returns:
 45//   - ModifyPositionParams: a new instance of ModifyPositionParams
 46func newModifyPositionParams(
 47	owner address,
 48	tickLower int32,
 49	tickUpper int32,
 50	liquidityDelta *i256.Int,
 51) ModifyPositionParams {
 52	return ModifyPositionParams{
 53		owner:          owner,
 54		tickLower:      tickLower,
 55		tickUpper:      tickUpper,
 56		liquidityDelta: liquidityDelta,
 57	}
 58}
 59
 60// SwapCache holds immutable swap-start inputs and oracle cumulatives that are
 61// populated lazily when the swap first crosses an initialized tick.
 62type SwapCache struct {
 63	feeProtocol                       uint8      // protocol fee for the input token
 64	liquidityStart                    *u256.Uint // liquidity at the beginning of the swap
 65	blockTimestamp                    int64      // current block timestamp
 66	tickCumulative                    int64      // current tick accumulator value
 67	secondsPerLiquidityCumulativeX128 *u256.Uint // current seconds per liquidity accumulator
 68	computedLatestObservation         bool       // whether we've computed the above accumulators
 69	slot0Start                        pl.Slot0   // immutable Slot0 snapshot captured at swap start
 70	readOnly                          bool       // quote without tick accounting or hooks
 71}
 72
 73func newSwapCache(
 74	feeProtocol uint8,
 75	liquidityStart *u256.Uint,
 76	blockTimestamp int64,
 77	slot0Start pl.Slot0,
 78) *SwapCache {
 79	return &SwapCache{
 80		feeProtocol:                       feeProtocol,
 81		liquidityStart:                    liquidityStart,
 82		blockTimestamp:                    blockTimestamp,
 83		tickCumulative:                    0,
 84		secondsPerLiquidityCumulativeX128: u256.Zero(),
 85		computedLatestObservation:         false,
 86		slot0Start:                        slot0Start.Clone(),
 87	}
 88}
 89
 90// SwapState tracks the changing values during a swap.
 91// This type helps manage the state transitions that occur as the swap progresses
 92// across different price ranges.
 93type SwapState struct {
 94	amountSpecifiedRemaining *i256.Int  // amount remaining to be swapped in/out of the input/output token
 95	amountCalculated         *i256.Int  // amount already swapped out/in of the output/input token
 96	sqrtPriceX96             *u256.Uint // current sqrt(price)
 97	tick                     int32      // tick associated with the current sqrt(price)
 98	feeGrowthGlobalX128      *u256.Uint // global fee growth of the input token
 99	protocolFee              *u256.Uint // amount of input token paid as protocol fee
100	liquidity                *u256.Uint // current liquidity in range
101}
102
103func newSwapState(
104	amountSpecifiedRemaining *i256.Int,
105	feeGrowthGlobalX128 *u256.Uint,
106	liquidity *u256.Uint,
107	slot0 pl.Slot0,
108) SwapState {
109	return SwapState{
110		amountSpecifiedRemaining: amountSpecifiedRemaining,
111		amountCalculated:         i256.Zero(),
112		sqrtPriceX96:             slot0.SqrtPriceX96(),
113		tick:                     slot0.Tick(),
114		feeGrowthGlobalX128:      feeGrowthGlobalX128,
115		protocolFee:              u256.Zero(),
116		liquidity:                liquidity,
117	}
118}
119
120func (s *SwapState) setSqrtPriceX96(sqrtPriceX96 *u256.Uint) {
121	s.sqrtPriceX96 = sqrtPriceX96.Clone()
122}
123
124func (s *SwapState) setTick(tick int32) {
125	s.tick = tick
126}
127
128func (s *SwapState) setFeeGrowthGlobalX128(feeGrowthGlobalX128 *u256.Uint) {
129	s.feeGrowthGlobalX128 = feeGrowthGlobalX128
130}
131
132func (s *SwapState) setProtocolFee(fee *u256.Uint) {
133	s.protocolFee = fee
134}
135
136// StepComputations holds intermediate values used during a single step of a swap.
137// Each step represents movement from the current tick to the next initialized tick
138// or the target price, whichever comes first.
139type StepComputations struct {
140	sqrtPriceStartX96 *u256.Uint // price at the beginning of the step
141	tickNext          int32      // next tick to swap to from the current tick in the swap direction
142	initialized       bool       // whether tickNext is initialized
143	sqrtPriceNextX96  *u256.Uint // sqrt(price) for the next tick (token1/token0) Q96
144	amountIn          *u256.Uint // how much being swapped in this step
145	amountOut         *u256.Uint // how much is being swapped out in this step
146	feeAmount         *u256.Uint // how much fee is being paid in this step
147}
148
149// init initializes the computation for a single swap step
150func (step *StepComputations) initSwapStep(state SwapState, p *pl.Pool, zeroForOne bool) {
151	step.sqrtPriceStartX96 = state.sqrtPriceX96
152	step.tickNext, step.initialized = tickBitmapNextInitializedTickWithInOneWord(
153		p,
154		state.tick,
155		p.TickSpacing(),
156		zeroForOne,
157	)
158
159	// prevent overshoot the min/max tick
160	step.clampTickNext()
161
162	// get the price for the next tick
163	step.sqrtPriceNextX96 = gnsmath.TickMathGetSqrtRatioAtTick(step.tickNext)
164}
165
166// clampTickNext ensures that `tickNext` stays within the min, max tick boundaries
167// as the tick bitmap is not aware of these bounds
168func (step *StepComputations) clampTickNext() {
169	if step.tickNext < MIN_TICK {
170		step.tickNext = MIN_TICK
171	} else if step.tickNext > MAX_TICK {
172		step.tickNext = MAX_TICK
173	}
174}
175
176func newPool(poolInfo *poolCreateConfig) *pl.Pool {
177	tick := gnsmath.TickMathGetTickAtSqrtRatio(poolInfo.SqrtPriceX96())
178
179	return pl.NewPool(
180		poolInfo.Token0Path(),
181		poolInfo.Token1Path(),
182		poolInfo.Fee(),
183		poolInfo.SqrtPriceX96(),
184		poolInfo.TickSpacing(),
185		tick,
186		poolInfo.slot0FeeProtocol,
187	)
188}