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

18.63 Kb · 706 lines
  1package staker
  2
  3import (
  4	"errors"
  5	"gno.land/p/gnoswap/store"
  6	bptree "gno.land/p/nt/bptree/v0"
  7	ufmt "gno.land/p/nt/ufmt/v0"
  8)
  9
 10type StoreKey string
 11
 12func (s StoreKey) String() string {
 13	return string(s)
 14}
 15
 16const (
 17	StoreKeyDepositGnsAmount                 StoreKey = "depositGnsAmount"
 18	StoreKeyMinimumRewardAmount              StoreKey = "minimumRewardAmount"
 19	StoreKeyDeposits                         StoreKey = "deposits"
 20	StoreKeyExternalIncentives               StoreKey = "externalIncentives"
 21	StoreKeyTotalEmissionSent                StoreKey = "totalEmissionSent"
 22	StoreKeyAllowedTokens                    StoreKey = "allowedTokens"
 23	StoreKeyIncentiveCounter                 StoreKey = "incentiveCounter"
 24	StoreKeyTokenSpecificMinimumRewards      StoreKey = "tokenSpecificMinimumRewards"
 25	StoreKeyUnstakingFee                     StoreKey = "unstakingFee"
 26	StoreKeyPendingProtocolFees              StoreKey = "pendingProtocolFees"
 27	StoreKeyPools                            StoreKey = "pools"
 28	StoreKeyPoolTierMemberships              StoreKey = "poolTierMemberships"
 29	StoreKeyPoolTierRatio                    StoreKey = "poolTierRatio"
 30	StoreKeyPoolTierCounts                   StoreKey = "poolTierCounts"
 31	StoreKeyPoolTierLastRewardCacheTimestamp StoreKey = "poolTierLastRewardCacheTimestamp"
 32	StoreKeyPoolTierCurrentEmission          StoreKey = "poolTierCurrentEmission"
 33	StoreKeyPoolTierGetEmission              StoreKey = "poolTierGetEmission"
 34	StoreKeyPoolTierGetHalvingBlocksInRange  StoreKey = "poolTierGetHalvingBlocksInRange"
 35	StoreKeyWarmupTemplate                   StoreKey = "warmupTemplate"
 36	StoreKeyCurrentSwapBatch                 StoreKey = "currentSwapBatch"
 37	StoreKeyExternalIncentivesByCreationTime StoreKey = "externalIncentivesByCreationTime"
 38)
 39
 40type stakerStore struct {
 41	kvStore store.KVStore
 42}
 43
 44// DepositGnsAmount
 45func (s *stakerStore) HasDepositGnsAmountStoreKey() bool {
 46	return s.kvStore.Has(StoreKeyDepositGnsAmount.String())
 47}
 48
 49func (s *stakerStore) GetDepositGnsAmount() int64 {
 50	result, err := s.kvStore.Get(StoreKeyDepositGnsAmount.String())
 51	if err != nil {
 52		panic(err)
 53	}
 54
 55	amount, ok := result.(int64)
 56	if !ok {
 57		panic(ufmt.Sprintf("failed to cast result to int64: %T", result))
 58	}
 59
 60	return amount
 61}
 62
 63func (s *stakerStore) SetDepositGnsAmount(_ int, rlm realm, amount int64) error {
 64	if !rlm.IsCurrent() {
 65		return errors.New(ErrSpoofedRealm)
 66	}
 67
 68	return s.kvStore.Set(0, rlm, StoreKeyDepositGnsAmount.String(), amount)
 69}
 70
 71// MinimumRewardAmount
 72func (s *stakerStore) HasMinimumRewardAmountStoreKey() bool {
 73	return s.kvStore.Has(StoreKeyMinimumRewardAmount.String())
 74}
 75
 76func (s *stakerStore) GetMinimumRewardAmount() int64 {
 77	result, err := s.kvStore.Get(StoreKeyMinimumRewardAmount.String())
 78	if err != nil {
 79		panic(err)
 80	}
 81
 82	amount, ok := result.(int64)
 83	if !ok {
 84		panic(ufmt.Sprintf("failed to cast result to int64: %T", result))
 85	}
 86
 87	return amount
 88}
 89
 90func (s *stakerStore) SetMinimumRewardAmount(_ int, rlm realm, amount int64) error {
 91	if !rlm.IsCurrent() {
 92		return errors.New(ErrSpoofedRealm)
 93	}
 94
 95	return s.kvStore.Set(0, rlm, StoreKeyMinimumRewardAmount.String(), amount)
 96}
 97
 98// Deposits
 99func (s *stakerStore) HasDepositsStoreKey() bool {
100	return s.kvStore.Has(StoreKeyDeposits.String())
101}
102
103func (s *stakerStore) GetDeposits() *bptree.BPTree {
104	result, err := s.kvStore.Get(StoreKeyDeposits.String())
105	if err != nil {
106		panic(err)
107	}
108
109	deposits, ok := result.(*bptree.BPTree)
110	if !ok {
111		panic(ufmt.Sprintf("failed to cast result to *bptree.BPTree: %T", result))
112	}
113
114	return deposits
115}
116
117func (s *stakerStore) SetDeposits(_ int, rlm realm, deposits *bptree.BPTree) error {
118	if !rlm.IsCurrent() {
119		return errors.New(ErrSpoofedRealm)
120	}
121
122	return s.kvStore.Set(0, rlm, StoreKeyDeposits.String(), deposits)
123}
124
125// ExternalIncentives
126func (s *stakerStore) HasExternalIncentivesStoreKey() bool {
127	return s.kvStore.Has(StoreKeyExternalIncentives.String())
128}
129
130func (s *stakerStore) GetExternalIncentives() *bptree.BPTree {
131	result, err := s.kvStore.Get(StoreKeyExternalIncentives.String())
132	if err != nil {
133		panic(err)
134	}
135
136	incentives, ok := result.(*bptree.BPTree)
137	if !ok {
138		panic(ufmt.Sprintf("failed to cast result to *bptree.BPTree: %T", result))
139	}
140
141	return incentives
142}
143
144func (s *stakerStore) SetExternalIncentives(_ int, rlm realm, incentives *bptree.BPTree) error {
145	if !rlm.IsCurrent() {
146		return errors.New(ErrSpoofedRealm)
147	}
148
149	return s.kvStore.Set(0, rlm, StoreKeyExternalIncentives.String(), incentives)
150}
151
152// TotalEmissionSent
153func (s *stakerStore) HasTotalEmissionSentStoreKey() bool {
154	return s.kvStore.Has(StoreKeyTotalEmissionSent.String())
155}
156
157func (s *stakerStore) GetTotalEmissionSent() int64 {
158	result, err := s.kvStore.Get(StoreKeyTotalEmissionSent.String())
159	if err != nil {
160		panic(err)
161	}
162
163	amount, ok := result.(int64)
164	if !ok {
165		panic(ufmt.Sprintf("failed to cast result to int64: %T", result))
166	}
167
168	return amount
169}
170
171func (s *stakerStore) SetTotalEmissionSent(_ int, rlm realm, amount int64) error {
172	if !rlm.IsCurrent() {
173		return errors.New(ErrSpoofedRealm)
174	}
175
176	return s.kvStore.Set(0, rlm, StoreKeyTotalEmissionSent.String(), amount)
177}
178
179// AllowedTokens
180func (s *stakerStore) HasAllowedTokensStoreKey() bool {
181	return s.kvStore.Has(StoreKeyAllowedTokens.String())
182}
183
184func (s *stakerStore) GetAllowedTokens() []string {
185	result, err := s.kvStore.Get(StoreKeyAllowedTokens.String())
186	if err != nil {
187		panic(err)
188	}
189
190	tokens, ok := result.([]string)
191	if !ok {
192		panic(ufmt.Sprintf("failed to cast result to []string: %T", result))
193	}
194
195	return cloneStringSlice(tokens)
196}
197
198func (s *stakerStore) SetAllowedTokens(_ int, rlm realm, tokens []string) error {
199	if !rlm.IsCurrent() {
200		return errors.New(ErrSpoofedRealm)
201	}
202
203	return s.kvStore.Set(0, rlm, StoreKeyAllowedTokens.String(), tokens)
204}
205
206// AddAllowedToken appends tokenPath to the allowed-tokens list when absent.
207// The store-owned slice is cloned before mutation to avoid readonly-taint panics.
208func (s *stakerStore) AddAllowedToken(_ int, rlm realm, tokenPath string) error {
209	if !rlm.IsCurrent() {
210		return errors.New(ErrSpoofedRealm)
211	}
212
213	tokens := s.GetAllowedTokens()
214	if !contains(tokens, tokenPath) {
215		tokens = append(tokens, tokenPath)
216	}
217
218	return s.kvStore.Set(0, rlm, StoreKeyAllowedTokens.String(), tokens)
219}
220
221// RemoveAllowedToken removes tokenPath from the allowed-tokens list when present.
222// The store-owned slice is cloned before mutation to avoid readonly-taint panics.
223func (s *stakerStore) RemoveAllowedToken(_ int, rlm realm, tokenPath string) error {
224	if !rlm.IsCurrent() {
225		return errors.New(ErrSpoofedRealm)
226	}
227
228	tokens := s.GetAllowedTokens()
229	for i, t := range tokens {
230		if t == tokenPath {
231			tokens = append(tokens[:i], tokens[i+1:]...)
232			break
233		}
234	}
235
236	return s.kvStore.Set(0, rlm, StoreKeyAllowedTokens.String(), tokens)
237}
238
239// IncentiveCounter
240func (s *stakerStore) HasIncentiveCounterStoreKey() bool {
241	return s.kvStore.Has(StoreKeyIncentiveCounter.String())
242}
243
244func (s *stakerStore) GetIncentiveCounter() *Counter {
245	result, err := s.kvStore.Get(StoreKeyIncentiveCounter.String())
246	if err != nil {
247		panic(err)
248	}
249
250	counter, ok := result.(*Counter)
251	if !ok {
252		panic(ufmt.Sprintf("failed to cast result to *Counter: %T", result))
253	}
254
255	return counter
256}
257
258func (s *stakerStore) SetIncentiveCounter(_ int, rlm realm, counter *Counter) error {
259	if !rlm.IsCurrent() {
260		return errors.New(ErrSpoofedRealm)
261	}
262
263	return s.kvStore.Set(0, rlm, StoreKeyIncentiveCounter.String(), counter)
264}
265
266func (s *stakerStore) NextIncentiveID(creator address, timestamp int64) string {
267	counter := s.GetIncentiveCounter()
268	return makeIncentiveID(creator, timestamp, counter.Next())
269}
270
271// TokenSpecificMinimumRewards
272func (s *stakerStore) HasTokenSpecificMinimumRewardsStoreKey() bool {
273	return s.kvStore.Has(StoreKeyTokenSpecificMinimumRewards.String())
274}
275
276func (s *stakerStore) GetTokenSpecificMinimumRewards() map[string]int64 {
277	result, err := s.kvStore.Get(StoreKeyTokenSpecificMinimumRewards.String())
278	if err != nil {
279		panic(err)
280	}
281
282	rewards, ok := result.(map[string]int64)
283	if !ok {
284		panic(ufmt.Sprintf("failed to cast result to map[string]int64: %T", result))
285	}
286
287	return rewards
288}
289
290func (s *stakerStore) SetTokenSpecificMinimumRewards(_ int, rlm realm, rewards map[string]int64) error {
291	if !rlm.IsCurrent() {
292		return errors.New(ErrSpoofedRealm)
293	}
294
295	return s.kvStore.Set(0, rlm, StoreKeyTokenSpecificMinimumRewards.String(), rewards)
296}
297
298// SetTokenSpecificMinimumRewardItem sets a single token's minimum reward amount.
299func (s *stakerStore) SetTokenSpecificMinimumRewardItem(_ int, rlm realm, tokenPath string, amount int64) error {
300	if !rlm.IsCurrent() {
301		return errors.New(ErrSpoofedRealm)
302	}
303
304	rewards := s.GetTokenSpecificMinimumRewards()
305
306	owned := make(map[string]int64)
307	for k, v := range rewards {
308		owned[k] = v
309	}
310
311	owned[tokenPath] = amount
312
313	return s.kvStore.Set(0, rlm, StoreKeyTokenSpecificMinimumRewards.String(), owned)
314}
315
316// RemoveTokenSpecificMinimumRewardItem removes a single token's minimum reward entry.
317func (s *stakerStore) RemoveTokenSpecificMinimumRewardItem(_ int, rlm realm, tokenPath string) error {
318	if !rlm.IsCurrent() {
319		return errors.New(ErrSpoofedRealm)
320	}
321
322	rewards := s.GetTokenSpecificMinimumRewards()
323
324	owned := make(map[string]int64)
325	for k, v := range rewards {
326		if k == tokenPath {
327			continue
328		}
329
330		owned[k] = v
331	}
332
333	return s.kvStore.Set(0, rlm, StoreKeyTokenSpecificMinimumRewards.String(), owned)
334}
335
336// UnstakingFee
337func (s *stakerStore) HasUnstakingFeeStoreKey() bool {
338	return s.kvStore.Has(StoreKeyUnstakingFee.String())
339}
340
341func (s *stakerStore) GetUnstakingFee() uint64 {
342	result, err := s.kvStore.Get(StoreKeyUnstakingFee.String())
343	if err != nil {
344		panic(err)
345	}
346
347	fee, ok := result.(uint64)
348	if !ok {
349		panic(ufmt.Sprintf("failed to cast result to uint64: %T", result))
350	}
351
352	return fee
353}
354
355func (s *stakerStore) SetUnstakingFee(_ int, rlm realm, fee uint64) error {
356	if !rlm.IsCurrent() {
357		return errors.New(ErrSpoofedRealm)
358	}
359
360	return s.kvStore.Set(0, rlm, StoreKeyUnstakingFee.String(), fee)
361}
362
363func (s *stakerStore) HasPendingProtocolFeesStoreKey() bool {
364	return s.kvStore.Has(StoreKeyPendingProtocolFees.String())
365}
366
367func (s *stakerStore) GetPendingProtocolFees() map[string]int64 {
368	result, err := s.kvStore.Get(StoreKeyPendingProtocolFees.String())
369	if err != nil {
370		panic(err)
371	}
372
373	fees, ok := result.(map[string]int64)
374	if !ok {
375		panic(ufmt.Sprintf("failed to cast result to map[string]int64: %T", result))
376	}
377
378	return fees
379}
380
381func (s *stakerStore) SetPendingProtocolFees(_ int, rlm realm, fees map[string]int64) error {
382	if !rlm.IsCurrent() {
383		return errors.New(ErrSpoofedRealm)
384	}
385
386	return s.kvStore.Set(0, rlm, StoreKeyPendingProtocolFees.String(), fees)
387}
388
389// Pools
390func (s *stakerStore) HasPoolsStoreKey() bool {
391	return s.kvStore.Has(StoreKeyPools.String())
392}
393
394func (s *stakerStore) GetPools() *bptree.BPTree {
395	result, err := s.kvStore.Get(StoreKeyPools.String())
396	if err != nil {
397		panic(err)
398	}
399
400	pools, ok := result.(*bptree.BPTree)
401	if !ok {
402		panic(ufmt.Sprintf("failed to cast result to *bptree.BPTree: %T", result))
403	}
404
405	return pools
406}
407
408func (s *stakerStore) SetPools(_ int, rlm realm, pools *bptree.BPTree) error {
409	if !rlm.IsCurrent() {
410		return errors.New(ErrSpoofedRealm)
411	}
412
413	return s.kvStore.Set(0, rlm, StoreKeyPools.String(), pools)
414}
415
416// PoolTierMemberships
417func (s *stakerStore) HasPoolTierMembershipsStoreKey() bool {
418	return s.kvStore.Has(StoreKeyPoolTierMemberships.String())
419}
420
421func (s *stakerStore) GetPoolTierMemberships() *bptree.BPTree {
422	result, err := s.kvStore.Get(StoreKeyPoolTierMemberships.String())
423	if err != nil {
424		panic(err)
425	}
426
427	memberships, ok := result.(*bptree.BPTree)
428	if !ok {
429		panic(ufmt.Sprintf("failed to cast result to *bptree.BPTree: %T", result))
430	}
431
432	return memberships
433}
434
435func (s *stakerStore) SetPoolTierMemberships(_ int, rlm realm, memberships *bptree.BPTree) error {
436	if !rlm.IsCurrent() {
437		return errors.New(ErrSpoofedRealm)
438	}
439
440	return s.kvStore.Set(0, rlm, StoreKeyPoolTierMemberships.String(), memberships)
441}
442
443// PoolTierRatio
444func (s *stakerStore) HasPoolTierRatioStoreKey() bool {
445	return s.kvStore.Has(StoreKeyPoolTierRatio.String())
446}
447
448func (s *stakerStore) GetPoolTierRatio() TierRatio {
449	result, err := s.kvStore.Get(StoreKeyPoolTierRatio.String())
450	if err != nil {
451		panic(err)
452	}
453
454	ratio, ok := result.(TierRatio)
455	if !ok {
456		panic(ufmt.Sprintf("failed to cast result to TierRatio: %T", result))
457	}
458
459	return ratio
460}
461
462func (s *stakerStore) SetPoolTierRatio(_ int, rlm realm, ratio TierRatio) error {
463	if !rlm.IsCurrent() {
464		return errors.New(ErrSpoofedRealm)
465	}
466
467	return s.kvStore.Set(0, rlm, StoreKeyPoolTierRatio.String(), ratio)
468}
469
470// PoolTierCounts
471func (s *stakerStore) HasPoolTierCountsStoreKey() bool {
472	return s.kvStore.Has(StoreKeyPoolTierCounts.String())
473}
474
475func (s *stakerStore) GetPoolTierCounts() [AllTierCount]uint64 {
476	result, err := s.kvStore.Get(StoreKeyPoolTierCounts.String())
477	if err != nil {
478		panic(err)
479	}
480
481	counts, ok := result.([AllTierCount]uint64)
482	if !ok {
483		panic(ufmt.Sprintf("failed to cast result to [AllTierCount]uint64: %T", result))
484	}
485
486	return counts
487}
488
489func (s *stakerStore) SetPoolTierCounts(_ int, rlm realm, counts [AllTierCount]uint64) error {
490	if !rlm.IsCurrent() {
491		return errors.New(ErrSpoofedRealm)
492	}
493
494	return s.kvStore.Set(0, rlm, StoreKeyPoolTierCounts.String(), counts)
495}
496
497// PoolTierLastRewardCacheTimestamp
498func (s *stakerStore) HasPoolTierLastRewardCacheTimestampStoreKey() bool {
499	return s.kvStore.Has(StoreKeyPoolTierLastRewardCacheTimestamp.String())
500}
501
502func (s *stakerStore) GetPoolTierLastRewardCacheTimestamp() int64 {
503	result, err := s.kvStore.Get(StoreKeyPoolTierLastRewardCacheTimestamp.String())
504	if err != nil {
505		panic(err)
506	}
507
508	timestamp, ok := result.(int64)
509	if !ok {
510		panic(ufmt.Sprintf("failed to cast result to int64: %T", result))
511	}
512
513	return timestamp
514}
515
516func (s *stakerStore) SetPoolTierLastRewardCacheTimestamp(_ int, rlm realm, timestamp int64) error {
517	if !rlm.IsCurrent() {
518		return errors.New(ErrSpoofedRealm)
519	}
520
521	return s.kvStore.Set(0, rlm, StoreKeyPoolTierLastRewardCacheTimestamp.String(), timestamp)
522}
523
524// PoolTierCurrentEmission
525func (s *stakerStore) HasPoolTierCurrentEmissionStoreKey() bool {
526	return s.kvStore.Has(StoreKeyPoolTierCurrentEmission.String())
527}
528
529func (s *stakerStore) GetPoolTierCurrentEmission() int64 {
530	result, err := s.kvStore.Get(StoreKeyPoolTierCurrentEmission.String())
531	if err != nil {
532		panic(err)
533	}
534
535	emission, ok := result.(int64)
536	if !ok {
537		panic(ufmt.Sprintf("failed to cast result to int64: %T", result))
538	}
539
540	return emission
541}
542
543func (s *stakerStore) SetPoolTierCurrentEmission(_ int, rlm realm, emission int64) error {
544	if !rlm.IsCurrent() {
545		return errors.New(ErrSpoofedRealm)
546	}
547
548	return s.kvStore.Set(0, rlm, StoreKeyPoolTierCurrentEmission.String(), emission)
549}
550
551// PoolTierGetEmission
552func (s *stakerStore) HasPoolTierGetEmissionStoreKey() bool {
553	return s.kvStore.Has(StoreKeyPoolTierGetEmission.String())
554}
555
556func (s *stakerStore) GetPoolTierGetEmission() func() int64 {
557	result, err := s.kvStore.Get(StoreKeyPoolTierGetEmission.String())
558	if err != nil {
559		panic(err)
560	}
561
562	fn, ok := result.(func() int64)
563	if !ok {
564		panic(ufmt.Sprintf("failed to cast result to func() int64: %T", result))
565	}
566
567	return fn
568}
569
570func (s *stakerStore) SetPoolTierGetEmission(_ int, rlm realm, fn func() int64) error {
571	if !rlm.IsCurrent() {
572		return errors.New(ErrSpoofedRealm)
573	}
574
575	return s.kvStore.Set(0, rlm, StoreKeyPoolTierGetEmission.String(), fn)
576}
577
578// PoolTierGetHalvingBlocksInRange
579func (s *stakerStore) HasPoolTierGetHalvingBlocksInRangeStoreKey() bool {
580	return s.kvStore.Has(StoreKeyPoolTierGetHalvingBlocksInRange.String())
581}
582
583func (s *stakerStore) GetPoolTierGetHalvingBlocksInRange() func(start, end int64) ([]int64, []int64) {
584	result, err := s.kvStore.Get(StoreKeyPoolTierGetHalvingBlocksInRange.String())
585	if err != nil {
586		panic(err)
587	}
588
589	fn, ok := result.(func(start, end int64) ([]int64, []int64))
590	if !ok {
591		panic(ufmt.Sprintf("failed to cast result to func(start, end int64) ([]int64, []int64): %T", result))
592	}
593
594	return fn
595}
596
597func (s *stakerStore) SetPoolTierGetHalvingBlocksInRange(_ int, rlm realm, fn func(start, end int64) ([]int64, []int64)) error {
598	if !rlm.IsCurrent() {
599		return errors.New(ErrSpoofedRealm)
600	}
601
602	return s.kvStore.Set(0, rlm, StoreKeyPoolTierGetHalvingBlocksInRange.String(), fn)
603}
604
605func (s *stakerStore) HasWarmupTemplateStoreKey() bool {
606	return s.kvStore.Has(StoreKeyWarmupTemplate.String())
607}
608
609func (s *stakerStore) GetWarmupTemplate() []Warmup {
610	result, err := s.kvStore.Get(StoreKeyWarmupTemplate.String())
611	if err != nil {
612		panic(err)
613	}
614
615	warmups, ok := result.([]Warmup)
616	if !ok {
617		panic(ufmt.Sprintf("failed to cast result to []Warmup: %T", result))
618	}
619
620	return cloneWarmups(warmups)
621}
622
623func (s *stakerStore) SetWarmupTemplate(_ int, rlm realm, warmups []Warmup) error {
624	if !rlm.IsCurrent() {
625		return errors.New(ErrSpoofedRealm)
626	}
627
628	return s.kvStore.Set(0, rlm, StoreKeyWarmupTemplate.String(), warmups)
629}
630
631// CurrentSwapBatch
632func (s *stakerStore) HasCurrentSwapBatchStoreKey() bool {
633	return s.kvStore.Has(StoreKeyCurrentSwapBatch.String())
634}
635
636func (s *stakerStore) GetCurrentSwapBatch() *SwapBatchProcessor {
637	result, err := s.kvStore.Get(StoreKeyCurrentSwapBatch.String())
638	if err != nil {
639		panic(err)
640	}
641
642	batch, ok := result.(*SwapBatchProcessor)
643	if !ok {
644		panic(ufmt.Sprintf("failed to cast result to *SwapBatchProcessor: %T", result))
645	}
646
647	return batch
648}
649
650func (s *stakerStore) SetCurrentSwapBatch(_ int, rlm realm, batch *SwapBatchProcessor) error {
651	if !rlm.IsCurrent() {
652		return errors.New(ErrSpoofedRealm)
653	}
654
655	return s.kvStore.Set(0, rlm, StoreKeyCurrentSwapBatch.String(), batch)
656}
657
658// ExternalIncentivesByCreationTime
659// key: timestamp -> value: *bptree.BPTree (poolPath -> []string)
660func (s *stakerStore) HasExternalIncentivesByCreationTimeStoreKey() bool {
661	return s.kvStore.Has(StoreKeyExternalIncentivesByCreationTime.String())
662}
663
664func (s *stakerStore) GetExternalIncentivesByCreationTime() *UintTree {
665	result, err := s.kvStore.Get(StoreKeyExternalIncentivesByCreationTime.String())
666	if err != nil {
667		panic(err)
668	}
669
670	tree, ok := result.(*UintTree)
671	if !ok {
672		panic(ufmt.Sprintf("failed to cast result to *UintTree: %T", result))
673	}
674
675	return tree
676}
677
678func (s *stakerStore) SetExternalIncentivesByCreationTime(_ int, rlm realm, tree *UintTree) error {
679	if !rlm.IsCurrent() {
680		return errors.New(ErrSpoofedRealm)
681	}
682
683	return s.kvStore.Set(0, rlm, StoreKeyExternalIncentivesByCreationTime.String(), tree)
684}
685
686// NewStakerStore creates a new staker store instance with the provided KV store.
687// This function is used by the upgrade system to create storage instances for each implementation.
688func NewStakerStore(kvStore store.KVStore) IStakerStore {
689	return &stakerStore{
690		kvStore: kvStore,
691	}
692}
693
694func makeIncentiveID(creator address, timestamp int64, index int64) string {
695	return ufmt.Sprintf("%s:%d:%d", creator.String(), timestamp, index)
696}
697
698func contains(items []string, item string) bool {
699	for _, i := range items {
700		if i == item {
701			return true
702		}
703	}
704
705	return false
706}