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

store.gno

21.09 Kb · 606 lines
  1package pool
  2
  3import (
  4	"errors"
  5
  6	"gno.land/p/gnoswap/store/v1"
  7	bptree "gno.land/p/nt/bptree/v0"
  8	ufmt "gno.land/p/nt/ufmt/v0"
  9)
 10
 11// StoreKey defines the keys used for storing pool data in the KV store.
 12// These keys are prefixed with the domain address to ensure namespace isolation.
 13type StoreKey string
 14
 15// Returns:
 16//   - keyText: the textual store key represented by s.
 17func (s StoreKey) String() string {
 18	return string(s)
 19}
 20
 21const (
 22	// Pool data storage keys
 23	StoreKeyPools                StoreKey = "pools"                // Map containing all pools
 24	StoreKeyObservations         StoreKey = "observations"         // poolPath -> observation B+tree
 25	StoreKeyFeeAmountTickSpacing StoreKey = "feeAmountTickSpacing" // Fee tier to tick spacing mapping
 26	StoreKeySlot0FeeProtocol     StoreKey = "slot0FeeProtocol"     // Protocol fee denominator(s)
 27
 28	// Protocol fee storage keys
 29	StoreKeyPoolCreationFee     StoreKey = "poolCreationFee"     // Pool creation fee amount
 30	StoreKeyPendingProtocolFees StoreKey = "pendingProtocolFees" // tokenPath -> amount held locally for protocol_fee
 31	StoreKeyWithdrawalFeeBPS    StoreKey = "withdrawalFeeBPS"    // Withdrawal fee in basis points
 32	StoreKeyUnlocked            StoreKey = "unlocked"            // Global pool reentrancy lock
 33
 34	// Swap hook storage keys
 35	StoreKeySwapStartHook StoreKey = "swapStartHook" // Swap start hook function
 36	StoreKeySwapEndHook   StoreKey = "swapEndHook"   // Swap end hook function
 37	StoreKeyTickCrossHook StoreKey = "tickCrossHook" // Tick cross hook function
 38)
 39
 40// poolStore implements the IPoolStore interface for pool domain storage.
 41// It provides type-safe access to pool data stored in the underlying KV store.
 42type poolStore struct {
 43	kvStore store.KVStore
 44}
 45
 46// Returns:
 47//   - exists: true when the pool collection key is present in the KV store.
 48func (s *poolStore) HasPools() bool {
 49	return s.kvStore.Has(StoreKeyPools.String())
 50}
 51
 52// GetPools retrieves the map containing all pool data.
 53// This is the main data structure that stores all pool instances.
 54// Returns:
 55//   - pools: the B+tree containing all persisted pool instances; panics if the
 56//     KV store cannot read it or the stored value is nil.
 57func (s *poolStore) GetPools() *bptree.BPTree {
 58	pools, err := s.kvStore.GetBPTree(StoreKeyPools.String())
 59	if err != nil {
 60		panic(err)
 61	}
 62
 63	if pools == nil {
 64		panic("pools is nil")
 65	}
 66
 67	return pools
 68}
 69
 70// SetPools stores the map containing all pool data.
 71// Parameters:
 72//   - _: leading realm-call discriminator; callers pass 0.
 73//   - rlm: propagated realm context; it must be the current realm or the method
 74//     returns ErrSpoofedRealm before writing.
 75//   - pools: non-nil B+tree containing the pool instances to persist.
 76//
 77// Returns:
 78//   - err: nil when the pool tree is stored; ErrSpoofedRealm for a non-current
 79//     realm, or the underlying KV-store write error.
 80func (s *poolStore) SetPools(_ int, rlm realm, pools *bptree.BPTree) error {
 81	if !rlm.IsCurrent() {
 82		return errors.New(ErrSpoofedRealm)
 83	}
 84
 85	if pools == nil {
 86		panic("pools is nil")
 87	}
 88
 89	return s.kvStore.Set(0, rlm, StoreKeyPools.String(), pools)
 90}
 91
 92// Returns:
 93//   - exists: true when the observations collection key is present in the KV store.
 94func (s *poolStore) HasObservations() bool {
 95	return s.kvStore.Has(StoreKeyObservations.String())
 96}
 97
 98// Returns:
 99//   - observations: the B+tree containing persisted observation trees; panics if
100//     the KV store cannot read it or the stored value is nil.
101func (s *poolStore) GetObservations() *bptree.BPTree {
102	observations, err := s.kvStore.GetBPTree(StoreKeyObservations.String())
103	if err != nil {
104		panic(err)
105	}
106	if observations == nil {
107		panic("observations is nil")
108	}
109	return observations
110}
111
112// Parameters:
113//   - _: leading realm-call discriminator; callers pass 0.
114//   - rlm: propagated realm context; it must be the current realm or the method
115//     returns ErrSpoofedRealm before writing.
116//   - observations: non-nil B+tree containing the observation data to persist.
117//
118// Returns:
119//   - err: nil when the observation tree is stored; ErrSpoofedRealm for a
120//     non-current realm, or the underlying KV-store write error.
121func (s *poolStore) SetObservations(_ int, rlm realm, observations *bptree.BPTree) error {
122	if !rlm.IsCurrent() {
123		return errors.New(ErrSpoofedRealm)
124	}
125	if observations == nil {
126		panic("observations is nil")
127	}
128	return s.kvStore.Set(0, rlm, StoreKeyObservations.String(), observations)
129}
130
131// Returns:
132//   - exists: true when the fee-tier/tick-spacing mapping key is present in the
133//     KV store.
134func (s *poolStore) HasFeeAmountTickSpacing() bool {
135	return s.kvStore.Has(StoreKeyFeeAmountTickSpacing.String())
136}
137
138// GetFeeAmountTickSpacing retrieves the mapping between fee amounts and tick spacing.
139// This mapping determines the tick spacing for each supported fee tier.
140// Returns:
141//   - feeAmountTickSpacing: a copy of the fee amount to tick-spacing mapping;
142//     panics if the KV value cannot be read, has the wrong type, or is nil.
143func (s *poolStore) GetFeeAmountTickSpacing() map[uint32]int32 {
144	result, err := s.kvStore.Get(StoreKeyFeeAmountTickSpacing.String())
145	if err != nil {
146		panic(err)
147	}
148
149	feeAmountTickSpacing, ok := result.(map[uint32]int32)
150	if !ok {
151		panic(ufmt.Sprintf("failed to cast result to map[uint32]int32: %T", result))
152	}
153
154	if feeAmountTickSpacing == nil {
155		panic("feeAmountTickSpacing is nil")
156	}
157
158	return cloneFeeAmountTickSpacings(feeAmountTickSpacing)
159}
160
161// SetFeeAmountTickSpacing stores the mapping between fee amounts and tick spacing.
162// Parameters:
163//   - _: leading realm-call discriminator; callers pass 0.
164//   - rlm: propagated realm context; it must be the current realm or the method
165//     returns ErrSpoofedRealm before writing.
166//   - feeAmountTickSpacing: non-nil mapping from fee tiers to their required
167//     int32 tick spacing values.
168//
169// Returns:
170//   - err: nil when the mapping is stored; ErrSpoofedRealm for a non-current
171//     realm, or the underlying KV-store write error.
172func (s *poolStore) SetFeeAmountTickSpacing(_ int, rlm realm, feeAmountTickSpacing map[uint32]int32) error {
173	if !rlm.IsCurrent() {
174		return errors.New(ErrSpoofedRealm)
175	}
176
177	if feeAmountTickSpacing == nil {
178		panic("feeAmountTickSpacing is nil")
179	}
180
181	return s.kvStore.Set(0, rlm, StoreKeyFeeAmountTickSpacing.String(), feeAmountTickSpacing)
182}
183
184// Returns:
185//   - exists: true when the slot0 protocol-fee configuration key is present in
186//     the KV store.
187func (s *poolStore) HasSlot0FeeProtocol() bool {
188	return s.kvStore.Has(StoreKeySlot0FeeProtocol.String())
189}
190
191// GetSlot0FeeProtocol retrieves the protocol fee denominator(s) for slot0.
192// Returns:
193//   - slot0FeeProtocol: packed protocol-fee denominator configuration for
194//     slot0; panics if the KV value cannot be read or has the wrong type.
195func (s *poolStore) GetSlot0FeeProtocol() uint8 {
196	result, err := s.kvStore.Get(StoreKeySlot0FeeProtocol.String())
197	if err != nil {
198		panic(err)
199	}
200
201	slot0FeeProtocol, ok := result.(uint8)
202	if !ok {
203		panic(ufmt.Sprintf("failed to cast result to uint8: %T", result))
204	}
205
206	return slot0FeeProtocol
207}
208
209// SetSlot0FeeProtocol stores the protocol fee denominator(s) for slot0.
210// Parameters:
211//   - _: leading realm-call discriminator; callers pass 0.
212//   - rlm: propagated realm context; it must be the current realm or the method
213//     returns ErrSpoofedRealm before writing.
214//   - slot0FeeProtocol: packed uint8 protocol-fee denominators for token0 and
215//     token1.
216//
217// Returns:
218//   - err: nil when the protocol-fee configuration is stored; ErrSpoofedRealm
219//     for a non-current realm, or the underlying KV-store write error.
220func (s *poolStore) SetSlot0FeeProtocol(_ int, rlm realm, slot0FeeProtocol uint8) error {
221	if !rlm.IsCurrent() {
222		return errors.New(ErrSpoofedRealm)
223	}
224
225	return s.kvStore.Set(0, rlm, StoreKeySlot0FeeProtocol.String(), slot0FeeProtocol)
226}
227
228// Returns:
229//   - exists: true when the pool-creation-fee key is present in the KV store.
230func (s *poolStore) HasPoolCreationFee() bool {
231	return s.kvStore.Has(StoreKeyPoolCreationFee.String())
232}
233
234// GetPoolCreationFee retrieves the pool creation fee amount.
235// Returns:
236//   - poolCreationFee: configured pool-creation charge in the chain's smallest
237//     currency unit; panics if the KV value cannot be read or has the wrong type.
238func (s *poolStore) GetPoolCreationFee() int64 {
239	result, err := s.kvStore.Get(StoreKeyPoolCreationFee.String())
240	if err != nil {
241		panic(err)
242	}
243
244	poolCreationFee, ok := result.(int64)
245	if !ok {
246		panic(ufmt.Sprintf("failed to cast result to int64: %T", result))
247	}
248
249	return poolCreationFee
250}
251
252// SetPoolCreationFee stores the pool creation fee amount.
253// Parameters:
254//   - _: leading realm-call discriminator; callers pass 0.
255//   - rlm: propagated realm context; it must be the current realm or the method
256//     returns ErrSpoofedRealm before writing.
257//   - poolCreationFee: pool-creation charge in the chain's smallest currency
258//     unit.
259//
260// Returns:
261//   - err: nil when the fee is stored; ErrSpoofedRealm for a non-current realm,
262//     or the underlying KV-store write error.
263func (s *poolStore) SetPoolCreationFee(_ int, rlm realm, poolCreationFee int64) error {
264	if !rlm.IsCurrent() {
265		return errors.New(ErrSpoofedRealm)
266	}
267
268	return s.kvStore.Set(0, rlm, StoreKeyPoolCreationFee.String(), poolCreationFee)
269}
270
271// Returns:
272//   - exists: true when the pending protocol-fees key is present in the KV store.
273func (s *poolStore) HasPendingProtocolFees() bool {
274	return s.kvStore.Has(StoreKeyPendingProtocolFees.String())
275}
276
277// Returns:
278//   - pendingProtocolFees: mapping from token path to pending protocol-fee
279//     amount in the chain's smallest currency unit; panics if the KV value
280//     cannot be read or has the wrong type.
281func (s *poolStore) GetPendingProtocolFees() map[string]int64 {
282	result, err := s.kvStore.Get(StoreKeyPendingProtocolFees.String())
283	if err != nil {
284		panic(err)
285	}
286
287	pendingProtocolFees, ok := result.(map[string]int64)
288	if !ok {
289		panic(ufmt.Sprintf("failed to cast result to map[string]int64: %T", result))
290	}
291
292	return pendingProtocolFees
293}
294
295// Parameters:
296//   - _: leading realm-call discriminator; callers pass 0.
297//   - rlm: propagated realm context; it must be the current realm or the method
298//     returns ErrSpoofedRealm before writing.
299//   - pendingProtocolFees: token-path-to-amount mapping; amounts are in the
300//     chain's smallest currency unit and are copied before storage.
301//
302// Returns:
303//   - err: nil when the copied mapping is stored; ErrSpoofedRealm for a
304//     non-current realm, or the underlying KV-store write error.
305func (s *poolStore) SetPendingProtocolFees(_ int, rlm realm, pendingProtocolFees map[string]int64) error {
306	if !rlm.IsCurrent() {
307		return errors.New(ErrSpoofedRealm)
308	}
309
310	// The map is copied here so it is allocated by, and therefore mutable from, this realm.
311	owned := make(map[string]int64, len(pendingProtocolFees))
312	for tokenPath, amount := range pendingProtocolFees {
313		owned[tokenPath] = amount
314	}
315
316	return s.kvStore.Set(0, rlm, StoreKeyPendingProtocolFees.String(), owned)
317}
318
319// Parameters:
320//   - tokenPath: token contract path used as the pending-fee map key.
321//
322// Returns:
323//   - amount: pending protocol-fee amount for tokenPath in the chain's smallest
324//     currency unit, or zero when no entry exists.
325func (s *poolStore) GetPendingProtocolFee(tokenPath string) int64 {
326	return s.GetPendingProtocolFees()[tokenPath]
327}
328
329// Parameters:
330//   - _: leading realm-call discriminator; callers pass 0.
331//   - rlm: propagated realm context; it must be the current realm or the method
332//     returns ErrSpoofedRealm before writing.
333//   - tokenPath: token contract path identifying the pending-fee entry.
334//   - amount: pending protocol-fee amount to assign for tokenPath, in the
335//     chain's smallest currency unit.
336//
337// Returns:
338//   - err: nil after the map entry is updated; ErrSpoofedRealm for a non-current
339//     realm, or store.ErrWritePermissionDenied for an unauthorized code realm.
340func (s *poolStore) SetPendingProtocolFee(_ int, rlm realm, tokenPath string, amount int64) error {
341	if !rlm.IsCurrent() {
342		return errors.New(ErrSpoofedRealm)
343	}
344
345	if rlm.IsCode() && !s.kvStore.IsWriteAuthorized(rlm.Address()) {
346		return errors.New(store.ErrWritePermissionDenied)
347	}
348
349	s.GetPendingProtocolFees()[tokenPath] = amount
350
351	return nil
352}
353
354// Parameters:
355//   - _: leading realm-call discriminator; callers pass 0.
356//   - rlm: propagated realm context; it must be the current realm or the method
357//     returns ErrSpoofedRealm before writing.
358//   - tokenPath: token contract path identifying the pending-fee entry to delete.
359//
360// Returns:
361//   - err: nil after the map entry is removed; ErrSpoofedRealm for a non-current
362//     realm, or store.ErrWritePermissionDenied for an unauthorized code realm.
363func (s *poolStore) RemovePendingProtocolFee(_ int, rlm realm, tokenPath string) error {
364	if !rlm.IsCurrent() {
365		return errors.New(ErrSpoofedRealm)
366	}
367
368	if rlm.IsCode() && !s.kvStore.IsWriteAuthorized(rlm.Address()) {
369		return errors.New(store.ErrWritePermissionDenied)
370	}
371
372	delete(s.GetPendingProtocolFees(), tokenPath)
373
374	return nil
375}
376
377// Returns:
378//   - exists: true when the withdrawal-fee key is present in the KV store.
379func (s *poolStore) HasWithdrawalFeeBPS() bool {
380	return s.kvStore.Has(StoreKeyWithdrawalFeeBPS.String())
381}
382
383// GetWithdrawalFeeBPS retrieves the withdrawal fee in basis points.
384// Returns:
385//   - withdrawalFeeBPS: withdrawal fee expressed in basis points (1/100 of a
386//     percent); panics if the KV value cannot be read or has the wrong type.
387func (s *poolStore) GetWithdrawalFeeBPS() uint64 {
388	result, err := s.kvStore.Get(StoreKeyWithdrawalFeeBPS.String())
389	if err != nil {
390		panic(err)
391	}
392
393	withdrawalFeeBPS, ok := result.(uint64)
394	if !ok {
395		panic(ufmt.Sprintf("failed to cast result to uint64: %T", result))
396	}
397
398	return withdrawalFeeBPS
399}
400
401// SetWithdrawalFeeBPS stores the withdrawal fee in basis points.
402// Parameters:
403//   - _: leading realm-call discriminator; callers pass 0.
404//   - rlm: propagated realm context; it must be the current realm or the method
405//     returns ErrSpoofedRealm before writing.
406//   - withdrawalFeeBPS: withdrawal fee in basis points, where 100 basis points
407//     equals one percent.
408//
409// Returns:
410//   - err: nil when the fee is stored; ErrSpoofedRealm for a non-current realm,
411//     or the underlying KV-store write error.
412func (s *poolStore) SetWithdrawalFeeBPS(_ int, rlm realm, withdrawalFeeBPS uint64) error {
413	if !rlm.IsCurrent() {
414		return errors.New(ErrSpoofedRealm)
415	}
416
417	return s.kvStore.Set(0, rlm, StoreKeyWithdrawalFeeBPS.String(), withdrawalFeeBPS)
418}
419
420// Returns:
421//   - exists: true when the global unlocked-state key is present in the KV store.
422func (s *poolStore) HasUnlocked() bool {
423	return s.kvStore.Has(StoreKeyUnlocked.String())
424}
425
426// Returns:
427//   - unlocked: the persisted global reentrancy-lock state; panics if the KV
428//     value cannot be read or has the wrong type.
429func (s *poolStore) GetUnlocked() bool {
430	result, err := s.kvStore.Get(StoreKeyUnlocked.String())
431	if err != nil {
432		panic(err)
433	}
434
435	unlocked, ok := result.(bool)
436	if !ok {
437		panic(ufmt.Sprintf("failed to cast result to bool: %T", result))
438	}
439
440	return unlocked
441}
442
443// Parameters:
444//   - _: leading realm-call discriminator; callers pass 0.
445//   - rlm: propagated realm context; it must be the current realm or the method
446//     returns ErrSpoofedRealm before writing.
447//   - unlocked: true when pool operations may proceed without the global lock.
448//
449// Returns:
450//   - err: nil when the lock state is stored; ErrSpoofedRealm for a non-current
451//     realm, or the underlying KV-store write error.
452func (s *poolStore) SetUnlocked(_ int, rlm realm, unlocked bool) error {
453	if !rlm.IsCurrent() {
454		return errors.New(ErrSpoofedRealm)
455	}
456
457	return s.kvStore.Set(0, rlm, StoreKeyUnlocked.String(), unlocked)
458}
459
460// HasSwapStartHook checks if the swap start hook is set.
461// Returns:
462//   - exists: true when a swap-start hook key is present in the KV store.
463func (s *poolStore) HasSwapStartHook() bool {
464	return s.kvStore.Has(StoreKeySwapStartHook.String())
465}
466
467// GetSwapStartHook retrieves the swap start hook function.
468// Returns:
469//   - swapStartHook: stored callback invoked at swap start with the current
470//     realm, pool path, and block timestamp; panics if the KV value cannot be
471//     read or has the wrong function type.
472func (s *poolStore) GetSwapStartHook() func(cur realm, poolPath string, timestamp int64) {
473	result, err := s.kvStore.Get(StoreKeySwapStartHook.String())
474	if err != nil {
475		panic(err)
476	}
477
478	swapStartHook, ok := result.(func(cur realm, poolPath string, timestamp int64))
479	if !ok {
480		panic(ufmt.Sprintf("failed to cast result to func(poolPath string, timestamp int64): %T", result))
481	}
482
483	return swapStartHook
484}
485
486// SetSwapStartHook stores the swap start hook function.
487// Parameters:
488//   - _: leading realm-call discriminator; callers pass 0.
489//   - rlm: propagated realm context; it must be the current realm or the method
490//     returns ErrSpoofedRealm before writing.
491//   - swapStartHook: callback receiving the current realm, pool path, and
492//     block timestamp when a swap starts.
493//
494// Returns:
495//   - err: nil when the callback is stored; ErrSpoofedRealm for a non-current
496//     realm, or the underlying KV-store write error.
497func (s *poolStore) SetSwapStartHook(_ int, rlm realm, swapStartHook func(cur realm, poolPath string, timestamp int64)) error {
498	if !rlm.IsCurrent() {
499		return errors.New(ErrSpoofedRealm)
500	}
501
502	return s.kvStore.Set(0, rlm, StoreKeySwapStartHook.String(), swapStartHook)
503}
504
505// HasSwapEndHook checks if the swap end hook is set.
506// Returns:
507//   - exists: true when a swap-end hook key is present in the KV store.
508func (s *poolStore) HasSwapEndHook() bool {
509	return s.kvStore.Has(StoreKeySwapEndHook.String())
510}
511
512// GetSwapEndHook retrieves the swap end hook function.
513// Returns:
514//   - swapEndHook: stored callback receiving the current realm and pool path at
515//     swap end and returning an error; panics if the KV value cannot be read or
516//     has the wrong function type.
517func (s *poolStore) GetSwapEndHook() func(cur realm, poolPath string) error {
518	result, err := s.kvStore.Get(StoreKeySwapEndHook.String())
519	if err != nil {
520		panic(err)
521	}
522
523	swapEndHook, ok := result.(func(cur realm, poolPath string) error)
524	if !ok {
525		panic(ufmt.Sprintf("failed to cast result to func(poolPath string): %T", result))
526	}
527
528	return swapEndHook
529}
530
531// SetSwapEndHook stores the swap end hook function.
532// Parameters:
533//   - _: leading realm-call discriminator; callers pass 0.
534//   - rlm: propagated realm context; it must be the current realm or the method
535//     returns ErrSpoofedRealm before writing.
536//   - swapEndHook: callback receiving the current realm and pool path at swap
537//     end and returning any hook error.
538//
539// Returns:
540//   - err: nil when the callback is stored; ErrSpoofedRealm for a non-current
541//     realm, or the underlying KV-store write error.
542func (s *poolStore) SetSwapEndHook(_ int, rlm realm, swapEndHook func(cur realm, poolPath string) error) error {
543	if !rlm.IsCurrent() {
544		return errors.New(ErrSpoofedRealm)
545	}
546
547	return s.kvStore.Set(0, rlm, StoreKeySwapEndHook.String(), swapEndHook)
548}
549
550// HasTickCrossHook checks if the tick cross hook is set.
551// Returns:
552//   - exists: true when a tick-cross hook key is present in the KV store.
553func (s *poolStore) HasTickCrossHook() bool {
554	return s.kvStore.Has(StoreKeyTickCrossHook.String())
555}
556
557// GetTickCrossHook retrieves the tick cross hook function.
558// Returns:
559//   - tickCrossHook: stored callback receiving the current realm, pool path,
560//     crossed tick, swap direction, and block timestamp; panics if the KV value
561//     cannot be read or has the wrong function type.
562func (s *poolStore) GetTickCrossHook() func(cur realm, poolPath string, tickId int32, zeroForOne bool, timestamp int64) {
563	result, err := s.kvStore.Get(StoreKeyTickCrossHook.String())
564	if err != nil {
565		panic(err)
566	}
567
568	tickCrossHook, ok := result.(func(cur realm, poolPath string, tickId int32, zeroForOne bool, timestamp int64))
569	if !ok {
570		panic(ufmt.Sprintf("failed to cast result to func(poolPath string, tickId int32, zeroForOne bool, timestamp int64): %T", result))
571	}
572
573	return tickCrossHook
574}
575
576// SetTickCrossHook stores the tick cross hook function.
577// Parameters:
578//   - _: leading realm-call discriminator; callers pass 0.
579//   - rlm: propagated realm context; it must be the current realm or the method
580//     returns ErrSpoofedRealm before writing.
581//   - tickCrossHook: callback receiving the current realm, pool path, crossed
582//     tick ID, swap direction, and block timestamp.
583//
584// Returns:
585//   - err: nil when the callback is stored; ErrSpoofedRealm for a non-current
586//     realm, or the underlying KV-store write error.
587func (s *poolStore) SetTickCrossHook(_ int, rlm realm, tickCrossHook func(cur realm, poolPath string, tickId int32, zeroForOne bool, timestamp int64)) error {
588	if !rlm.IsCurrent() {
589		return errors.New(ErrSpoofedRealm)
590	}
591
592	return s.kvStore.Set(0, rlm, StoreKeyTickCrossHook.String(), tickCrossHook)
593}
594
595// NewPoolStore creates a new pool store instance with the provided KV store.
596// This function is used by the upgrade system to create storage instances for each implementation.
597// Parameters:
598//   - kvStore: KV store used to persist and retrieve pool-domain state.
599//
600// Returns:
601//   - poolStore: an IPoolStore implementation backed by kvStore.
602func NewPoolStore(kvStore store.KVStore) IPoolStore {
603	return &poolStore{
604		kvStore: kvStore,
605	}
606}