getter.gno
6.31 Kb · 183 lines
1package v1
2
3import (
4 "strconv"
5
6 u256 "gno.land/p/gnoswap/uint256"
7 ufmt "gno.land/p/nt/ufmt/v0"
8
9 pl "gno.land/r/gnoswap/pool"
10 "gno.land/r/gnoswap/position"
11)
12
13// MustGetPosition returns a position for a given position ID.
14// panics if position doesn't exist
15func (p *positionV1) mustGetPosition(positionId uint64) *position.Position {
16 pos, exist := p.GetPosition(positionId)
17 if !exist {
18 panic(newErrorWithDetail(
19 errPositionDoesNotExist,
20 ufmt.Sprintf("position with position ID(%d) doesn't exist", positionId),
21 ))
22 }
23
24 return &pos
25}
26
27// GetPositionCount returns the total number of positions.
28func (p *positionV1) GetPositionCount() int {
29 return p.store.GetPositions().Size()
30}
31
32// GetPositionIDs returns a paginated list of position IDs.
33func (p *positionV1) GetPositionIDs(offset, count int) []uint64 {
34 positions := p.store.GetPositions()
35 positionIDs := make([]uint64, 0)
36
37 positions.IterateByOffset(offset, count, func(key string, _ any) bool {
38 id, err := strconv.ParseUint(key, 10, 64)
39 if err != nil {
40 return false
41 }
42
43 positionIDs = append(positionIDs, id)
44
45 return false
46 })
47
48 return positionIDs
49}
50
51// GetPosition returns a position for a given position ID.
52// Returns false if position doesn't exist
53func (p *positionV1) GetPosition(id uint64) (position.Position, bool) {
54 return p.store.GetPosition(id)
55}
56
57// ExistPosition checks if a position exists for a given position ID
58func (p *positionV1) ExistPosition(positionId uint64) bool {
59 return p.store.HasPosition(positionId)
60}
61
62func (p *positionV1) IsBurned(positionId uint64) bool {
63 return p.mustGetPosition(positionId).Burned()
64}
65
66func (p *positionV1) IsInRange(positionId uint64) bool {
67 position := p.mustGetPosition(positionId)
68 poolPath := position.PoolKey()
69 poolCurrentTick := pl.GetSlot0Tick(poolPath)
70
71 return position.TickLower() <= poolCurrentTick && poolCurrentTick < position.TickUpper()
72}
73
74func (p *positionV1) GetPositionOperator(positionId uint64) address {
75 return p.mustGetPosition(positionId).Operator()
76}
77
78func (p *positionV1) GetPositionPoolKey(positionId uint64) string {
79 return p.mustGetPosition(positionId).PoolKey()
80}
81
82func (p *positionV1) GetPositionTickLower(positionId uint64) int32 {
83 return p.mustGetPosition(positionId).TickLower()
84}
85
86func (p *positionV1) GetPositionTickUpper(positionId uint64) int32 {
87 return p.mustGetPosition(positionId).TickUpper()
88}
89
90func (p *positionV1) GetPositionLiquidity(positionId uint64) string {
91 return p.mustGetPosition(positionId).Liquidity()
92}
93
94func (p *positionV1) GetPositionTokenBalances(positionId uint64) (int64, int64) {
95 position := p.mustGetPosition(positionId)
96
97 return calculatePositionBalances(position)
98}
99
100func (p *positionV1) GetPositionFeeGrowthInside0LastX128(positionId uint64) string {
101 return p.mustGetPosition(positionId).FeeGrowthInside0LastX128()
102}
103
104func (p *positionV1) GetPositionFeeGrowthInside1LastX128(positionId uint64) string {
105 return p.mustGetPosition(positionId).FeeGrowthInside1LastX128()
106}
107
108func (p *positionV1) GetPositionTokensOwed0(positionId uint64) int64 {
109 return p.mustGetPosition(positionId).TokensOwed0()
110}
111
112func (p *positionV1) GetPositionTokensOwed1(positionId uint64) int64 {
113 return p.mustGetPosition(positionId).TokensOwed1()
114}
115
116func (p *positionV1) GetPositionOwner(positionId uint64) address {
117 owner, err := p.nftAccessor.OwnerOf(positionIdFrom(positionId))
118 if err != nil {
119 panic(newErrorWithDetail(
120 errDataNotFound, err.Error()))
121 }
122
123 return owner
124}
125
126func (p *positionV1) GetUnclaimedFee(positionId uint64) (*u256.Uint, *u256.Uint) {
127 // ref: https://blog.uniswap.org/uniswap-v3-math-primer-2#calculating-uncollected-fees
128 position := p.mustGetPosition(positionId)
129
130 liquidity := u256.MustFromDecimal(position.Liquidity())
131 tickLower := position.TickLower()
132 tickUpper := position.TickUpper()
133
134 poolKey := position.PoolKey()
135
136 currentTick := pl.GetSlot0Tick(poolKey)
137
138 feeGrowthGlobal0X128Str, feeGrowthGlobal1X128Str := pl.GetFeeGrowthGlobalX128(poolKey)
139 feeGrowthGlobal0X128 := u256.MustFromDecimal(feeGrowthGlobal0X128Str)
140 feeGrowthGlobal1X128 := u256.MustFromDecimal(feeGrowthGlobal1X128Str)
141
142 tickUpperFeeGrowthOutside0X128Str, tickUpperFeeGrowthOutside1X128Str := pl.GetTickFeeGrowthOutsideX128(poolKey, tickUpper)
143 tickUpperFeeGrowthOutside0X128 := u256.MustFromDecimal(tickUpperFeeGrowthOutside0X128Str)
144 tickUpperFeeGrowthOutside1X128 := u256.MustFromDecimal(tickUpperFeeGrowthOutside1X128Str)
145
146 tickLowerFeeGrowthOutside0X128Str, tickLowerFeeGrowthOutside1X128Str := pl.GetTickFeeGrowthOutsideX128(poolKey, tickLower)
147 tickLowerFeeGrowthOutside0X128 := u256.MustFromDecimal(tickLowerFeeGrowthOutside0X128Str)
148 tickLowerFeeGrowthOutside1X128 := u256.MustFromDecimal(tickLowerFeeGrowthOutside1X128Str)
149
150 feeGrowthInside0LastX128 := u256.MustFromDecimal(position.FeeGrowthInside0LastX128())
151 feeGrowthInside1LastX128 := u256.MustFromDecimal(position.FeeGrowthInside1LastX128())
152
153 var tickLowerFeeGrowthBelow0, tickLowerFeeGrowthBelow1, tickUpperFeeGrowthAbove0, tickUpperFeeGrowthAbove1 *u256.Uint
154
155 if currentTick >= tickUpper {
156 tickUpperFeeGrowthAbove0 = u256.Zero().Sub(feeGrowthGlobal0X128, tickUpperFeeGrowthOutside0X128)
157 tickUpperFeeGrowthAbove1 = u256.Zero().Sub(feeGrowthGlobal1X128, tickUpperFeeGrowthOutside1X128)
158 } else {
159 tickUpperFeeGrowthAbove0 = tickUpperFeeGrowthOutside0X128
160 tickUpperFeeGrowthAbove1 = tickUpperFeeGrowthOutside1X128
161 }
162
163 if currentTick >= tickLower {
164 tickLowerFeeGrowthBelow0 = tickLowerFeeGrowthOutside0X128
165 tickLowerFeeGrowthBelow1 = tickLowerFeeGrowthOutside1X128
166 } else {
167 tickLowerFeeGrowthBelow0 = u256.Zero().Sub(feeGrowthGlobal0X128, tickLowerFeeGrowthOutside0X128)
168 tickLowerFeeGrowthBelow1 = u256.Zero().Sub(feeGrowthGlobal1X128, tickLowerFeeGrowthOutside1X128)
169 }
170
171 feeGrowthInside0X128 := u256.Zero().Sub(feeGrowthGlobal0X128, tickLowerFeeGrowthBelow0)
172 feeGrowthInside0X128 = u256.Zero().Sub(feeGrowthInside0X128, tickUpperFeeGrowthAbove0)
173
174 feeGrowthInside1X128 := u256.Zero().Sub(feeGrowthGlobal1X128, tickLowerFeeGrowthBelow1)
175 feeGrowthInside1X128 = u256.Zero().Sub(feeGrowthInside1X128, tickUpperFeeGrowthAbove1)
176
177 diffGrowthInside0X128 := u256.Zero().Sub(feeGrowthInside0X128, feeGrowthInside0LastX128)
178 unclaimedFee0 := u256.MulDiv(diffGrowthInside0X128, liquidity, q128)
179
180 diffGrowthInside1X128 := u256.Zero().Sub(feeGrowthInside1X128, feeGrowthInside1LastX128)
181 unclaimedFee1 := u256.MulDiv(diffGrowthInside1X128, liquidity, q128)
182 return unclaimedFee0, unclaimedFee1
183}