manage_pool_tier_and_warmup.gno
4.77 Kb ยท 176 lines
1package v1
2
3import (
4 "chain"
5 "chain/runtime"
6 "time"
7
8 "gno.land/r/gnoswap/access"
9 "gno.land/r/gnoswap/halt"
10 sr "gno.land/r/gnoswap/staker"
11)
12
13const (
14 NOT_EMISSION_TARGET_TIER uint64 = 0
15)
16
17// SetPoolTier assigns a tier level to a pool for internal GNS emission rewards.
18// Only admin or governance can call this function.
19func (s *stakerV1) SetPoolTier(poolPath string, tier uint64) {
20 halt.AssertIsNotHaltedStaker()
21
22 caller := runtime.PreviousRealm().Address()
23 access.AssertIsAdminOrGovernance(caller)
24
25 assertIsPoolExists(s, poolPath)
26 assertIsValidPoolTier(tier)
27
28 currentTime := time.Now().Unix()
29 s.setPoolTier(poolPath, tier, currentTime)
30
31 previousRealm := runtime.PreviousRealm()
32 chain.Emit(
33 "SetPoolTier",
34 "prevAddr", previousRealm.Address().String(),
35 "prevRealm", previousRealm.PkgPath(),
36 "poolPath", poolPath,
37 "tier", formatUint(tier),
38 "currentTime", formatAnyInt(currentTime),
39 "currentHeight", formatAnyInt(runtime.ChainHeight()),
40 )
41}
42
43// ChangePoolTier modifies the tier level of an existing pool.
44// Only admin or governance can call this function.
45func (s *stakerV1) ChangePoolTier(poolPath string, tier uint64) {
46 halt.AssertIsNotHaltedStaker()
47
48 previousRealm := runtime.PreviousRealm()
49 caller := previousRealm.Address()
50 access.AssertIsAdminOrGovernance(caller)
51
52 assertIsPoolExists(s, poolPath)
53 assertIsValidPoolTier(tier)
54
55 currentTime := time.Now().Unix()
56 previousTier, newTier := s.changePoolTier(poolPath, tier, currentTime)
57
58 chain.Emit(
59 "ChangePoolTier",
60 "prevAddr", caller.String(),
61 "prevRealm", previousRealm.PkgPath(),
62 "poolPath", poolPath,
63 "prevTier", formatUint(previousTier),
64 "newTier", formatUint(newTier),
65 "currentTime", formatAnyInt(currentTime),
66 "currentHeight", formatAnyInt(runtime.ChainHeight()),
67 )
68}
69
70// RemovePoolTier removes a pool from internal GNS emission rewards.
71// Only admin or governance can call this function.
72func (s *stakerV1) RemovePoolTier(poolPath string) {
73 halt.AssertIsNotHaltedStaker()
74
75 previousRealm := runtime.PreviousRealm()
76 caller := previousRealm.Address()
77 access.AssertIsAdminOrGovernance(caller)
78
79 assertIsPoolExists(s, poolPath)
80
81 currentTime := time.Now().Unix()
82 s.removePoolTier(poolPath, currentTime)
83
84 chain.Emit(
85 "RemovePoolTier",
86 "prevAddr", caller.String(),
87 "prevRealm", previousRealm.PkgPath(),
88 "poolPath", poolPath,
89 "currentTime", formatAnyInt(currentTime),
90 "currentHeight", formatAnyInt(runtime.ChainHeight()),
91 )
92}
93
94// SetWarmUp configures the warm-up percentage and duration for rewards.
95// Only admin or governance can call this function.
96func (s *stakerV1) SetWarmUp(pct, timeDuration int64) {
97 halt.AssertIsNotHaltedStaker()
98
99 previousRealm := runtime.PreviousRealm()
100 caller := previousRealm.Address()
101 access.AssertIsAdminOrGovernance(caller)
102
103 s.setWarmUp(pct, timeDuration)
104
105 chain.Emit(
106 "SetWarmUp",
107 "prevAddr", caller.String(),
108 "prevRealm", previousRealm.PkgPath(),
109 "pct", formatAnyInt(pct),
110 "timeDuration", formatAnyInt(timeDuration),
111 )
112}
113
114// setPoolTier internally sets the pool tier.
115func (s *stakerV1) setPoolTier(poolPath string, tier uint64, currentTime int64) {
116 s.emissionAccessor.MintAndDistributeGns()
117
118 pool := s.getPools().GetPoolOrNil(poolPath)
119 if pool == nil {
120 pool = sr.NewPool(poolPath, currentTime)
121 s.getPools().set(poolPath, pool)
122 }
123 poolTier := s.getPoolTier()
124 poolTier.changeTier(runtime.ChainHeight(), currentTime, s.getPools(), poolPath, tier)
125 s.updatePoolTier(poolTier)
126}
127
128// changePoolTier internally changes the pool tier and returns old and new tiers.
129func (s *stakerV1) changePoolTier(poolPath string, tier uint64, currentTime int64) (uint64, uint64) {
130 s.emissionAccessor.MintAndDistributeGns()
131 poolTier := s.getPoolTier()
132 previousTier := poolTier.CurrentTier(poolPath)
133
134 poolTier.changeTier(runtime.ChainHeight(), currentTime, s.getPools(), poolPath, tier)
135 s.updatePoolTier(poolTier)
136
137 return previousTier, tier
138}
139
140// removePoolTier internally removes the pool from tier system.
141func (s *stakerV1) removePoolTier(poolPath string, currentTime int64) {
142 s.emissionAccessor.MintAndDistributeGns()
143
144 poolTier := s.getPoolTier()
145 poolTier.changeTier(runtime.ChainHeight(), currentTime, s.getPools(), poolPath, NOT_EMISSION_TARGET_TIER)
146 s.updatePoolTier(poolTier)
147}
148
149// setWarmUp internally sets the warm-up parameters.
150func (s *stakerV1) setWarmUp(pct, timeDuration int64) {
151 s.emissionAccessor.MintAndDistributeGns()
152
153 warmupTemplate := s.store.GetWarmupTemplate()
154 warmupTemplate = modifyWarmup(warmupTemplate, pctToIndex(pct), timeDuration)
155
156 err := s.store.SetWarmupTemplate(warmupTemplate)
157 if err != nil {
158 panic(err)
159 }
160}
161
162// pctToIndex converts percentage to warmup index.
163func pctToIndex(pct int64) int {
164 switch pct {
165 case 30:
166 return 0
167 case 50:
168 return 1
169 case 70:
170 return 2
171 case 100:
172 return 3
173 default:
174 panic("staker.gno__pctToIndex() || pct is not valid")
175 }
176}