Search Apps Documentation Source Content File Folder Download Copy Actions Download

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}