Kind Realm (renderable)
Name v1
Namespace gnoswap / staker
Exported functions 14
Module gno.land/r/gnoswap/staker/v1
gno 0.9 manage_pool_tier_and_warmup.gno gno
⧉
1 package staker 2 3 import ( 4 "chain" 5 "chain/runtime" 6 "time" 7 8 NewDepositResolver (deposit *gno.land/r/gnoswap/staker.Deposit) *gno.land/r/gnoswap/staker/v1.DepositResolver
NewDeposits () *gno.land/r/gnoswap/staker/v1.Deposits
NewExternalIncentiveResolver (externalIncentive *gno.land/r/gnoswap/staker.ExternalIncentive) *gno.land/r/gnoswap/staker/v1.ExternalIncentiveResolver
NewExternalIncentives () *gno.land/r/gnoswap/staker/v1.ExternalIncentives
NewIncentivesResolver (incentives *gno.land/r/gnoswap/staker.Incentives) *gno.land/r/gnoswap/staker/v1.IncentivesResolver
NewPoolResolver (pool *gno.land/r/gnoswap/staker.Pool) *gno.land/r/gnoswap/staker/v1.PoolResolver
NewPools () *gno.land/r/gnoswap/staker/v1.Pools
NewPoolTier (pools *gno.land/r/gnoswap/staker/v1.Pools, currentTime int64, initialPoolPath string, getEmission func() (int64, .uverse.error), getHalvingBlocksInRange func(int64, int64) ([]int64, []int64, .uverse.error)) *gno.land/r/gnoswap/staker/v1.PoolTier
NewPoolTierBy (membership *gno.land/p/nt/bptree/v0.BPTree, tierRatio struct{Tier1 uint64; Tier2 uint64; Tier3 uint64}, counts [4]uint64, lastRewardCacheTimestamp int64, currentEmission int64, getEmission func() (int64, .uverse.error), getHalvingBlocksInRange func(int64, int64) ([]int64, []int64, .uverse.error)) *gno.land/r/gnoswap/staker/v1.PoolTier
NewStakerV1 (stakerStore interface {AddAllowedToken func(int, .uverse.realm, string) .uverse.error; AddDeniedRewardToken func(int, .uverse.realm, string) .uverse.error; GetAllowedTokens func() []string; GetCurrentSwapBatch func() *gno.land/r/gnoswap/staker.SwapBatchProcessor; GetDeniedRewardTokens func() []string; GetDepositGnsAmount func() int64; GetDeposits func() *gno.land/p/nt/bptree/v0.BPTree; GetExternalIncentives func() *gno.land/p/nt/bptree/v0.BPTree; GetIncentiveCounter func() *gno.land/r/gnoswap/staker.Counter; GetMinimumRewardAmount func() int64; GetPendingProtocolFee func(string) int64; GetPendingProtocolFees func() map[string]int64; GetPoolTierCounts func() [4]uint64; GetPoolTierCurrentEmission func() int64; GetPoolTierGetEmission func() func() (int64, .uverse.error); GetPoolTierGetHalvingBlocksInRange func() func(int64, int64) ([]int64, []int64, .uverse.error); GetPoolTierLastRewardCacheTimestamp func() int64; GetPoolTierMemberships func() *gno.land/p/nt/bptree/v0.BPTree; GetPoolTierRatio func() gno.land/r/gnoswap/staker.TierRatio; GetPools func() *gno.land/p/nt/bptree/v0.BPTree; GetTokenSpecificMinimumRewards func() map[string]int64; GetTotalEmissionSent func() int64; GetUncollectedIncentiveCounts func() *gno.land/p/nt/bptree/v0.BPTree; GetUnstakedPositions func() *gno.land/p/nt/bptree/v0.BPTree; GetUnstakingFee func() uint64; GetWarmupTemplate func() []gno.land/r/gnoswap/staker.Warmup; HasAllowedTokensStoreKey func() bool; HasCurrentSwapBatchStoreKey func() bool; HasDeniedRewardTokensStoreKey func() bool; HasDepositGnsAmountStoreKey func() bool; HasDepositsStoreKey func() bool; HasExternalIncentivesStoreKey func() bool; HasIncentiveCounterStoreKey func() bool; HasMinimumRewardAmountStoreKey func() bool; HasPendingProtocolFeesStoreKey func() bool; HasPoolTierCountsStoreKey func() bool; HasPoolTierCurrentEmissionStoreKey func() bool; HasPoolTierGetEmissionStoreKey func() bool; HasPoolTierGetHalvingBlocksInRangeStoreKey func() bool; HasPoolTierLastRewardCacheTimestampStoreKey func() bool; HasPoolTierMembershipsStoreKey func() bool; HasPoolTierRatioStoreKey func() bool; HasPoolsStoreKey func() bool; HasTokenSpecificMinimumRewardsStoreKey func() bool; HasTotalEmissionSentStoreKey func() bool; HasUncollectedIncentiveCountsStoreKey func() bool; HasUnstakedPositionsStoreKey func() bool; HasUnstakingFeeStoreKey func() bool; HasWarmupTemplateStoreKey func() bool; NextIncentiveID func(.uverse.address, int64) string; RemoveAllowedToken func(int, .uverse.realm, string) .uverse.error; RemoveDeniedRewardToken func(int, .uverse.realm, string) .uverse.error; RemovePendingProtocolFee func(int, .uverse.realm, string) .uverse.error; RemoveTokenSpecificMinimumRewardItem func(int, .uverse.realm, string) .uverse.error; SetAllowedTokens func(int, .uverse.realm, []string) .uverse.error; SetCurrentSwapBatch func(int, .uverse.realm, *gno.land/r/gnoswap/staker.SwapBatchProcessor) .uverse.error; SetDepositGnsAmount func(int, .uverse.realm, int64) .uverse.error; SetDeposits func(int, .uverse.realm, *gno.land/p/nt/bptree/v0.BPTree) .uverse.error; SetExternalIncentives func(int, .uverse.realm, *gno.land/p/nt/bptree/v0.BPTree) .uverse.error; SetIncentiveCounter func(int, .uverse.realm, *gno.land/r/gnoswap/staker.Counter) .uverse.error; SetMinimumRewardAmount func(int, .uverse.realm, int64) .uverse.error; SetPendingProtocolFee func(int, .uverse.realm, string, int64) .uverse.error; SetPendingProtocolFees func(int, .uverse.realm, map[string]int64) .uverse.error; SetPoolTierCounts func(int, .uverse.realm, [4]uint64) .uverse.error; SetPoolTierCurrentEmission func(int, .uverse.realm, int64) .uverse.error; SetPoolTierGetEmission func(int, .uverse.realm, func() (int64, .uverse.error)) .uverse.error; SetPoolTierGetHalvingBlocksInRange func(int, .uverse.realm, func(int64, int64) ([]int64, []int64, .uverse.error)) .uverse.error; SetPoolTierLastRewardCacheTimestamp func(int, .uverse.realm, int64) .uverse.error; SetPoolTierMemberships func(int, .uverse.realm, *gno.land/p/nt/bptree/v0.BPTree) .uverse.error; SetPoolTierRatio func(int, .uverse.realm, gno.land/r/gnoswap/staker.TierRatio) .uverse.error; SetPools func(int, .uverse.realm, *gno.land/p/nt/bptree/v0.BPTree) .uverse.error; SetTokenSpecificMinimumRewardItem func(int, .uverse.realm, string, int64) .uverse.error; SetTokenSpecificMinimumRewards func(int, .uverse.realm, map[string]int64) .uverse.error; SetTotalEmissionSent func(int, .uverse.realm, int64) .uverse.error; SetUncollectedIncentiveCounts func(int, .uverse.realm, *gno.land/p/nt/bptree/v0.BPTree) .uverse.error; SetUnstakedPositions func(int, .uverse.realm, *gno.land/p/nt/bptree/v0.BPTree) .uverse.error; SetUnstakingFee func(int, .uverse.realm, uint64) .uverse.error; SetWarmupTemplate func(int, .uverse.realm, []gno.land/r/gnoswap/staker.Warmup) .uverse.error}, poolAccessor interface {ExistsPoolPath func(string) bool; GetSlot0SqrtPriceX96 func(string) string; GetSlot0Tick func(string) int32; SetSwapEndHook func(int, .uverse.realm, func(int, .uverse.realm, string) .uverse.error); SetSwapStartHook func(int, .uverse.realm, func(int, .uverse.realm, string, int64)); SetTickCrossHook func(int, .uverse.realm, func(int, .uverse.realm, string, int32, bool, int64))}, emissionAccessor interface {GetStakerEmissionAmountPerSecond func() (int64, .uverse.error); GetStakerEmissionAmountPerSecondInRange func(int64, int64) ([]int64, []int64, .uverse.error); MintAndDistributeGns func(int, .uverse.realm) (int64, bool); SetOnDistributionPctChangeCallback func(int, .uverse.realm, func(int, .uverse.realm, int64))}, nftAccessor interface {Approve func(int, .uverse.realm, .uverse.address, gno.land/p/nt/grc721/v0.TokenID) .uverse.error; Burn func(int, .uverse.realm, gno.land/p/nt/grc721/v0.TokenID); Exists func(gno.land/p/nt/grc721/v0.TokenID) bool; Mint func(int, .uverse.realm, .uverse.address, gno.land/p/nt/grc721/v0.TokenID) gno.land/p/nt/grc721/v0.TokenID; MustOwnerOf func(gno.land/p/nt/grc721/v0.TokenID) .uverse.address; OwnerOf func(gno.land/p/nt/grc721/v0.TokenID) (.uverse.address, .uverse.error); TotalSupply func() int64; TransferFrom func(int, .uverse.realm, .uverse.address, .uverse.address, gno.land/p/nt/grc721/v0.TokenID) .uverse.error})
NewTickCrossEventInfo (tickID int32, stakedLiquidityGross *gno.land/p/gnoswap/uint256/v1.Uint, stakedLiquidityDelta *gno.land/p/gnoswap/int256/v1.Int, outsideAccumulation *gno.land/p/gnoswap/uint256/v1.Uint) *gno.land/r/gnoswap/staker/v1.tickCrossEventInfo
NewTickResolver (tick *gno.land/r/gnoswap/staker.Tick) *gno.land/r/gnoswap/staker/v1.TickResolver
NewUnstakedPositions () *gno.land/r/gnoswap/staker/v1.UnstakedPositions
TierRatioFromCounts (tier1Count uint64, tier2Count uint64, tier3Count uint64) struct{Tier1 uint64; Tier2 uint64; Tier3 uint64}
Signatures reconstructed verbatim from vm/qfuncs — interface params keep their inline definitions.
This realm does not provide renderable output (vm/qrender → NoRenderDeclError).
View on gnoweb ↗ vm/qrender output, sanitized (docs/render-security.md) and displayed in an empty-sandbox iframe — scripts, forms and popups cannot run. Links stay inert in-preview; right-click to open.
"gno.land/p/gnoswap/utils/v1"
9
10 "gno.land/r/gnoswap/access/v1"
11 "gno.land/r/gnoswap/halt/v1"
12 sr "gno.land/r/gnoswap/staker"
13 )
14
15 const (
16 NOT_EMISSION_TARGET_TIER uint64 = 0
17 )
18
19 // SetPoolTier assigns a tier level to a pool for internal GNS emission rewards.
20 // Only admin or governance can call this function.
21 //
22 // Parameters:
23 // - _: Noncrossing implementation-call discriminator; pass 0.
24 // - rlm: Current realm context forwarded unchanged by the staker proxy.
25 // - poolPath: Existing pool path whose internal GNS emission tier is being assigned.
26 // - tier: Emission tier to assign; valid values are below AllTierCount, including 0 for no emission target.
27 func (s *stakerV1) SetPoolTier(_ int , rlm realm, poolPath string , tier uint64 ) {
28 access.AssertIsRlmCurrent( 0 , rlm)
29
30 halt.AssertIsNotHaltedStaker()
31
32 caller := rlm.Previous().Address()
33 access.AssertIsAdminOrGovernance(caller)
34
35 assertIsPoolExists(s, poolPath)
36 assertIsValidPoolTier(tier)
37
38 // If the tier is already set, do nothing
39 poolTier := s.getPoolTier()
40 previousTier := poolTier.CurrentTier(poolPath)
41 if previousTier == tier {
42 return
43 }
44
45 currentTime := time.Now().Unix()
46 rewardPerSecond, tierRewards := s.setPoolTier( 0 , rlm, poolPath, tier, currentTime)
47
48 previousRealm := rlm.Previous()
49 emitSetPoolTier(
50 previousRealm.Address().String(),
51 previousRealm.PkgPath(),
52 poolPath,
53 tier,
54 rewardPerSecond,
55 tierRewards,
56 poolTier.counts,
57 currentTime,
58 )
59 }
60
61 // ChangePoolTier modifies the tier level of an existing pool.
62 // Only admin or governance can call this function.
63 //
64 // Parameters:
65 // - _: Noncrossing implementation-call discriminator; pass 0.
66 // - rlm: Current realm context forwarded unchanged by the staker proxy.
67 // - poolPath: Existing pool path whose emission tier is being changed.
68 // - tier: Replacement emission tier; values at or above AllTierCount are rejected.
69 func (s *stakerV1) ChangePoolTier(_ int , rlm realm, poolPath string , tier uint64 ) {
70 access.AssertIsRlmCurrent( 0 , rlm)
71
72 halt.AssertIsNotHaltedStaker()
73
74 previousRealm := rlm.Previous()
75 caller := previousRealm.Address()
76 access.AssertIsAdminOrGovernance(caller)
77
78 assertIsPoolExists(s, poolPath)
79 assertIsValidPoolTier(tier)
80
81 poolTier := s.getPoolTier()
82
83 // If the tier is already set, do nothing
84 previousTier := poolTier.CurrentTier(poolPath)
85 if previousTier == tier {
86 return
87 }
88
89 currentTime := time.Now().Unix()
90 previousTier, newTier, rewardPerSecond, tierRewards := s.changePoolTier( 0 , rlm, poolPath, tier, currentTime)
91
92 chain.Emit(
93 "ChangePoolTier" ,
94 "prevAddr" , caller.String(),
95 "prevRealm" , previousRealm.PkgPath(),
96 "poolPath" , poolPath,
97 "prevTier" , utils.FormatUint(previousTier),
98 "newTier" , utils.FormatUint(newTier),
99 "rewardPerSecond" , utils.FormatInt(rewardPerSecond),
100 "tier1RewardPerSecond" , utils.FormatInt(tierRewards[Tier1]),
101 "tier2RewardPerSecond" , utils.FormatInt(tierRewards[Tier2]),
102 "tier3RewardPerSecond" , utils.FormatInt(tierRewards[Tier3]),
103 "tier1Count" , utils.FormatUint(poolTier.counts[Tier1]),
104 "tier2Count" , utils.FormatUint(poolTier.counts[Tier2]),
105 "tier3Count" , utils.FormatUint(poolTier.counts[Tier3]),
106 "currentTime" , utils.FormatInt(currentTime),
107 "currentHeight" , utils.FormatInt(runtime.ChainHeight()),
108 )
109 }
110
111 // RemovePoolTier removes a pool from internal GNS emission rewards.
112 // Only admin or governance can call this function.
113 //
114 // Parameters:
115 // - _: Noncrossing implementation-call discriminator; pass 0.
116 // - rlm: Current realm context forwarded unchanged by the staker proxy.
117 // - poolPath: Existing pool path to remove from the emission-tier accounting.
118 func (s *stakerV1) RemovePoolTier(_ int , rlm realm, poolPath string ) {
119 access.AssertIsRlmCurrent( 0 , rlm)
120
121 halt.AssertIsNotHaltedStaker()
122
123 previousRealm := rlm.Previous()
124 caller := previousRealm.Address()
125 access.AssertIsAdminOrGovernance(caller)
126
127 assertIsPoolExists(s, poolPath)
128
129 poolTier := s.getPoolTier()
130
131 // If the tier is already set, do nothing
132 previousTier := poolTier.CurrentTier(poolPath)
133 if previousTier == NOT_EMISSION_TARGET_TIER {
134 return
135 }
136
137 currentTime := time.Now().Unix()
138 rewardPerSecond, tierRewards := s.removePoolTier( 0 , rlm, poolPath, currentTime)
139
140 chain.Emit(
141 "RemovePoolTier" ,
142 "prevAddr" , caller.String(),
143 "prevRealm" , previousRealm.PkgPath(),
144 "poolPath" , poolPath,
145 "rewardPerSecond" , utils.FormatInt(rewardPerSecond),
146 "tier1RewardPerSecond" , utils.FormatInt(tierRewards[Tier1]),
147 "tier2RewardPerSecond" , utils.FormatInt(tierRewards[Tier2]),
148 "tier3RewardPerSecond" , utils.FormatInt(tierRewards[Tier3]),
149 "tier1Count" , utils.FormatUint(poolTier.counts[Tier1]),
150 "tier2Count" , utils.FormatUint(poolTier.counts[Tier2]),
151 "tier3Count" , utils.FormatUint(poolTier.counts[Tier3]),
152 "currentTime" , utils.FormatInt(currentTime),
153 "currentHeight" , utils.FormatInt(runtime.ChainHeight()),
154 )
155 }
156
157 // SetWarmUp configures the duration for the warm-up tier selected by its fixed ratio.
158 // Finite tiers are capped at 365 days; the final 100% tier must remain math.MaxInt64.
159 // Only admin or governance can call this function.
160 //
161 // Parameters:
162 // - _: Noncrossing implementation-call discriminator; pass 0.
163 // - rlm: Current realm context forwarded unchanged by the staker proxy.
164 // - pct: Warm-up tier percentage selecting one of the configured 30%, 50%, 70%, or 100% templates.
165 // - timeDuration: Warm-up duration in seconds; finite tiers are capped at 365 days while the 100% tier uses the maximum int64 duration.
166 func (s *stakerV1) SetWarmUp(_ int , rlm realm, pct, timeDuration int64 ) {
167 access.AssertIsRlmCurrent( 0 , rlm)
168
169 halt.AssertIsNotHaltedStaker()
170
171 previousRealm := rlm.Previous()
172 caller := previousRealm.Address()
173 access.AssertIsAdminOrGovernance(caller)
174
175 s.setWarmUp( 0 , rlm, pct, timeDuration)
176
177 chain.Emit(
178 "SetWarmUp" ,
179 "prevAddr" , caller.String(),
180 "prevRealm" , previousRealm.PkgPath(),
181 "pct" , utils.FormatInt(pct),
182 "timeDuration" , utils.FormatInt(timeDuration),
183 )
184 }
185
186 // setPoolTier internally sets the pool tier.
187 func (s *stakerV1) setPoolTier(_ int , rlm realm, poolPath string , tier uint64 , currentTime int64 ) ( int64 , map [ uint64 ] int64 ) {
188 s.emissionAccessor.MintAndDistributeGns( 0 , rlm)
189
190 pool := s.getPools().GetPoolOrNil(poolPath)
191 if pool == nil {
192 pool = sr.NewPool(poolPath, currentTime)
193 s.getPools().set(poolPath, pool)
194 }
195 poolTier := s.getPoolTier()
196 tierRewards := poolTier.changeTier(currentTime, s.getPools(), poolPath, tier)
197
198 s.updatePoolTier( 0 , rlm, poolTier)
199
200 return poolTier.currentEmission, tierRewards
201 }
202
203 // changePoolTier internally changes the pool tier and returns old and new tiers.
204 func (s *stakerV1) changePoolTier(_ int , rlm realm, poolPath string , tier uint64 , currentTime int64 ) ( uint64 , uint64 , int64 , map [ uint64 ] int64 ) {
205 s.emissionAccessor.MintAndDistributeGns( 0 , rlm)
206 poolTier := s.getPoolTier()
207 previousTier := poolTier.CurrentTier(poolPath)
208
209 tierRewards := poolTier.changeTier(currentTime, s.getPools(), poolPath, tier)
210
211 s.updatePoolTier( 0 , rlm, poolTier)
212
213 return previousTier, tier, poolTier.currentEmission, tierRewards
214 }
215
216 // removePoolTier internally removes the pool from tier system.
217 func (s *stakerV1) removePoolTier(_ int , rlm realm, poolPath string , currentTime int64 ) ( int64 , map [ uint64 ] int64 ) {
218 s.emissionAccessor.MintAndDistributeGns( 0 , rlm)
219
220 poolTier := s.getPoolTier()
221 tierRewards := poolTier.changeTier(currentTime, s.getPools(), poolPath, NOT_EMISSION_TARGET_TIER)
222 s.updatePoolTier( 0 , rlm, poolTier)
223
224 return poolTier.currentEmission, tierRewards
225 }
226
227 // setWarmUp internally sets the warm-up parameters.
228 func (s *stakerV1) setWarmUp(_ int , rlm realm, pct, timeDuration int64 ) {
229 s.emissionAccessor.MintAndDistributeGns( 0 , rlm)
230
231 warmupTemplate := s.store.GetWarmupTemplate()
232 warmupTemplate = modifyWarmup(warmupTemplate, pctToIndex(pct), timeDuration)
233
234 err := s.store.SetWarmupTemplate( 0 , rlm, warmupTemplate)
235 if err != nil {
236 panic(err)
237 }
238 }
239
240 // pctToIndex converts percentage to warmup index.
241 func pctToIndex(pct int64 ) int {
242 switch pct {
243 case 30 :
244 return 0
245 case 50 :
246 return 1
247 case 70 :
248 return 2
249 case 100 :
250 return 3
251 default :
252 panic( "staker.gno__pctToIndex() || pct is not valid" )
253 }
254 }
255
*gno.land/r/gnoswap/staker/v1.stakerV1