Search Apps Documentation Source Content File Folder Download Copy Actions Download 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}