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}