Search Apps Documentation Source Content File Folder Download Copy Actions Download

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}