Skip to content Search Apps Documentation Source Content File Folder Download Copy Actions State String Boolean Number Struct Map Slice Pointer Function Closure Reference Nil Package Type Interface Unknown

store.gno

5.90 Kb · 194 lines
  1package router
  2
  3import (
  4	"errors"
  5
  6	"gno.land/p/gnoswap/store/v1"
  7	ufmt "gno.land/p/nt/ufmt/v0"
  8)
  9
 10const errSpoofedRealm = "rlm does not match the current crossing frame"
 11
 12type StoreKey string
 13
 14// String converts the typed store key to the string key used by KVStore.
 15//
 16// Returns:
 17//   - key: underlying string representation of the store key
 18func (s StoreKey) String() string {
 19	return string(s)
 20}
 21
 22const (
 23	StoreKeySwapFee             StoreKey = "swapFee"             // Swap fee in basis points
 24	StoreKeyPendingProtocolFees StoreKey = "pendingProtocolFees" // tokenPath -> amount held locally for protocol_fee
 25)
 26
 27type routerStore struct {
 28	kvStore store.KVStore
 29}
 30
 31// HasSwapFeeKey reports whether persistent storage contains the router swap-fee key.
 32//
 33// Returns:
 34//   - exists: true when the swap-fee key is present, otherwise false
 35func (s *routerStore) HasSwapFeeKey() bool {
 36	return s.kvStore.Has(StoreKeySwapFee.String())
 37}
 38
 39// GetSwapFee retrieves the current swap fee from persistent storage.
 40//
 41// Returns:
 42//   - fee: configured router fee in basis points; panics if the key is missing or has the wrong type
 43func (s *routerStore) GetSwapFee() uint64 {
 44	result, err := s.kvStore.Get(StoreKeySwapFee.String())
 45	if err != nil {
 46		panic(err)
 47	}
 48
 49	swapFee, ok := result.(uint64)
 50	if !ok {
 51		panic(ufmt.Sprintf("failed to cast result to uint64: %T", result))
 52	}
 53
 54	return swapFee
 55}
 56
 57// SetSwapFee stores the router fee in persistent storage.
 58//
 59// Parameters:
 60//   - _: leading call discriminator; callers pass 0
 61//   - rlm: current realm context; must be the current crossing frame
 62//   - fee: router fee rate in basis points
 63//
 64// Returns:
 65//   - err: nil when storage succeeds; an error when rlm is not current or KVStore rejects the write
 66func (s *routerStore) SetSwapFee(_ int, rlm realm, fee uint64) error {
 67	if !rlm.IsCurrent() {
 68		return errors.New(errSpoofedRealm)
 69	}
 70
 71	return s.kvStore.Set(0, rlm, StoreKeySwapFee.String(), fee)
 72}
 73
 74// HasPendingProtocolFeesKey reports whether persistent storage contains the pending-fees map.
 75//
 76// Returns:
 77//   - exists: true when the pending protocol-fees key is present, otherwise false
 78func (s *routerStore) HasPendingProtocolFeesKey() bool {
 79	return s.kvStore.Has(StoreKeyPendingProtocolFees.String())
 80}
 81
 82// GetPendingProtocolFees retrieves the token-path keyed pending protocol-fees map.
 83//
 84// Returns:
 85//   - fees: stored token-path to pending amount map; panics if storage is missing or has the wrong type
 86func (s *routerStore) GetPendingProtocolFees() map[string]int64 {
 87	result, err := s.kvStore.Get(StoreKeyPendingProtocolFees.String())
 88	if err != nil {
 89		panic(err)
 90	}
 91
 92	pendingProtocolFees, ok := result.(map[string]int64)
 93	if !ok {
 94		panic(ufmt.Sprintf("failed to cast result to map[string]int64: %T", result))
 95	}
 96
 97	return pendingProtocolFees
 98}
 99
100// SetPendingProtocolFees replaces the pending protocol-fees map in persistent storage.
101//
102// Parameters:
103//   - _: leading call discriminator; callers pass 0
104//   - rlm: current realm context; must be the current crossing frame
105//   - fees: token-path keyed pending fee amounts to store; entries are copied into realm-owned storage
106//
107// Returns:
108//   - err: nil when storage succeeds; an error when rlm is not current or KVStore rejects the write
109func (s *routerStore) SetPendingProtocolFees(_ int, rlm realm, fees map[string]int64) error {
110	if !rlm.IsCurrent() {
111		return errors.New(errSpoofedRealm)
112	}
113
114	// The map is copied here so it is allocated by, and therefore mutable from, this realm.
115	owned := make(map[string]int64, len(fees))
116	for tokenPath, amount := range fees {
117		owned[tokenPath] = amount
118	}
119
120	return s.kvStore.Set(0, rlm, StoreKeyPendingProtocolFees.String(), owned)
121}
122
123// GetPendingProtocolFee returns the pending amount recorded for one token path.
124//
125// Parameters:
126//   - tokenPath: token contract path whose pending protocol fee is queried
127//
128// Returns:
129//   - amount: pending fee amount for tokenPath, or zero when no entry exists
130func (s *routerStore) GetPendingProtocolFee(tokenPath string) int64 {
131	return s.GetPendingProtocolFees()[tokenPath]
132}
133
134// SetPendingProtocolFee updates one token path's pending protocol-fee amount.
135//
136// Parameters:
137//   - _: leading call discriminator; callers pass 0
138//   - rlm: current realm context; must be current and authorized to write storage
139//   - tokenPath: token contract path whose pending amount is updated
140//   - amount: pending protocol-fee amount to record
141//
142// Returns:
143//   - err: nil when updated; an error when the realm is spoofed or lacks KVStore write permission
144func (s *routerStore) SetPendingProtocolFee(_ int, rlm realm, tokenPath string, amount int64) error {
145	if !rlm.IsCurrent() {
146		return errors.New(errSpoofedRealm)
147	}
148
149	if rlm.IsCode() && !s.kvStore.IsWriteAuthorized(rlm.Address()) {
150		return errors.New(store.ErrWritePermissionDenied)
151	}
152
153	s.GetPendingProtocolFees()[tokenPath] = amount
154
155	return nil
156}
157
158// RemovePendingProtocolFee deletes one token path's pending protocol-fee entry.
159//
160// Parameters:
161//   - _: leading call discriminator; callers pass 0
162//   - rlm: current realm context; must be current and authorized to write storage
163//   - tokenPath: token contract path whose pending amount is removed
164//
165// Returns:
166//   - err: nil when removed; an error when the realm is spoofed or lacks KVStore write permission
167func (s *routerStore) RemovePendingProtocolFee(_ int, rlm realm, tokenPath string) error {
168	if !rlm.IsCurrent() {
169		return errors.New(errSpoofedRealm)
170	}
171
172	if rlm.IsCode() && !s.kvStore.IsWriteAuthorized(rlm.Address()) {
173		return errors.New(store.ErrWritePermissionDenied)
174	}
175
176	delete(s.GetPendingProtocolFees(), tokenPath)
177
178	return nil
179}
180
181// NewRouterStore creates a router store backed by the provided KV store.
182//
183// Parameters:
184//   - kvStore: persistent key-value store used for router fee and pending-fee data
185//
186// Returns:
187//   - routerStore: router storage implementation using kvStore
188func NewRouterStore(kvStore store.KVStore) IRouterStore {
189	rs := &routerStore{
190		kvStore: kvStore,
191	}
192
193	return rs
194}