type.gno
7.27 Kb · 196 lines
1package staker
2
3import (
4 "gno.land/p/gnoswap/gnsmath/v1"
5 sr "gno.land/r/gnoswap/staker"
6)
7
8type ExternalIncentiveResolver struct {
9 *sr.ExternalIncentive
10}
11
12// isActive checks if the incentive is currently active at the given timestamp
13func (self *ExternalIncentiveResolver) isActive(currentTimestamp int64) bool {
14 return currentTimestamp >= self.StartTimestamp() && currentTimestamp <= self.EndTimestamp()
15}
16
17// IsEnded reports whether an external incentive's distribution window has ended.
18//
19// Parameters:
20// - currentTimestamp: Timestamp in Unix seconds to compare with the incentive end time.
21//
22// Returns:
23// - ended: True when currentTimestamp is after the inclusive end timestamp; false otherwise.
24func (self *ExternalIncentiveResolver) IsEnded(currentTimestamp int64) bool {
25 return currentTimestamp > self.EndTimestamp()
26}
27
28// IsStarted reports whether an external incentive's distribution window has opened.
29//
30// Parameters:
31// - currentTimestamp: Timestamp in Unix seconds to compare with the incentive start time.
32//
33// Returns:
34// - started: True when currentTimestamp is at or after the incentive start timestamp; false otherwise.
35func (self *ExternalIncentiveResolver) IsStarted(currentTimestamp int64) bool {
36 return currentTimestamp >= self.StartTimestamp()
37}
38
39// addDistributedRewardAmount adds the given amount to the distributed reward amount.
40// This function is used to add the distributed reward amount when the incentive is un-staked and refunded.
41func (self *ExternalIncentiveResolver) addDistributedRewardAmount(amount int64) {
42 distributedRewardAmount := gnsmath.SafeAddInt64(self.DistributedRewardAmount(), amount)
43 self.SetDistributedRewardAmount(distributedRewardAmount)
44}
45
46// addAccumulatedPenaltyAmount adds the given amount to the accumulated penalty amount.
47// Called during CollectReward to track warmup penalties for later collection.
48func (self *ExternalIncentiveResolver) addAccumulatedPenaltyAmount(amount int64) {
49 accumulatedPenaltyAmount := gnsmath.SafeAddInt64(self.AccumulatedPenaltyAmount(), amount)
50 self.SetAccumulatedPenaltyAmount(accumulatedPenaltyAmount)
51}
52
53// NewExternalIncentiveResolver wraps an external incentive with resolver operations.
54//
55// Parameters:
56// - externalIncentive: External incentive whose timestamps and accounting state the resolver exposes.
57//
58// Returns:
59// - resolver: Resolver backed by externalIncentive.
60func NewExternalIncentiveResolver(
61 externalIncentive *sr.ExternalIncentive,
62) *ExternalIncentiveResolver {
63 return &ExternalIncentiveResolver{
64 ExternalIncentive: externalIncentive,
65 }
66}
67
68type DepositResolver struct {
69 *sr.Deposit
70}
71
72// InternalRewardLastCollectTime returns the last collect time for the internal reward.
73// If the last collect time is 0, it returns the staked time.
74//
75// Returns:
76// - lastCollectTime: Last internal reward collection time in Unix seconds, falling back to StakeTime when the stored cursor is zero.
77func (self *DepositResolver) InternalRewardLastCollectTime() int64 {
78 if self.Deposit.InternalRewardLastCollectTime() == 0 {
79 return self.Deposit.StakeTime()
80 }
81
82 return self.Deposit.InternalRewardLastCollectTime()
83}
84
85// ExternalRewardLastCollectTime returns the last collect time for the external reward for the given incentive ID.
86// If the last collect time is 0, it returns the staked time.
87//
88// Parameters:
89// - incentiveID: External incentive ID whose collection cursor should be resolved.
90//
91// Returns:
92// - lastCollectTime: Last collection time in Unix seconds, falling back to StakeTime when no nonzero cursor is stored.
93func (self *DepositResolver) ExternalRewardLastCollectTime(incentiveID string) int64 {
94 lastCollectTime, exists := self.Deposit.GetExternalRewardLastCollectTime(incentiveID)
95 if !exists || lastCollectTime == 0 {
96 return self.Deposit.StakeTime()
97 }
98
99 return lastCollectTime
100}
101
102// CollectedExternalReward returns the amount already collected for one external incentive.
103//
104// Parameters:
105// - incentiveID: External incentive ID whose collected amount should be resolved.
106//
107// Returns:
108// - collectedReward: Cumulative amount collected for incentiveID, or 0 when no amount is stored.
109func (self *DepositResolver) CollectedExternalReward(incentiveID string) int64 {
110 collectedExternalReward, exists := self.Deposit.GetCollectedExternalReward(incentiveID)
111 if !exists {
112 return 0
113 }
114
115 return collectedExternalReward
116}
117
118func (self *DepositResolver) addCollectedInternalReward(reward int64) {
119 self.SetCollectedInternalReward(gnsmath.SafeAddInt64(self.CollectedInternalReward(), reward))
120}
121
122func (self *DepositResolver) addCollectedExternalReward(incentiveID string, reward int64) {
123 collectedExternalReward := gnsmath.SafeAddInt64(self.CollectedExternalReward(incentiveID), reward)
124 self.SetCollectedExternalReward(incentiveID, collectedExternalReward)
125}
126
127// updateInternalRewardLastCollectTime updates the last collect time for the internal reward.
128// It returns an error if the current time is less than the last collect time for the internal reward.
129func (self *DepositResolver) updateInternalRewardLastCollectTime(currentTime int64) error {
130 if self.InternalRewardLastCollectTime() > currentTime {
131 return makeErrorWithDetails(errNotAvailableUpdateCollectTime, "currentTime must be greater than internal reward last collect time")
132 }
133
134 self.SetInternalRewardLastCollectTime(currentTime)
135
136 return nil
137}
138
139// updateExternalRewardLastCollectTime lazily updates the last collect time for the external reward for the given incentive ID.
140// It returns an error if the current time is less than the last collect time for the external reward for the given incentive ID.
141func (self *DepositResolver) updateExternalRewardLastCollectTime(incentiveID string, currentTime int64) error {
142 if self.ExternalRewardLastCollectTimes() == nil {
143 self.SetExternalRewardLastCollectTimes(make(map[string]int64))
144 }
145
146 externalLastCollectTime, exists := self.Deposit.GetExternalRewardLastCollectTime(incentiveID)
147 if exists && externalLastCollectTime > currentTime {
148 return makeErrorWithDetails(errNotAvailableUpdateCollectTime, "currentTime must be greater than external reward last collect time")
149 }
150
151 self.Deposit.SetExternalRewardLastCollectTime(incentiveID, currentTime)
152
153 return nil
154}
155
156// FindWarmup returns the first warmup tier whose end time is after currentTime.
157//
158// Parameters:
159// - currentTime: Timestamp in Unix seconds used to select the active warmup tier.
160//
161// Returns:
162// - index: Index of the first tier with a later NextWarmupTime, or the final tier's index when all tiers have ended.
163func (self *DepositResolver) FindWarmup(currentTime int64) int {
164 for i, warmup := range self.Warmups() {
165 if currentTime < warmup.NextWarmupTime {
166 return i
167 }
168 }
169 return len(self.Warmups()) - 1
170}
171
172// GetWarmup returns the warmup tier at index.
173//
174// Parameters:
175// - index: Zero-based warmup-tier index; an out-of-range index panics through slice indexing.
176//
177// Returns:
178// - warmup: Warmup tier stored at index.
179func (self *DepositResolver) GetWarmup(index int) sr.Warmup {
180 return self.Warmups()[index]
181}
182
183// NewDepositResolver wraps a deposit with reward-cursor and warmup resolution helpers.
184//
185// Parameters:
186// - deposit: Deposit whose persisted reward state should be resolved.
187//
188// Returns:
189// - resolver: Resolver backed by deposit.
190func NewDepositResolver(
191 deposit *sr.Deposit,
192) *DepositResolver {
193 return &DepositResolver{
194 Deposit: deposit,
195 }
196}