Search Apps Documentation Source Content File Folder Download Copy Actions Download

type.gno

6.24 Kb · 183 lines
  1package v1
  2
  3import (
  4	"gno.land/p/gnoswap/gnsmath"
  5	i256 "gno.land/p/gnoswap/int256"
  6	u256 "gno.land/p/gnoswap/uint256"
  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 data that remains constant throughout a swap.
 61type SwapCache struct {
 62	feeProtocol                       uint8      // protocol fee for the input token
 63	liquidityStart                    *u256.Uint // liquidity at the beginning of the swap
 64	blockTimestamp                    int64      // current block timestamp
 65	tickCumulative                    int64      // current tick accumulator value
 66	secondsPerLiquidityCumulativeX128 *u256.Uint // current seconds per liquidity accumulator
 67	computedLatestObservation         bool       // whether we've computed the above accumulators
 68}
 69
 70func newSwapCache(
 71	feeProtocol uint8,
 72	liquidityStart *u256.Uint,
 73	blockTimestamp int64,
 74) *SwapCache {
 75	return &SwapCache{
 76		feeProtocol:                       feeProtocol,
 77		liquidityStart:                    liquidityStart,
 78		blockTimestamp:                    blockTimestamp,
 79		tickCumulative:                    0,
 80		secondsPerLiquidityCumulativeX128: u256.Zero(),
 81		computedLatestObservation:         false,
 82	}
 83}
 84
 85// SwapState tracks the changing values during a swap.
 86// This type helps manage the state transitions that occur as the swap progresses
 87// across different price ranges.
 88type SwapState struct {
 89	amountSpecifiedRemaining *i256.Int  // amount remaining to be swapped in/out of the input/output token
 90	amountCalculated         *i256.Int  // amount already swapped out/in of the output/input token
 91	sqrtPriceX96             *u256.Uint // current sqrt(price)
 92	tick                     int32      // tick associated with the current sqrt(price)
 93	feeGrowthGlobalX128      *u256.Uint // global fee growth of the input token
 94	protocolFee              *u256.Uint // amount of input token paid as protocol fee
 95	liquidity                *u256.Uint // current liquidity in range
 96}
 97
 98func newSwapState(
 99	amountSpecifiedRemaining *i256.Int,
100	feeGrowthGlobalX128 *u256.Uint,
101	liquidity *u256.Uint,
102	slot0 pl.Slot0,
103) SwapState {
104	return SwapState{
105		amountSpecifiedRemaining: amountSpecifiedRemaining,
106		amountCalculated:         i256.Zero(),
107		sqrtPriceX96:             slot0.SqrtPriceX96(),
108		tick:                     slot0.Tick(),
109		feeGrowthGlobalX128:      feeGrowthGlobalX128,
110		protocolFee:              u256.Zero(),
111		liquidity:                liquidity,
112	}
113}
114
115func (s *SwapState) setSqrtPriceX96(sqrtPriceX96 *u256.Uint) {
116	s.sqrtPriceX96 = sqrtPriceX96.Clone()
117}
118
119func (s *SwapState) setTick(tick int32) {
120	s.tick = tick
121}
122
123func (s *SwapState) setFeeGrowthGlobalX128(feeGrowthGlobalX128 *u256.Uint) {
124	s.feeGrowthGlobalX128 = feeGrowthGlobalX128
125}
126
127func (s *SwapState) setProtocolFee(fee *u256.Uint) {
128	s.protocolFee = fee
129}
130
131// StepComputations holds intermediate values used during a single step of a swap.
132// Each step represents movement from the current tick to the next initialized tick
133// or the target price, whichever comes first.
134type StepComputations struct {
135	sqrtPriceStartX96 *u256.Uint // price at the beginning of the step
136	tickNext          int32      // next tick to swap to from the current tick in the swap direction
137	initialized       bool       // whether tickNext is initialized
138	sqrtPriceNextX96  *u256.Uint // sqrt(price) for the next tick (token1/token0) Q96
139	amountIn          *u256.Uint // how much being swapped in this step
140	amountOut         *u256.Uint // how much is being swapped out in this step
141	feeAmount         *u256.Uint // how much fee is being paid in this step
142}
143
144// init initializes the computation for a single swap step
145func (step *StepComputations) initSwapStep(state SwapState, p *pl.Pool, zeroForOne bool) {
146	step.sqrtPriceStartX96 = state.sqrtPriceX96
147	step.tickNext, step.initialized = tickBitmapNextInitializedTickWithInOneWord(
148		p,
149		state.tick,
150		p.TickSpacing(),
151		zeroForOne,
152	)
153
154	// prevent overshoot the min/max tick
155	step.clampTickNext()
156
157	// get the price for the next tick
158	step.sqrtPriceNextX96 = gnsmath.TickMathGetSqrtRatioAtTick(step.tickNext)
159}
160
161// clampTickNext ensures that `tickNext` stays within the min, max tick boundaries
162// as the tick bitmap is not aware of these bounds
163func (step *StepComputations) clampTickNext() {
164	if step.tickNext < MIN_TICK {
165		step.tickNext = MIN_TICK
166	} else if step.tickNext > MAX_TICK {
167		step.tickNext = MAX_TICK
168	}
169}
170
171func newPool(poolInfo *poolCreateConfig) *pl.Pool {
172	tick := gnsmath.TickMathGetTickAtSqrtRatio(poolInfo.SqrtPriceX96())
173
174	return pl.NewPool(
175		poolInfo.Token0Path(),
176		poolInfo.Token1Path(),
177		poolInfo.Fee(),
178		poolInfo.SqrtPriceX96(),
179		poolInfo.TickSpacing(),
180		tick,
181		poolInfo.slot0FeeProtocol,
182	)
183}