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

9.96 Kb · 366 lines
  1package protocol_fee
  2
  3import (
  4	"errors"
  5
  6	"gno.land/p/gnoswap/store"
  7	bptree "gno.land/p/nt/bptree/v0"
  8	ufmt "gno.land/p/nt/ufmt/v0"
  9)
 10
 11type StoreKey string
 12
 13func (s StoreKey) String() string {
 14	return string(s)
 15}
 16
 17const (
 18	// By default, devOps will get 0% of the protocol fee (which means gov/staker will get 100% of the protocol fee)
 19	// This percentage can be modified through governance.
 20	StoreKeyDevOpsPct StoreKey = "devOpsPct"
 21
 22	// accumulated amount distributed to gov/staker by token path
 23	StoreKeyAccuToGovStaker StoreKey = "accuToGovStaker" // tokenPath -> amount
 24	StoreKeyAccuToDevOps    StoreKey = "accuToDevOps"    // tokenPath -> amount
 25
 26	// distributedToDevOpsHistory and distributedToGovStakerHistory are used to keep track of the distribution history
 27	StoreKeyDistributedToGovStakerHistory StoreKey = "distributedToGovStakerHistory" // tokenPath -> amount
 28	StoreKeyDistributedToDevOpsHistory    StoreKey = "distributedToDevOpsHistory"    // tokenPath -> amount
 29
 30	// reservedTokens tracks token paths collected but not yet distributed.
 31	StoreKeyReservedTokens StoreKey = "reservedTokens"
 32)
 33
 34const (
 35	defaultDevOpsPct = int64(0)
 36	errSpoofedRealm  = "rlm does not match the current crossing frame"
 37)
 38
 39// NewBPTreeN allocates a BP-tree under /r/gnoswap/protocol_fee's realm context
 40// so tree.Set leaf-slot writes clear the readonly-taint gate regardless of
 41// which realm (protocol_fee/v1, mock, tests) calls Set. Callers must allocate
 42// protocol_fee trees through here rather than bptree.NewBPTreeN directly.
 43func NewBPTreeN(fanout int) *bptree.BPTree {
 44	return bptree.NewBPTreeN(fanout)
 45}
 46
 47type protocolFeeStore struct {
 48	kvStore store.KVStore
 49}
 50
 51// handle devOpsPct store data
 52func (s *protocolFeeStore) HasDevOpsPctStoreKey() bool {
 53	return s.kvStore.Has(StoreKeyDevOpsPct.String())
 54}
 55
 56func (s *protocolFeeStore) InitializeDevOpsPct(_ int, rlm realm) error {
 57	if !rlm.IsCurrent() {
 58		return errors.New(errSpoofedRealm)
 59	}
 60
 61	return s.kvStore.Set(0, rlm, StoreKeyDevOpsPct.String(), defaultDevOpsPct)
 62}
 63
 64func (s *protocolFeeStore) GetDevOpsPct() int64 {
 65	devOpsPct, err := s.kvStore.GetInt64(StoreKeyDevOpsPct.String())
 66	if err != nil {
 67		panic(err)
 68	}
 69
 70	return devOpsPct
 71}
 72
 73func (s *protocolFeeStore) SetDevOpsPct(_ int, rlm realm, pct int64) error {
 74	if !rlm.IsCurrent() {
 75		return errors.New(errSpoofedRealm)
 76	}
 77
 78	return s.kvStore.Set(0, rlm, StoreKeyDevOpsPct.String(), pct)
 79}
 80
 81// handle accuToGovStaker store data
 82func (s *protocolFeeStore) HasAccuToGovStakerStoreKey() bool {
 83	return s.kvStore.Has(StoreKeyAccuToGovStaker.String())
 84}
 85
 86func (s *protocolFeeStore) InitializeAccuToGovStaker(_ int, rlm realm) error {
 87	if !rlm.IsCurrent() {
 88		return errors.New(errSpoofedRealm)
 89	}
 90
 91	return s.kvStore.Set(0, rlm, StoreKeyAccuToGovStaker.String(), NewBPTreeN(16))
 92}
 93
 94func (s *protocolFeeStore) GetAccuToGovStaker() *bptree.BPTree {
 95	accuToGovStaker, err := s.kvStore.GetBPTree(StoreKeyAccuToGovStaker.String())
 96	if err != nil {
 97		panic(err)
 98	}
 99
100	return accuToGovStaker
101}
102
103func (s *protocolFeeStore) GetAccuToGovStakerItem(tokenPath string) (int64, bool) {
104	accuToGovStaker, err := s.kvStore.GetBPTree(StoreKeyAccuToGovStaker.String())
105	if err != nil {
106		panic(err)
107	}
108
109	result := accuToGovStaker.Get(tokenPath)
110	if result == nil {
111		return 0, false
112	}
113
114	amount, ok := result.(int64)
115	if !ok {
116		panic(ufmt.Errorf("failed to cast result to int64: %T", result))
117	}
118
119	return amount, true
120}
121
122func (s *protocolFeeStore) SetAccuToGovStakerItem(_ int, rlm realm, tokenPath string, amount int64) error {
123	if !rlm.IsCurrent() {
124		return errors.New(errSpoofedRealm)
125	}
126
127	accuToGovStaker, err := s.kvStore.GetBPTree(StoreKeyAccuToGovStaker.String())
128	if err != nil {
129		return err
130	}
131
132	accuToGovStaker.Set(tokenPath, amount)
133
134	return s.kvStore.Set(0, rlm, StoreKeyAccuToGovStaker.String(), accuToGovStaker)
135}
136
137// handle accuToDevOps store data
138func (s *protocolFeeStore) HasAccuToDevOpsStoreKey() bool {
139	return s.kvStore.Has(StoreKeyAccuToDevOps.String())
140}
141
142func (s *protocolFeeStore) InitializeAccuToDevOps(_ int, rlm realm) error {
143	if !rlm.IsCurrent() {
144		return errors.New(errSpoofedRealm)
145	}
146
147	return s.kvStore.Set(0, rlm, StoreKeyAccuToDevOps.String(), NewBPTreeN(16))
148}
149
150func (s *protocolFeeStore) GetAccuToDevOps() *bptree.BPTree {
151	accuToDevOps, err := s.kvStore.GetBPTree(StoreKeyAccuToDevOps.String())
152	if err != nil {
153		panic(err)
154	}
155
156	return accuToDevOps
157}
158
159func (s *protocolFeeStore) GetAccuToDevOpsItem(tokenPath string) (int64, bool) {
160	accuToDevOps, err := s.kvStore.GetBPTree(StoreKeyAccuToDevOps.String())
161	if err != nil {
162		panic(err)
163	}
164
165	result := accuToDevOps.Get(tokenPath)
166	if result == nil {
167		return 0, false
168	}
169
170	amount, ok := result.(int64)
171	if !ok {
172		panic(ufmt.Errorf("failed to cast result to int64: %T", result))
173	}
174
175	return amount, true
176}
177
178func (s *protocolFeeStore) SetAccuToDevOpsItem(_ int, rlm realm, tokenPath string, amount int64) error {
179	if !rlm.IsCurrent() {
180		return errors.New(errSpoofedRealm)
181	}
182
183	accuToDevOps, err := s.kvStore.GetBPTree(StoreKeyAccuToDevOps.String())
184	if err != nil {
185		return err
186	}
187
188	accuToDevOps.Set(tokenPath, amount)
189
190	return s.kvStore.Set(0, rlm, StoreKeyAccuToDevOps.String(), accuToDevOps)
191}
192
193// handle distributedToGovStakerHistory store data
194func (s *protocolFeeStore) HasDistributedToGovStakerHistoryStoreKey() bool {
195	return s.kvStore.Has(StoreKeyDistributedToGovStakerHistory.String())
196}
197
198func (s *protocolFeeStore) InitializeDistributedToGovStakerHistory(_ int, rlm realm) error {
199	if !rlm.IsCurrent() {
200		return errors.New(errSpoofedRealm)
201	}
202
203	return s.kvStore.Set(0, rlm, StoreKeyDistributedToGovStakerHistory.String(), NewBPTreeN(16))
204}
205
206func (s *protocolFeeStore) GetDistributedToGovStakerHistory() *bptree.BPTree {
207	distributedToGovStakerHistory, err := s.kvStore.GetBPTree(StoreKeyDistributedToGovStakerHistory.String())
208	if err != nil {
209		panic(err)
210	}
211
212	return distributedToGovStakerHistory
213}
214
215func (s *protocolFeeStore) GetDistributedToGovStakerHistoryItem(tokenPath string) (int64, bool) {
216	distributedToGovStakerHistory, err := s.kvStore.GetBPTree(StoreKeyDistributedToGovStakerHistory.String())
217	if err != nil {
218		panic(err)
219	}
220
221	result := distributedToGovStakerHistory.Get(tokenPath)
222	if result == nil {
223		return 0, false
224	}
225
226	amount, ok := result.(int64)
227	if !ok {
228		panic(ufmt.Errorf("failed to cast result to int64: %T", result))
229	}
230
231	return amount, true
232}
233
234func (s *protocolFeeStore) SetDistributedToGovStakerHistoryItem(_ int, rlm realm, tokenPath string, amount int64) error {
235	if !rlm.IsCurrent() {
236		return errors.New(errSpoofedRealm)
237	}
238
239	distributedToGovStakerHistory, err := s.kvStore.GetBPTree(StoreKeyDistributedToGovStakerHistory.String())
240	if err != nil {
241		return err
242	}
243
244	distributedToGovStakerHistory.Set(tokenPath, amount)
245
246	return s.kvStore.Set(0, rlm, StoreKeyDistributedToGovStakerHistory.String(), distributedToGovStakerHistory)
247}
248
249// handle distributedToDevOpsHistory store data
250func (s *protocolFeeStore) HasDistributedToDevOpsHistoryStoreKey() bool {
251	return s.kvStore.Has(StoreKeyDistributedToDevOpsHistory.String())
252}
253
254func (s *protocolFeeStore) InitializeDistributedToDevOpsHistory(_ int, rlm realm) error {
255	if !rlm.IsCurrent() {
256		return errors.New(errSpoofedRealm)
257	}
258
259	return s.kvStore.Set(0, rlm, StoreKeyDistributedToDevOpsHistory.String(), NewBPTreeN(16))
260}
261
262func (s *protocolFeeStore) GetDistributedToDevOpsHistory() *bptree.BPTree {
263	distributedToDevOpsHistory, err := s.kvStore.GetBPTree(StoreKeyDistributedToDevOpsHistory.String())
264	if err != nil {
265		panic(err)
266	}
267
268	return distributedToDevOpsHistory
269}
270
271func (s *protocolFeeStore) GetDistributedToDevOpsHistoryItem(tokenPath string) (int64, bool) {
272	distributedToDevOpsHistory, err := s.kvStore.GetBPTree(StoreKeyDistributedToDevOpsHistory.String())
273	if err != nil {
274		panic(err)
275	}
276
277	result := distributedToDevOpsHistory.Get(tokenPath)
278	if result == nil {
279		return 0, false
280	}
281
282	amount, ok := result.(int64)
283	if !ok {
284		panic(ufmt.Errorf("failed to cast result to int64: %T", result))
285	}
286
287	return amount, true
288}
289
290func (s *protocolFeeStore) SetDistributedToDevOpsHistoryItem(_ int, rlm realm, tokenPath string, amount int64) error {
291	if !rlm.IsCurrent() {
292		return errors.New(errSpoofedRealm)
293	}
294
295	distributedToDevOpsHistory, err := s.kvStore.GetBPTree(StoreKeyDistributedToDevOpsHistory.String())
296	if err != nil {
297		return err
298	}
299
300	distributedToDevOpsHistory.Set(tokenPath, amount)
301
302	return s.kvStore.Set(0, rlm, StoreKeyDistributedToDevOpsHistory.String(), distributedToDevOpsHistory)
303}
304
305// handle reservedTokens store data
306func (s *protocolFeeStore) HasReservedTokensStoreKey() bool {
307	return s.kvStore.Has(StoreKeyReservedTokens.String())
308}
309
310func (s *protocolFeeStore) InitializeReservedTokens(_ int, rlm realm) error {
311	if !rlm.IsCurrent() {
312		return errors.New(errSpoofedRealm)
313	}
314
315	return s.kvStore.Set(0, rlm, StoreKeyReservedTokens.String(), []string{})
316}
317
318func (s *protocolFeeStore) GetReservedTokens() []string {
319	result, err := s.kvStore.Get(StoreKeyReservedTokens.String())
320	if err != nil {
321		panic(err)
322	}
323
324	reservedTokens, ok := result.([]string)
325	if !ok {
326		panic(ufmt.Errorf("failed to cast result to []string: %T", result))
327	}
328
329	return reservedTokens
330}
331
332func (s *protocolFeeStore) SetReservedTokens(_ int, rlm realm, reservedTokens []string) error {
333	if !rlm.IsCurrent() {
334		return errors.New(errSpoofedRealm)
335	}
336
337	if reservedTokens == nil {
338		return errors.New("reservedTokens is nil")
339	}
340
341	return s.kvStore.Set(0, rlm, StoreKeyReservedTokens.String(), reservedTokens)
342}
343
344func (s *protocolFeeStore) AddReservedToken(_ int, rlm realm, tokenPath string) error {
345	if !rlm.IsCurrent() {
346		return errors.New(errSpoofedRealm)
347	}
348
349	reservedTokens := s.GetReservedTokens()
350	for _, reservedToken := range reservedTokens {
351		if reservedToken == tokenPath {
352			return nil
353		}
354	}
355
356	reservedTokens = append(reservedTokens, tokenPath)
357	return s.SetReservedTokens(0, rlm, reservedTokens)
358}
359
360// NewprotocolFeeStore creates a new protocol fee store instance with the provided KV store.
361// This function is used by the upgrade system to create storage instances for each implementation.
362func NewProtocolFeeStore(kvStore store.KVStore) IProtocolFeeStore {
363	return &protocolFeeStore{
364		kvStore: kvStore,
365	}
366}