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

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}