utils.gno
5.60 Kb · 197 lines
1package v1
2
3import (
4 "math"
5 "strconv"
6 "strings"
7
8 "gno.land/p/gnoswap/deps/grc721"
9 prabc "gno.land/p/gnoswap/rbac"
10 u256 "gno.land/p/gnoswap/uint256"
11 ufmt "gno.land/p/nt/ufmt/v0"
12 "gno.land/r/gnoswap/access"
13)
14
15const MAX_UINT256 string = "115792089237316195423570985008687907853269984665640564039457584007913129639935"
16
17func mustGetStakerAddress() address {
18 return access.MustGetAddress(prabc.ROLE_STAKER.String())
19}
20
21// positionIdFrom converts positionId to grc721.TokenID type
22// input: positionId uint64
23// output: grc721.TokenID
24func positionIdFrom(positionId uint64) grc721.TokenID {
25 return grc721.TokenID(strconv.FormatUint(positionId, 10))
26}
27
28// exists checks whether positionId exists
29// If positionId doesn't exist, return false, otherwise return true
30// input: positionId uint64
31// output: bool
32func (p *positionV1) exists(positionId uint64) bool {
33 return p.nftAccessor.Exists(positionIdFrom(positionId))
34}
35
36// isOwner checks whether the caller is the owner of the positionId
37// If the caller is the owner of the positionId, return true, otherwise return false
38// input: positionId uint64, addr std.Address
39// output: bool
40func (p *positionV1) isOwner(positionId uint64, addr address) bool {
41 owner, err := p.nftAccessor.OwnerOf(positionIdFrom(positionId))
42 if err != nil {
43 return false
44 }
45 return owner == addr
46}
47
48// isOperator checks whether the caller is the approved operator of the positionId
49// If the caller is the approved operator of the positionId, return true, otherwise return false
50// input: positionId uint64, addr std.Address
51// output: bool
52func (p *positionV1) isOperator(positionId uint64, addr address) bool {
53 return p.GetPositionOperator(positionId) == addr
54}
55
56// isStaked checks whether positionId is staked
57// If positionId is staked, owner of positionId is staker contract
58// If positionId is staked, return true, otherwise return false
59// input: positionId grc721.TokenID
60// output: bool
61func (p *positionV1) isStaked(positionId grc721.TokenID) bool {
62 exist := p.nftAccessor.Exists(positionId)
63 if !exist {
64 return false
65 }
66 owner, err := p.nftAccessor.OwnerOf(positionId)
67 if err == nil && owner == mustGetStakerAddress() {
68 return true
69 }
70 return false
71}
72
73// isOwnerOrOperator checks whether the caller is the owner or approved operator of the positionId
74// If the caller is the owner or approved operator of the positionId, return true, otherwise return false
75// input: addr std.Address, positionId uint64
76// output: bool
77func (p *positionV1) isOwnerOrOperator(positionId uint64, addr address) bool {
78 if !addr.IsValid() || !p.exists(positionId) {
79 return false
80 }
81
82 if p.isStaked(positionIdFrom(positionId)) {
83 return p.isOperator(positionId, addr)
84 }
85
86 return p.isOwner(positionId, addr)
87}
88
89// splitOf divides poolKey into pToken0, pToken1, and pFee
90// If poolKey is invalid, it will panic
91//
92// input: poolKey string
93// output:
94// - token0Path string
95// - token1Path string
96// - fee uint32
97func splitOf(poolKey string) (string, string, uint32) {
98 res := strings.Split(poolKey, ":")
99 if len(res) != 3 {
100 panic(newErrorWithDetail(errInvalidInput, ufmt.Sprintf("invalid poolKey(%s)", poolKey)))
101 }
102
103 pToken0, pToken1, pFeeStr := res[0], res[1], res[2]
104
105 pFee, err := strconv.Atoi(pFeeStr)
106 if err != nil {
107 panic(newErrorWithDetail(errInvalidInput, ufmt.Sprintf("invalid fee(%s)", pFeeStr)))
108 }
109
110 return pToken0, pToken1, uint32(pFee)
111}
112
113func formatUint(v any) string {
114 switch v := v.(type) {
115 case uint8:
116 return strconv.FormatUint(uint64(v), 10)
117 case uint32:
118 return strconv.FormatUint(uint64(v), 10)
119 case uint64:
120 return strconv.FormatUint(v, 10)
121 default:
122 panic(ufmt.Sprintf("invalid type: %T", v))
123 }
124}
125
126func formatInt(v any) string {
127 switch v := v.(type) {
128 case int32:
129 return strconv.FormatInt(int64(v), 10)
130 case int64:
131 return strconv.FormatInt(v, 10)
132 case int:
133 return strconv.Itoa(v)
134 default:
135 panic(ufmt.Sprintf("invalid type: %T", v))
136 }
137}
138
139func isSlippageExceeded(amount0, amount1, amount0Min, amount1Min *u256.Uint) bool {
140 return !(amount0.Gte(amount0Min) && amount1.Gte(amount1Min))
141}
142
143// safeConvertToInt64 safely converts a *u256.Uint value to an int64, ensuring no overflow.
144//
145// This function attempts to convert the given *u256.Uint value to an int64. If the value exceeds
146// the maximum allowable range for int64 (`2^63 - 1`), it triggers a panic with a descriptive error message.
147//
148// Parameters:
149// - value (*u256.Uint): The unsigned 256-bit integer to be converted.
150//
151// Returns:
152// - int64: The converted value if it falls within the int64 range.
153//
154// Panics:
155// - If the `value` exceeds the range of int64, the function will panic with an error indicating
156// the overflow and the original value.
157func safeConvertToInt64(value *u256.Uint) int64 {
158 res, overflow := value.Uint64WithOverflow()
159 if overflow || res > 9223372036854775807 {
160 panic(ufmt.Sprintf(
161 "amount(%s) overflows int64 range (max: 9223372036854775807)",
162 value.ToString(),
163 ))
164 }
165 return int64(res)
166}
167
168func safeParseInt64(value string) int64 {
169 amountInt64, err := strconv.ParseInt(value, 10, 64)
170 if err != nil {
171 panic(err)
172 }
173
174 return amountInt64
175}
176
177// safeAddInt64 performs safe addition of int64 values, panicking on overflow or underflow.
178func safeAddInt64(a, b int64) int64 {
179 if a > 0 && b > math.MaxInt64-a {
180 panic("int64 addition overflow")
181 }
182 if a < 0 && b < math.MinInt64-a {
183 panic("int64 addition underflow")
184 }
185 return a + b
186}
187
188// safeSubInt64 performs safe subtraction of int64 values, panicking on overflow or underflow.
189func safeSubInt64(a, b int64) int64 {
190 if b > 0 && a < math.MinInt64+b {
191 panic("int64 subtraction underflow")
192 }
193 if b < 0 && a > math.MaxInt64+b {
194 panic("int64 subtraction overflow")
195 }
196 return a - b
197}