Search Apps Documentation Source Content File Folder Download Copy Actions Download

store.gno

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