store.gno
9.87 Kb · 339 lines
1package pool
2
3import (
4 "gno.land/p/gnoswap/store"
5 bptree "gno.land/p/nt/bptree/v0"
6 ufmt "gno.land/p/nt/ufmt/v0"
7)
8
9// StoreKey defines the keys used for storing pool data in the KV store.
10// These keys are prefixed with the domain address to ensure namespace isolation.
11type StoreKey string
12
13func (s StoreKey) String() string {
14 return string(s)
15}
16
17const (
18 // Pool data storage keys
19 StoreKeyPools StoreKey = "pools" // Map containing all pools
20 StoreKeyFeeAmountTickSpacing StoreKey = "feeAmountTickSpacing" // Fee tier to tick spacing mapping
21 StoreKeySlot0FeeProtocol StoreKey = "slot0FeeProtocol" // Protocol fee percentage
22
23 // Protocol fee storage keys
24 StoreKeyPoolCreationFee StoreKey = "poolCreationFee" // Pool creation fee amount
25 StoreKeyPendingProtocolFees StoreKey = "pendingProtocolFees" // tokenPath -> amount held locally for protocol_fee
26 StoreKeyWithdrawalFeeBPS StoreKey = "withdrawalFeeBPS" // Withdrawal fee in basis points
27 StoreKeyUnlocked StoreKey = "unlocked" // Global pool reentrancy lock
28
29 // Swap hook storage keys
30 StoreKeySwapStartHook StoreKey = "swapStartHook" // Swap start hook function
31 StoreKeySwapEndHook StoreKey = "swapEndHook" // Swap end hook function
32 StoreKeyTickCrossHook StoreKey = "tickCrossHook" // Tick cross hook function
33)
34
35// poolStore implements the IPoolStore interface for pool domain storage.
36// It provides type-safe access to pool data stored in the underlying KV store.
37type poolStore struct {
38 kvStore store.KVStore
39}
40
41func (s *poolStore) HasPools() bool {
42 return s.kvStore.Has(StoreKeyPools.String())
43}
44
45// GetPools retrieves the map containing all pool data.
46// This is the main data structure that stores all pool instances.
47func (s *poolStore) GetPools() *bptree.BPTree {
48 pools, err := s.kvStore.GetBPTree(StoreKeyPools.String())
49 if err != nil {
50 panic(err)
51 }
52
53 if pools == nil {
54 panic("pools is nil")
55 }
56
57 return pools
58}
59
60// SetPools stores the map containing all pool data.
61func (s *poolStore) SetPools(_ int, rlm realm, pools *bptree.BPTree) error {
62 if !rlm.IsCurrent() {
63 return ErrSpoofedRealm
64 }
65
66 if pools == nil {
67 panic("pools is nil")
68 }
69
70 return s.kvStore.Set(0, rlm, StoreKeyPools.String(), pools)
71}
72
73func (s *poolStore) HasFeeAmountTickSpacing() bool {
74 return s.kvStore.Has(StoreKeyFeeAmountTickSpacing.String())
75}
76
77// GetFeeAmountTickSpacing retrieves the mapping between fee amounts and tick spacing.
78// This mapping determines the tick spacing for each supported fee tier.
79func (s *poolStore) GetFeeAmountTickSpacing() map[uint32]int32 {
80 result, err := s.kvStore.Get(StoreKeyFeeAmountTickSpacing.String())
81 if err != nil {
82 panic(err)
83 }
84
85 feeAmountTickSpacing, ok := result.(map[uint32]int32)
86 if !ok {
87 panic(ufmt.Sprintf("failed to cast result to map[uint32]int32: %T", result))
88 }
89
90 if feeAmountTickSpacing == nil {
91 panic("feeAmountTickSpacing is nil")
92 }
93
94 return feeAmountTickSpacing
95}
96
97// SetFeeAmountTickSpacing stores the mapping between fee amounts and tick spacing.
98func (s *poolStore) SetFeeAmountTickSpacing(_ int, rlm realm, feeAmountTickSpacing map[uint32]int32) error {
99 if !rlm.IsCurrent() {
100 return ErrSpoofedRealm
101 }
102
103 if feeAmountTickSpacing == nil {
104 panic("feeAmountTickSpacing is nil")
105 }
106
107 return s.kvStore.Set(0, rlm, StoreKeyFeeAmountTickSpacing.String(), feeAmountTickSpacing)
108}
109
110func (s *poolStore) HasSlot0FeeProtocol() bool {
111 return s.kvStore.Has(StoreKeySlot0FeeProtocol.String())
112}
113
114// GetSlot0FeeProtocol retrieves the protocol fee percentage for slot0.
115func (s *poolStore) GetSlot0FeeProtocol() uint8 {
116 result, err := s.kvStore.Get(StoreKeySlot0FeeProtocol.String())
117 if err != nil {
118 panic(err)
119 }
120
121 slot0FeeProtocol, ok := result.(uint8)
122 if !ok {
123 panic(ufmt.Sprintf("failed to cast result to uint8: %T", result))
124 }
125
126 return slot0FeeProtocol
127}
128
129// SetSlot0FeeProtocol stores the protocol fee percentage for slot0.
130func (s *poolStore) SetSlot0FeeProtocol(_ int, rlm realm, slot0FeeProtocol uint8) error {
131 if !rlm.IsCurrent() {
132 return ErrSpoofedRealm
133 }
134
135 return s.kvStore.Set(0, rlm, StoreKeySlot0FeeProtocol.String(), slot0FeeProtocol)
136}
137
138func (s *poolStore) HasPoolCreationFee() bool {
139 return s.kvStore.Has(StoreKeyPoolCreationFee.String())
140}
141
142// GetPoolCreationFee retrieves the pool creation fee amount.
143func (s *poolStore) GetPoolCreationFee() int64 {
144 result, err := s.kvStore.Get(StoreKeyPoolCreationFee.String())
145 if err != nil {
146 panic(err)
147 }
148
149 poolCreationFee, ok := result.(int64)
150 if !ok {
151 panic(ufmt.Sprintf("failed to cast result to int64: %T", result))
152 }
153
154 return poolCreationFee
155}
156
157// SetPoolCreationFee stores the pool creation fee amount.
158func (s *poolStore) SetPoolCreationFee(_ int, rlm realm, poolCreationFee int64) error {
159 if !rlm.IsCurrent() {
160 return ErrSpoofedRealm
161 }
162
163 return s.kvStore.Set(0, rlm, StoreKeyPoolCreationFee.String(), poolCreationFee)
164}
165
166func (s *poolStore) HasPendingProtocolFees() bool {
167 return s.kvStore.Has(StoreKeyPendingProtocolFees.String())
168}
169
170func (s *poolStore) GetPendingProtocolFees() map[string]int64 {
171 result, err := s.kvStore.Get(StoreKeyPendingProtocolFees.String())
172 if err != nil {
173 panic(err)
174 }
175
176 pendingProtocolFees, ok := result.(map[string]int64)
177 if !ok {
178 panic(ufmt.Sprintf("failed to cast result to map[string]int64: %T", result))
179 }
180
181 return pendingProtocolFees
182}
183
184func (s *poolStore) SetPendingProtocolFees(_ int, rlm realm, pendingProtocolFees map[string]int64) error {
185 if !rlm.IsCurrent() {
186 return ErrSpoofedRealm
187 }
188
189 return s.kvStore.Set(0, rlm, StoreKeyPendingProtocolFees.String(), pendingProtocolFees)
190}
191
192func (s *poolStore) HasWithdrawalFeeBPS() bool {
193 return s.kvStore.Has(StoreKeyWithdrawalFeeBPS.String())
194}
195
196// GetWithdrawalFeeBPS retrieves the withdrawal fee in basis points.
197func (s *poolStore) GetWithdrawalFeeBPS() uint64 {
198 result, err := s.kvStore.Get(StoreKeyWithdrawalFeeBPS.String())
199 if err != nil {
200 panic(err)
201 }
202
203 withdrawalFeeBPS, ok := result.(uint64)
204 if !ok {
205 panic(ufmt.Sprintf("failed to cast result to uint64: %T", result))
206 }
207
208 return withdrawalFeeBPS
209}
210
211// SetWithdrawalFeeBPS stores the withdrawal fee in basis points.
212func (s *poolStore) SetWithdrawalFeeBPS(_ int, rlm realm, withdrawalFeeBPS uint64) error {
213 if !rlm.IsCurrent() {
214 return ErrSpoofedRealm
215 }
216
217 return s.kvStore.Set(0, rlm, StoreKeyWithdrawalFeeBPS.String(), withdrawalFeeBPS)
218}
219
220func (s *poolStore) HasUnlocked() bool {
221 return s.kvStore.Has(StoreKeyUnlocked.String())
222}
223
224func (s *poolStore) GetUnlocked() bool {
225 result, err := s.kvStore.Get(StoreKeyUnlocked.String())
226 if err != nil {
227 panic(err)
228 }
229
230 unlocked, ok := result.(bool)
231 if !ok {
232 panic(ufmt.Sprintf("failed to cast result to bool: %T", result))
233 }
234
235 return unlocked
236}
237
238func (s *poolStore) SetUnlocked(_ int, rlm realm, unlocked bool) error {
239 if !rlm.IsCurrent() {
240 return ErrSpoofedRealm
241 }
242
243 return s.kvStore.Set(0, rlm, StoreKeyUnlocked.String(), unlocked)
244}
245
246// HasSwapStartHook checks if the swap start hook is set.
247func (s *poolStore) HasSwapStartHook() bool {
248 return s.kvStore.Has(StoreKeySwapStartHook.String())
249}
250
251// GetSwapStartHook retrieves the swap start hook function.
252func (s *poolStore) GetSwapStartHook() func(cur realm, poolPath string, timestamp int64) {
253 result, err := s.kvStore.Get(StoreKeySwapStartHook.String())
254 if err != nil {
255 panic(err)
256 }
257
258 swapStartHook, ok := result.(func(cur realm, poolPath string, timestamp int64))
259 if !ok {
260 panic(ufmt.Sprintf("failed to cast result to func(poolPath string, timestamp int64): %T", result))
261 }
262
263 return swapStartHook
264}
265
266// SetSwapStartHook stores the swap start hook function.
267func (s *poolStore) SetSwapStartHook(_ int, rlm realm, swapStartHook func(cur realm, poolPath string, timestamp int64)) error {
268 if !rlm.IsCurrent() {
269 return ErrSpoofedRealm
270 }
271
272 return s.kvStore.Set(0, rlm, StoreKeySwapStartHook.String(), swapStartHook)
273}
274
275// HasSwapEndHook checks if the swap end hook is set.
276func (s *poolStore) HasSwapEndHook() bool {
277 return s.kvStore.Has(StoreKeySwapEndHook.String())
278}
279
280// GetSwapEndHook retrieves the swap end hook function.
281func (s *poolStore) GetSwapEndHook() func(cur realm, poolPath string) error {
282 result, err := s.kvStore.Get(StoreKeySwapEndHook.String())
283 if err != nil {
284 panic(err)
285 }
286
287 swapEndHook, ok := result.(func(cur realm, poolPath string) error)
288 if !ok {
289 panic(ufmt.Sprintf("failed to cast result to func(poolPath string): %T", result))
290 }
291
292 return swapEndHook
293}
294
295// SetSwapEndHook stores the swap end hook function.
296func (s *poolStore) SetSwapEndHook(_ int, rlm realm, swapEndHook func(cur realm, poolPath string) error) error {
297 if !rlm.IsCurrent() {
298 return ErrSpoofedRealm
299 }
300
301 return s.kvStore.Set(0, rlm, StoreKeySwapEndHook.String(), swapEndHook)
302}
303
304// HasTickCrossHook checks if the tick cross hook is set.
305func (s *poolStore) HasTickCrossHook() bool {
306 return s.kvStore.Has(StoreKeyTickCrossHook.String())
307}
308
309// GetTickCrossHook retrieves the tick cross hook function.
310func (s *poolStore) GetTickCrossHook() func(cur realm, poolPath string, tickId int32, zeroForOne bool, timestamp int64) {
311 result, err := s.kvStore.Get(StoreKeyTickCrossHook.String())
312 if err != nil {
313 panic(err)
314 }
315
316 tickCrossHook, ok := result.(func(cur realm, poolPath string, tickId int32, zeroForOne bool, timestamp int64))
317 if !ok {
318 panic(ufmt.Sprintf("failed to cast result to func(poolPath string, tickId int32, zeroForOne bool, timestamp int64): %T", result))
319 }
320
321 return tickCrossHook
322}
323
324// SetTickCrossHook stores the tick cross hook function.
325func (s *poolStore) SetTickCrossHook(_ int, rlm realm, tickCrossHook func(cur realm, poolPath string, tickId int32, zeroForOne bool, timestamp int64)) error {
326 if !rlm.IsCurrent() {
327 return ErrSpoofedRealm
328 }
329
330 return s.kvStore.Set(0, rlm, StoreKeyTickCrossHook.String(), tickCrossHook)
331}
332
333// NewPoolStore creates a new pool store instance with the provided KV store.
334// This function is used by the upgrade system to create storage instances for each implementation.
335func NewPoolStore(kvStore store.KVStore) IPoolStore {
336 return &poolStore{
337 kvStore: kvStore,
338 }
339}