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