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

getter.gno

28.11 Kb · 903 lines
  1package pool
  2
  3import (
  4	"errors"
  5	"time"
  6
  7	u256 "gno.land/p/gnoswap/uint256/v1"
  8	rotree "gno.land/p/nt/bptree/rotree/v0"
  9	ufmt "gno.land/p/nt/ufmt/v0"
 10	pl "gno.land/r/gnoswap/pool"
 11)
 12
 13// GetPoolPath generates a unique pool path string based on the token paths and fee tier.
 14// Parameters:
 15//   - token0Path: first token contract path; pool paths canonicalize token order.
 16//   - token1Path: second token contract path; pool paths canonicalize token order.
 17//   - fee: fee tier encoded in the pool identifier.
 18//
 19// Returns:
 20//   - poolPath: canonical token0:token1:fee pool identifier.
 21func GetPoolPath(token0Path, token1Path string, fee uint32) string {
 22	return pl.GetPoolPath(token0Path, token1Path, fee)
 23}
 24
 25// GetFeeAmountTickSpacing retrieves the tick spacing associated with a given fee amount.
 26// Parameters:
 27//   - fee: fee tier whose configured tick spacing is requested.
 28//
 29// Returns:
 30//   - spacing: configured signed tick interval for fee.
 31//   - err: nil when fee is configured; an unsupported-fee error otherwise.
 32func (i *poolV1) GetFeeAmountTickSpacing(fee uint32) (spacing int32, err error) {
 33	feeAmountTickSpacing := i.store.GetFeeAmountTickSpacing()
 34
 35	spacing, exist := feeAmountTickSpacing[fee]
 36	if !exist {
 37		return 0, errors.New(newErrorWithDetail(
 38			errUnsupportedFeeTier,
 39			ufmt.Sprintf("expected fee(%d) to be one of %d, %d, %d, %d", fee, FeeTier100, FeeTier500, FeeTier3000, FeeTier10000),
 40		))
 41	}
 42
 43	return spacing, nil
 44}
 45
 46// Parameters:
 47//   - poolPath: canonical pool identifier to look up.
 48//
 49// Returns:
 50//   - token0Path: canonical token0 contract path stored in the pool.
 51//   - err: nil when the pool exists; the pool lookup error otherwise.
 52func (i *poolV1) GetToken0Path(poolPath string) (string, error) {
 53	pool, err := i.getPool(poolPath)
 54	if err != nil {
 55		return "", err
 56	}
 57	return pool.Token0Path(), nil
 58}
 59
 60// Parameters:
 61//   - poolPath: canonical pool identifier to look up.
 62//
 63// Returns:
 64//   - token1Path: canonical token1 contract path stored in the pool.
 65//   - err: nil when the pool exists; the pool lookup error otherwise.
 66func (i *poolV1) GetToken1Path(poolPath string) (string, error) {
 67	pool, err := i.getPool(poolPath)
 68	if err != nil {
 69		return "", err
 70	}
 71	return pool.Token1Path(), nil
 72}
 73
 74// Parameters:
 75//   - poolPath: canonical pool identifier to look up.
 76//
 77// Returns:
 78//   - fee: configured fee tier stored in the pool.
 79//   - err: nil when the pool exists; the pool lookup error otherwise.
 80func (i *poolV1) GetFee(poolPath string) (uint32, error) {
 81	pool, err := i.getPool(poolPath)
 82	if err != nil {
 83		return 0, err
 84	}
 85	return pool.Fee(), nil
 86}
 87
 88// Parameters:
 89//   - poolPath: canonical pool identifier to look up.
 90//
 91// Returns:
 92//   - balanceToken0: pool-held token0 balance in the token's smallest unit.
 93//   - err: nil when the pool exists; the pool lookup error otherwise.
 94func (i *poolV1) GetBalanceToken0(poolPath string) (int64, error) {
 95	pool, err := i.getPool(poolPath)
 96	if err != nil {
 97		return 0, err
 98	}
 99	return pool.BalanceToken0(), nil
100}
101
102// Parameters:
103//   - poolPath: canonical pool identifier to look up.
104//
105// Returns:
106//   - balanceToken1: pool-held token1 balance in the token's smallest unit.
107//   - err: nil when the pool exists; the pool lookup error otherwise.
108func (i *poolV1) GetBalanceToken1(poolPath string) (int64, error) {
109	pool, err := i.getPool(poolPath)
110	if err != nil {
111		return 0, err
112	}
113	return pool.BalanceToken1(), nil
114}
115
116// Parameters:
117//   - poolPath: canonical pool identifier to look up.
118//
119// Returns:
120//   - tickSpacing: configured signed interval between usable initialized ticks.
121//   - err: nil when the pool exists; the pool lookup error otherwise.
122func (i *poolV1) GetTickSpacing(poolPath string) (int32, error) {
123	pool, err := i.getPool(poolPath)
124	if err != nil {
125		return 0, err
126	}
127	return pool.TickSpacing(), nil
128}
129
130// Parameters:
131//   - poolPath: canonical pool identifier to look up.
132//
133// Returns:
134//   - maxLiquidity: decimal representation of the maximum liquidity permitted
135//     at one tick for the pool's tick spacing.
136//   - err: nil when the pool exists; the pool lookup error otherwise.
137func (i *poolV1) GetMaxLiquidityPerTick(poolPath string) (string, error) {
138	pool, err := i.getPool(poolPath)
139	if err != nil {
140		return "", err
141	}
142	return calculateMaxLiquidityPerTick(pool.TickSpacing()).ToString(), nil
143}
144
145// Parameters:
146//   - poolPath: canonical pool identifier to look up.
147//
148// Returns:
149//   - feeProtocol: packed token0/token1 protocol-fee denominator configuration
150//     stored in slot0.
151//   - err: nil when the pool exists; the pool lookup error otherwise.
152func (i *poolV1) GetSlot0FeeProtocol(poolPath string) (uint8, error) {
153	pool, err := i.getPool(poolPath)
154	if err != nil {
155		return 0, err
156	}
157	return pool.Slot0FeeProtocol(), nil
158}
159
160// Parameters:
161//   - poolPath: canonical pool identifier to look up.
162//
163// Returns:
164//   - unlocked: true when the pool's slot0 reentrancy lock is open.
165//   - err: nil when the pool exists; the pool lookup error otherwise.
166func (i *poolV1) GetSlot0Unlocked(poolPath string) (bool, error) {
167	pool, err := i.getPool(poolPath)
168	if err != nil {
169		return false, err
170	}
171	return pool.Slot0Unlocked(), nil
172}
173
174// Parameters:
175//   - poolPath: canonical pool identifier to look up.
176//
177// Returns:
178//   - slot0: current pool price, tick, observation, and lock metadata; panics
179//     when poolPath does not identify an existing pool.
180func (i *poolV1) GetSlot0(poolPath string) pl.Slot0 {
181	return i.mustGetPool(poolPath).Slot0()
182}
183
184// Parameters:
185//   - poolPath: canonical pool identifier containing the observation ring.
186//   - index: observation slot index; in-range unwritten slots return a default
187//     observation, while indices at or above maxObservationCardinality error.
188//
189// Returns:
190//   - observation: observation stored at index, or the default zero observation
191//     for an in-range slot that has never been written.
192//   - err: nil for a valid pool and index; a pool, observation, or range error
193//     otherwise.
194func (i *poolV1) GetObservationAt(poolPath string, index uint16) (pl.Observation, error) {
195	if _, err := i.getPool(poolPath); err != nil {
196		return pl.DefaultObservation(), err
197	}
198
199	// Uniswap's observations(uint256) getter is backed by a fixed-size array:
200	// an in-range but never-written slot returns the zero observation, while an
201	// out-of-range index reverts.
202	if index >= maxObservationCardinality {
203		return pl.DefaultObservation(), makeErrorWithDetails(errDataNotFound, ufmt.Sprintf("observation index %d out of range", index))
204	}
205
206	observations, err := i.getObservations(poolPath)
207	if err != nil {
208		return pl.DefaultObservation(), err
209	}
210
211	observation, ok := observations.Get(index)
212	if !ok {
213		return pl.DefaultObservation(), nil
214	}
215
216	return observation, nil
217}
218
219// Observe returns the tick and seconds-per-liquidity cumulatives for each
220// requested lookback. It reads the current block timestamp once and never
221// writes an observation, matching Uniswap V3's view-only observe call.
222// Parameters:
223//   - poolPath: canonical pool identifier whose observation history is queried.
224//   - secondsAgos: lookback durations in seconds; one cumulative pair is
225//     produced for each entry, with zero meaning the current cumulative value.
226//
227// Returns:
228//   - tickCumulatives: cumulative tick values aligned by index with secondsAgos.
229//   - secondsPerLiquidityCumulativeX128s: cumulative seconds-per-liquidity
230//     values aligned with secondsAgos and scaled by 2^128 as decimal strings.
231//   - err: nil when every requested lookback can be resolved; an observation
232//     history, epoch, cardinality, or interpolation error otherwise.
233func (i *poolV1) Observe(poolPath string, secondsAgos []uint32) ([]int64, []string, error) {
234	pool, err := i.getPool(poolPath)
235	if err != nil {
236		return nil, nil, err
237	}
238
239	observations, err := i.getObservations(poolPath)
240	if err != nil {
241		return nil, nil, err
242	}
243
244	slot0 := pool.Slot0()
245	return observe(
246		observations,
247		time.Now().Unix(),
248		secondsAgos,
249		slot0.Tick(),
250		slot0.ObservationIndex(),
251		pool.Liquidity(),
252		slot0.ObservationCardinality(),
253	)
254}
255
256// SnapshotCumulativesInside returns the oracle accumulators that accrued while
257// the pool price was inside [tickLower, tickUpper).
258// Parameters:
259//   - poolPath: canonical pool identifier whose oracle accumulators are queried.
260//   - tickLower: inclusive lower tick boundary of the range.
261//   - tickUpper: exclusive upper tick boundary of the range.
262//
263// Returns:
264//   - tickCumulativeInside: cumulative tick value accrued while price was
265//     inside [tickLower, tickUpper).
266//   - secondsPerLiquidityInsideX128: seconds-per-liquidity accumulator accrued
267//     inside the range, scaled by 2^128.
268//   - secondsInside: number of seconds during which price was inside the range.
269//   - err: nil when bounds, boundary ticks, and observations are valid; the
270//     corresponding validation or observation error otherwise.
271func (i *poolV1) SnapshotCumulativesInside(
272	poolPath string,
273	tickLower int32,
274	tickUpper int32,
275) (int64, *u256.Uint, uint32, error) {
276	pool, err := i.getPool(poolPath)
277	if err != nil {
278		return 0, nil, 0, err
279	}
280
281	observations, err := i.getObservations(poolPath)
282	if err != nil {
283		return 0, nil, 0, err
284	}
285
286	return snapshotCumulativesInside(pool, observations, tickLower, tickUpper)
287}
288
289// Parameters:
290//   - poolPath: canonical pool identifier to look up.
291//
292// Returns:
293//   - feeGrowthGlobal0X128: global token0 fee-growth accumulator scaled by 2^128.
294//   - err: nil when the pool exists; the pool lookup error otherwise.
295func (i *poolV1) GetFeeGrowthGlobal0X128(poolPath string) (*u256.Uint, error) {
296	pool, err := i.getPool(poolPath)
297	if err != nil {
298		return nil, err
299	}
300	return pool.FeeGrowthGlobal0X128(), nil
301}
302
303// Parameters:
304//   - poolPath: canonical pool identifier to look up.
305//
306// Returns:
307//   - feeGrowthGlobal1X128: global token1 fee-growth accumulator scaled by 2^128.
308//   - err: nil when the pool exists; the pool lookup error otherwise.
309func (i *poolV1) GetFeeGrowthGlobal1X128(poolPath string) (*u256.Uint, error) {
310	pool, err := i.getPool(poolPath)
311	if err != nil {
312		return nil, err
313	}
314	return pool.FeeGrowthGlobal1X128(), nil
315}
316
317// Parameters:
318//   - poolPath: canonical pool identifier to look up.
319//
320// Returns:
321//   - protocolFeesToken0: protocol fees accrued in token0's smallest unit.
322//   - err: nil when the pool exists; the pool lookup error otherwise.
323func (i *poolV1) GetProtocolFeesToken0(poolPath string) (int64, error) {
324	pool, err := i.getPool(poolPath)
325	if err != nil {
326		return 0, err
327	}
328	return pool.ProtocolFeesToken0(), nil
329}
330
331// Parameters:
332//   - poolPath: canonical pool identifier to look up.
333//
334// Returns:
335//   - protocolFeesToken1: protocol fees accrued in token1's smallest unit.
336//   - err: nil when the pool exists; the pool lookup error otherwise.
337func (i *poolV1) GetProtocolFeesToken1(poolPath string) (int64, error) {
338	pool, err := i.getPool(poolPath)
339	if err != nil {
340		return 0, err
341	}
342	return pool.ProtocolFeesToken1(), nil
343}
344
345// Parameters:
346//   - poolPath: canonical pool identifier to look up.
347//
348// Returns:
349//   - liquidity: current active pool liquidity as a u256 integer.
350//   - err: nil when the pool exists; the pool lookup error otherwise.
351func (i *poolV1) GetLiquidity(poolPath string) (*u256.Uint, error) {
352	pool, err := i.getPool(poolPath)
353	if err != nil {
354		return nil, err
355	}
356	return pool.Liquidity(), nil
357}
358
359// Parameters:
360//   - poolPath: canonical pool identifier containing the position.
361//   - key: position key identifying its lower and upper tick range.
362//
363// Returns:
364//   - position: pointer to a copy of the stored position information; panics
365//     when the pool or position is absent or has an unexpected type.
366func (i *poolV1) MustGetPosition(poolPath, key string) *pl.PositionInfo {
367	pool := i.mustGetPool(poolPath)
368
369	positions := pool.Positions()
370
371	result := positions.Get(key)
372	if result == nil {
373		panic(newErrorWithDetail(
374			errDataNotFound,
375			ufmt.Sprintf("expected position(%s) to exist", key),
376		))
377	}
378
379	position, ok := result.(pl.PositionInfo)
380	if !ok {
381		panic("failed to cast position to PositionInfo")
382	}
383
384	return &position
385}
386
387// Parameters:
388//   - poolPath: canonical pool identifier containing the position.
389//   - key: position key identifying its lower and upper tick range.
390//
391// Returns:
392//   - feeGrowthInside0LastX128: token0 fee-growth-inside value last accounted
393//     for the position, encoded as a decimal integer scaled by 2^128.
394//   - err: nil when pool and position exist; the lookup error otherwise.
395func (i *poolV1) GetPositionFeeGrowthInside0LastX128(poolPath, key string) (string, error) {
396	pool, err := i.getPool(poolPath)
397	if err != nil {
398		return "", err
399	}
400	position, err := pool.GetPosition(key)
401	if err != nil {
402		return "", err
403	}
404	return position.FeeGrowthInside0LastX128(), nil
405}
406
407// Parameters:
408//   - poolPath: canonical pool identifier containing the position.
409//   - key: position key identifying its lower and upper tick range.
410//
411// Returns:
412//   - feeGrowthInside1LastX128: token1 fee-growth-inside value last accounted
413//     for the position, encoded as a decimal integer scaled by 2^128.
414//   - err: nil when pool and position exist; the lookup error otherwise.
415func (i *poolV1) GetPositionFeeGrowthInside1LastX128(poolPath, key string) (string, error) {
416	pool, err := i.getPool(poolPath)
417	if err != nil {
418		return "", err
419	}
420	position, err := pool.GetPosition(key)
421	if err != nil {
422		return "", err
423	}
424	return position.FeeGrowthInside1LastX128(), nil
425}
426
427// Parameters:
428//   - poolPath: canonical pool identifier containing the position.
429//   - key: position key identifying its lower and upper tick range.
430//
431// Returns:
432//   - tokensOwed0: token0 fees owed to the position in token0's smallest unit.
433//   - err: nil when pool and position exist; the lookup error otherwise.
434func (i *poolV1) GetPositionTokensOwed0(poolPath, key string) (int64, error) {
435	pool, err := i.getPool(poolPath)
436	if err != nil {
437		return 0, err
438	}
439	position, err := pool.GetPosition(key)
440	if err != nil {
441		return 0, err
442	}
443	return position.TokensOwed0(), nil
444}
445
446// Parameters:
447//   - poolPath: canonical pool identifier containing the position.
448//   - key: position key identifying its lower and upper tick range.
449//
450// Returns:
451//   - tokensOwed1: token1 fees owed to the position in token1's smallest unit.
452//   - err: nil when pool and position exist; the lookup error otherwise.
453func (i *poolV1) GetPositionTokensOwed1(poolPath, key string) (int64, error) {
454	pool, err := i.getPool(poolPath)
455	if err != nil {
456		return 0, err
457	}
458	position, err := pool.GetPosition(key)
459	if err != nil {
460		return 0, err
461	}
462	return position.TokensOwed1(), nil
463}
464
465// Parameters:
466//   - poolPath: canonical pool identifier containing the tick.
467//   - tick: signed tick index whose gross liquidity is requested.
468//
469// Returns:
470//   - liquidityGross: total liquidity referencing the tick, encoded as a decimal
471//     integer string.
472//   - err: nil when pool and tick exist; the lookup error otherwise.
473func (i *poolV1) GetTickLiquidityGross(poolPath string, tick int32) (string, error) {
474	pool, err := i.getPool(poolPath)
475	if err != nil {
476		return "", err
477	}
478
479	tickInfo, err := pool.GetTick(tick)
480	if err != nil {
481		return "", err
482	}
483	return tickInfo.LiquidityGross(), nil
484}
485
486// Parameters:
487//   - poolPath: canonical pool identifier containing the tick.
488//   - tick: signed tick index whose net liquidity change is requested.
489//
490// Returns:
491//   - liquidityNet: signed net liquidity change applied when crossing the tick,
492//     encoded as a decimal integer string.
493//   - err: nil when pool and tick exist; the lookup error otherwise.
494func (i *poolV1) GetTickLiquidityNet(poolPath string, tick int32) (string, error) {
495	pool, err := i.getPool(poolPath)
496	if err != nil {
497		return "", err
498	}
499
500	tickInfo, err := pool.GetTick(tick)
501	if err != nil {
502		return "", err
503	}
504	return tickInfo.LiquidityNet(), nil
505}
506
507// Parameters:
508//   - poolPath: canonical pool identifier containing the tick.
509//   - tick: signed tick index whose token0 fee-growth-outside value is requested.
510//
511// Returns:
512//   - feeGrowthOutside0X128: token0 fee-growth-outside accumulator scaled by
513//     2^128, encoded as a decimal string.
514//   - err: nil when pool and tick exist; the lookup error otherwise.
515func (i *poolV1) GetTickFeeGrowthOutside0X128(poolPath string, tick int32) (string, error) {
516	pool, err := i.getPool(poolPath)
517	if err != nil {
518		return "", err
519	}
520
521	tickInfo, err := pool.GetTick(tick)
522	if err != nil {
523		return "", err
524	}
525	return tickInfo.FeeGrowthOutside0X128(), nil
526}
527
528// Parameters:
529//   - poolPath: canonical pool identifier containing the tick.
530//   - tick: signed tick index whose token1 fee-growth-outside value is requested.
531//
532// Returns:
533//   - feeGrowthOutside1X128: token1 fee-growth-outside accumulator scaled by
534//     2^128, encoded as a decimal string.
535//   - err: nil when pool and tick exist; the lookup error otherwise.
536func (i *poolV1) GetTickFeeGrowthOutside1X128(poolPath string, tick int32) (string, error) {
537	pool, err := i.getPool(poolPath)
538	if err != nil {
539		return "", err
540	}
541
542	tickInfo, err := pool.GetTick(tick)
543	if err != nil {
544		return "", err
545	}
546	return tickInfo.FeeGrowthOutside1X128(), nil
547}
548
549// Parameters:
550//   - poolPath: canonical pool identifier containing the tick.
551//   - tick: signed tick index whose token fee-growth-outside values are requested.
552//
553// Returns:
554//   - feeGrowthOutside0X128: token0 fee-growth-outside accumulator scaled by 2^128,
555//     encoded as a decimal string.
556//   - feeGrowthOutside1X128: token1 fee-growth-outside accumulator scaled by 2^128,
557//     encoded as a decimal string.
558//   - err: nil when pool and tick exist; the lookup error otherwise.
559func (i *poolV1) GetTickFeeGrowthOutsideX128(poolPath string, tick int32) (string, string, error) {
560	pool, err := i.getPool(poolPath)
561	if err != nil {
562		return "", "", err
563	}
564
565	tickInfo, err := pool.GetTick(tick)
566	if err != nil {
567		return "", "", err
568	}
569
570	return tickInfo.FeeGrowthOutside0X128(), tickInfo.FeeGrowthOutside1X128(), nil
571}
572
573// Parameters:
574//   - poolPath: canonical pool identifier containing the tick.
575//   - tick: signed tick index whose cumulative tick-outside value is requested.
576//
577// Returns:
578//   - tickCumulativeOutside: cumulative tick value recorded outside the tick's
579//     active range.
580//   - err: nil when pool and tick exist; the lookup error otherwise.
581func (i *poolV1) GetTickCumulativeOutside(poolPath string, tick int32) (int64, error) {
582	pool, err := i.getPool(poolPath)
583	if err != nil {
584		return 0, err
585	}
586
587	tickInfo, err := pool.GetTick(tick)
588	if err != nil {
589		return 0, err
590	}
591	return tickInfo.TickCumulativeOutside(), nil
592}
593
594// Parameters:
595//   - poolPath: canonical pool identifier containing the tick.
596//   - tick: signed tick index whose seconds-per-liquidity accumulator is
597//     requested.
598//
599// Returns:
600//   - secondsPerLiquidityOutsideX128: seconds-per-liquidity-outside accumulator
601//     encoded as a decimal integer scaled by 2^128.
602//   - err: nil when pool and tick exist; the lookup error otherwise.
603func (i *poolV1) GetTickSecondsPerLiquidityOutsideX128(poolPath string, tick int32) (string, error) {
604	pool, err := i.getPool(poolPath)
605	if err != nil {
606		return "", err
607	}
608
609	tickInfo, err := pool.GetTick(tick)
610	if err != nil {
611		return "", err
612	}
613	return tickInfo.SecondsPerLiquidityOutsideX128(), nil
614}
615
616// Parameters:
617//   - poolPath: canonical pool identifier containing the tick.
618//   - tick: signed tick index whose seconds-outside accumulator is requested.
619//
620// Returns:
621//   - secondsOutside: seconds elapsed outside the tick's side of the active
622//     range, as recorded by the pool.
623//   - err: nil when pool and tick exist; the lookup error otherwise.
624func (i *poolV1) GetTickSecondsOutside(poolPath string, tick int32) (uint32, error) {
625	pool, err := i.getPool(poolPath)
626	if err != nil {
627		return 0, err
628	}
629
630	tickInfo, err := pool.GetTick(tick)
631	if err != nil {
632		return 0, err
633	}
634	return tickInfo.SecondsOutside(), nil
635}
636
637// Parameters:
638//   - poolPath: canonical pool identifier containing the tick.
639//   - tick: signed tick index whose initialization flag is requested.
640//
641// Returns:
642//   - initialized: true when the tick has been initialized in the pool.
643//   - err: nil when pool and tick can be read; the lookup error otherwise.
644func (i *poolV1) GetTickInitialized(poolPath string, tick int32) (bool, error) {
645	pool, err := i.getPool(poolPath)
646	if err != nil {
647		return false, err
648	}
649
650	tickInfo, err := pool.GetTick(tick)
651	if err != nil {
652		return false, err
653	}
654	return tickInfo.Initialized(), nil
655}
656
657// Parameters:
658//   - poolPath: canonical pool identifier to look up.
659//
660// Returns:
661//   - tick: current signed slot0 tick.
662//   - err: nil when the pool exists; the pool lookup error otherwise.
663func (i *poolV1) GetSlot0Tick(poolPath string) (int32, error) {
664	pool, err := i.getPool(poolPath)
665	if err != nil {
666		return 0, err
667	}
668	return pool.Slot0Tick(), nil
669}
670
671// Parameters:
672//   - poolPath: canonical pool identifier to look up.
673//
674// Returns:
675//   - sqrtPriceX96: current square-root price as a u256 Q64.96 integer.
676//   - err: nil when the pool exists; the pool lookup error otherwise.
677func (i *poolV1) GetSlot0SqrtPriceX96(poolPath string) (*u256.Uint, error) {
678	pool, err := i.getPool(poolPath)
679	if err != nil {
680		return nil, err
681	}
682	return pool.Slot0SqrtPriceX96(), nil
683}
684
685// Parameters:
686//   - poolPath: canonical pool identifier to look up.
687//
688// Returns:
689//   - feeGrowthGlobal0X128: global token0 fee-growth accumulator scaled by 2^128.
690//   - feeGrowthGlobal1X128: global token1 fee-growth accumulator scaled by 2^128.
691//   - err: nil when the pool exists; the pool lookup error otherwise.
692func (i *poolV1) GetFeeGrowthGlobalX128(poolPath string) (*u256.Uint, *u256.Uint, error) {
693	pool, err := i.getPool(poolPath)
694	if err != nil {
695		return nil, nil, err
696	}
697	return pool.FeeGrowthGlobal0X128(), pool.FeeGrowthGlobal1X128(), nil
698}
699
700// Parameters:
701//   - poolPath: canonical pool identifier containing the position.
702//   - key: position key identifying its lower and upper tick range.
703//
704// Returns:
705//   - feeGrowthInside0LastX128: token0 fee-growth-inside value last accounted
706//     for the position, encoded as a decimal integer scaled by 2^128.
707//   - feeGrowthInside1LastX128: token1 fee-growth-inside value last accounted
708//     for the position, encoded as a decimal integer scaled by 2^128.
709//   - err: nil when pool and position exist; the lookup error otherwise.
710func (i *poolV1) GetPositionFeeGrowthInsideLastX128(poolPath, key string) (string, string, error) {
711	pool, err := i.getPool(poolPath)
712	if err != nil {
713		return "", "", err
714	}
715	position, err := pool.GetPosition(key)
716	if err != nil {
717		return "", "", err
718	}
719	return position.FeeGrowthInside0LastX128(),
720		position.FeeGrowthInside1LastX128(), nil
721}
722
723// Parameters:
724//   - poolPath: canonical pool identifier containing the position.
725//   - key: position key identifying its lower and upper tick range.
726//
727// Returns:
728//   - liquidity: position liquidity encoded as a decimal integer string.
729//   - err: nil when pool and position exist; the lookup error otherwise.
730func (i *poolV1) GetPositionLiquidity(poolPath, key string) (string, error) {
731	pool, err := i.getPool(poolPath)
732	if err != nil {
733		return "", err
734	}
735	position, err := pool.GetPosition(key)
736	if err != nil {
737		return "", err
738	}
739	return position.Liquidity(), nil
740}
741
742// Parameters:
743//   - poolPath: canonical pool identifier whose existence is checked.
744//
745// Returns:
746//   - exists: true when the pool tree contains poolPath.
747func (i *poolV1) ExistsPoolPath(poolPath string) bool {
748	pools := i.store.GetPools()
749	return pools.Has(poolPath)
750}
751
752// Returns:
753//   - poolCreationFee: configured pool-creation charge in the chain's smallest
754//     currency unit.
755func (i *poolV1) GetPoolCreationFee() int64 {
756	return i.store.GetPoolCreationFee()
757}
758
759// Returns:
760//   - withdrawalFeeBPS: configured withdrawal fee in basis points, where 100
761//     basis points equals one percent.
762func (i *poolV1) GetWithdrawalFee() uint64 {
763	return i.store.GetWithdrawalFeeBPS()
764}
765
766// OracleConsult returns the time-weighted average price for a pool over a specified period.
767//
768// Parameters:
769//   - poolPath: canonical pool identifier whose observations are consulted.
770//   - secondsAgo: lookback duration in seconds for the time-weighted query.
771//
772// Returns:
773//   - arithmeticMeanTick: arithmetic mean tick over the requested lookback.
774//   - harmonicMeanLiquidity: harmonic mean active liquidity as a u256 integer.
775//   - err: nil when the pool history covers secondsAgo; an observation or
776//     lookback error otherwise.
777func (i *poolV1) OracleConsult(poolPath string, secondsAgo uint32) (int32, *u256.Uint, error) {
778	pool, err := i.getPool(poolPath)
779	if err != nil {
780		return 0, nil, err
781	}
782
783	observations, err := i.getObservations(poolPath)
784	if err != nil {
785		return 0, nil, err
786	}
787
788	tick, liquidity, err := oracleConsult(pool, observations, secondsAgo)
789	if err != nil {
790		return 0, nil, err
791	}
792
793	return tick, liquidity, nil
794}
795
796// GetPools returns a read-only view of every pool, keyed by pool path.
797// Callers paginate it themselves through IterateByOffset.
798// Returns:
799//   - pools: read-only tree keyed by canonical pool path; entries are exposed
800//     through safe read-only wrappers and callers paginate the tree themselves.
801func (i *poolV1) GetPools() *rotree.ReadOnlyTree {
802	return rotree.Wrap(i.store.GetPools(), clonePoolEntry)
803}
804
805// GetFeeAmountTickSpacings returns all fee tier to tick spacing mappings.
806// Returns:
807//   - feeAmountTickSpacings: copy of the configured fee-tier to tick-spacing
808//     mapping.
809func (i *poolV1) GetFeeAmountTickSpacings() map[uint32]int32 {
810	return i.store.GetFeeAmountTickSpacing()
811}
812
813// GetPoolPositions returns a read-only view of a pool's positions, keyed by
814// position key. Callers paginate it themselves through IterateByOffset.
815// nil is returned when the pool does not exist.
816// Parameters:
817//   - poolPath: canonical pool identifier whose positions are exposed.
818//
819// Returns:
820//   - positions: read-only tree keyed by position key, or nil when poolPath
821//     does not identify an existing pool.
822func (i *poolV1) GetPoolPositions(poolPath string) *rotree.ReadOnlyTree {
823	pool, err := i.getPool(poolPath)
824	if err != nil {
825		return nil
826	}
827
828	// makeEntrySafeFn is a function that makes an entry safe to read.
829	// But PositionInfo is immutable, so we can just return the entry as is.
830	return rotree.Wrap(pool.Positions(), nil)
831}
832
833// Tick enumeration
834
835// GetInitializedTicksInRange returns initialized ticks within the given range.
836// Parameters:
837//   - poolPath: canonical pool identifier whose initialized ticks are listed.
838//   - tickLower: inclusive lower tick bound for enumeration.
839//   - tickUpper: inclusive upper tick bound for enumeration.
840//
841// Returns:
842//   - ticks: initialized tick indices in the requested inclusive range, in
843//     encoded tree order; empty when no ticks are initialized there.
844//   - err: nil when the pool exists; the pool lookup error otherwise.
845func (i *poolV1) GetInitializedTicksInRange(poolPath string, tickLower, tickUpper int32) ([]int32, error) {
846	pool, err := i.getPool(poolPath)
847	if err != nil {
848		return nil, err
849	}
850
851	ticks := make([]int32, 0)
852
853	pool.IterateTicks(tickLower, tickUpper, func(tick int32, _ pl.TickInfo) bool {
854		ticks = append(ticks, tick)
855		return false
856	})
857
858	return ticks, nil
859}
860
861// Structure getters
862
863// GetTickInfo returns the tick info for a given tick.
864// Parameters:
865//   - poolPath: canonical pool identifier containing the tick.
866//   - tick: signed tick index whose full state is requested.
867//
868// Returns:
869//   - tickInfo: initialized state and outside accumulators for tick.
870//   - err: nil when the pool and tick can be read; the corresponding lookup
871//     error otherwise.
872func (i *poolV1) GetTickInfo(poolPath string, tick int32) (pl.TickInfo, error) {
873	pool, err := i.getPool(poolPath)
874	if err != nil {
875		return pl.NewTickInfo(), err
876	}
877
878	return pool.GetTick(tick)
879}
880
881// GetTickBitmaps returns the tick bitmap for a given word position.
882// Parameters:
883//   - poolPath: canonical pool identifier whose bitmap map is queried.
884//   - wordPos: signed bitmap-word position to retrieve.
885//
886// Returns:
887//   - bitmap: decimal string encoding the initialized-tick bitmap word at
888//     wordPos.
889//   - err: nil when the pool and bitmap word exist; the pool lookup or missing
890//     bitmap error otherwise.
891func (i *poolV1) GetTickBitmaps(poolPath string, wordPos int16) (string, error) {
892	pool, err := i.getPool(poolPath)
893	if err != nil {
894		return "", err
895	}
896
897	tickBitmap, ok := pool.TickBitmaps()[wordPos]
898	if !ok {
899		return "", ufmt.Errorf("tick bitmap %d not found", wordPos)
900	}
901
902	return tickBitmap, nil
903}