Kind Realm (renderable)
Name v1
Namespace gnoswap / gov / staker
Exported functions 12
Module gno.land/r/gnoswap/gov/staker/v1
gno 0.9 emission_reward_manager.gno gno
⧉
1 package staker 2 3 import ( 4 "errors" 5 "math" 6 7 gnsmath "gno.land/p/gnoswap/gnsmath/v1" 8 NewDelegation (id int64, delegateFrom string, delegateTo string, delegateAmount int64, createdHeight int64, createdAt int64) *gno.land/r/gnoswap/gov/staker.Delegation
NewDelegationManagerResolver (delegationManager *gno.land/r/gnoswap/gov/staker.DelegationManager) *gno.land/r/gnoswap/gov/staker/v1.DelegationManagerResolver
NewDelegationResolver (delegation *gno.land/r/gnoswap/gov/staker.Delegation) *gno.land/r/gnoswap/gov/staker/v1.DelegationResolver
NewDelegationWithdraw (delegationID int64, unDelegateAmount int64, createdHeight int64, createdAt int64, unDelegationLockupPeriod int64) struct{delegationID int64; unDelegateAmount int64; unDelegatedHeight int64; unDelegatedAt int64; collectedAmount int64; collectableTime int64; collectedAt int64; collected bool}
NewDelegationWithdrawResolver (withdraw *gno.land/r/gnoswap/gov/staker.DelegationWithdraw) *gno.land/r/gnoswap/gov/staker/v1.DelegationWithdrawResolver
NewDelegationWithdrawWithoutLockup (delegationID int64, unDelegateAmount int64, createdHeight int64, createdAt int64) struct{delegationID int64; unDelegateAmount int64; unDelegatedHeight int64; unDelegatedAt int64; collectedAmount int64; collectableTime int64; collectedAt int64; collected bool}
NewEmissionRewardManagerResolver (emissionRewardManager *gno.land/r/gnoswap/gov/staker.EmissionRewardManager) *gno.land/r/gnoswap/gov/staker/v1.EmissionRewardManagerResolver
NewEmissionRewardStateResolver (emissionRewardState *gno.land/r/gnoswap/gov/staker.EmissionRewardState) *gno.land/r/gnoswap/gov/staker/v1.EmissionRewardStateResolver
NewGovStakerV1 (store interface {GetAllDelegations func() *gno.land/p/nt/bptree/v0.BPTree; GetDelegation func(int64) (*gno.land/r/gnoswap/gov/staker.Delegation, bool); GetDelegationCounter func() *gno.land/r/gnoswap/gov/staker.Counter; GetDelegationManager func() *gno.land/r/gnoswap/gov/staker.DelegationManager; GetEmissionRewardManager func() *gno.land/r/gnoswap/gov/staker.EmissionRewardManager; GetLaunchpadProjectDeposits func() *gno.land/r/gnoswap/gov/staker.LaunchpadProjectDeposits; GetProtocolFeeRewardManager func() *gno.land/r/gnoswap/gov/staker.ProtocolFeeRewardManager; GetTotalDelegatedAmount func() int64; GetTotalDelegationHistory func() *gno.land/r/gnoswap/gov/staker.UintTree; GetTotalLockedAmount func() int64; GetUnDelegationLockupPeriod func() int64; GetUserDelegationHistory func() *gno.land/p/nt/bptree/v0.BPTree; HasDelegation func(int64) bool; HasDelegationCounterStoreKey func() bool; HasDelegationManagerStoreKey func() bool; HasDelegationsStoreKey func() bool; HasEmissionRewardManagerStoreKey func() bool; HasLaunchpadProjectDepositsStoreKey func() bool; HasProtocolFeeRewardManagerStoreKey func() bool; HasTotalDelegatedAmountStoreKey func() bool; HasTotalDelegationHistoryStoreKey func() bool; HasTotalLockedAmountStoreKey func() bool; HasUnDelegationLockupPeriodStoreKey func() bool; HasUserDelegationHistoryStoreKey func() bool; RemoveDelegation func(int, .uverse.realm, int64) .uverse.error; SetDelegation func(int, .uverse.realm, int64, *gno.land/r/gnoswap/gov/staker.Delegation) .uverse.error; SetDelegationCounter func(int, .uverse.realm, *gno.land/r/gnoswap/gov/staker.Counter) .uverse.error; SetDelegationManager func(int, .uverse.realm, *gno.land/r/gnoswap/gov/staker.DelegationManager) .uverse.error; SetDelegations func(int, .uverse.realm, *gno.land/p/nt/bptree/v0.BPTree) .uverse.error; SetEmissionRewardManager func(int, .uverse.realm, *gno.land/r/gnoswap/gov/staker.EmissionRewardManager) .uverse.error; SetLaunchpadProjectDeposits func(int, .uverse.realm, *gno.land/r/gnoswap/gov/staker.LaunchpadProjectDeposits) .uverse.error; SetProtocolFeeRewardManager func(int, .uverse.realm, *gno.land/r/gnoswap/gov/staker.ProtocolFeeRewardManager) .uverse.error; SetTotalDelegatedAmount func(int, .uverse.realm, int64) .uverse.error; SetTotalDelegationHistory func(int, .uverse.realm, *gno.land/r/gnoswap/gov/staker.UintTree) .uverse.error; SetTotalLockedAmount func(int, .uverse.realm, int64) .uverse.error; SetUnDelegationLockupPeriod func(int, .uverse.realm, int64) .uverse.error; SetUserDelegationHistory func(int, .uverse.realm, *gno.land/p/nt/bptree/v0.BPTree) .uverse.error}) interface {CleanStakerDelegationSnapshotByAdmin func(int, .uverse.realm, int64, .uverse.address); CollectEmissionReward func(int, .uverse.realm); CollectEmissionRewardFromLaunchPad func(int, .uverse.realm, .uverse.address); CollectProtocolFeeReward func(int, .uverse.realm, string); CollectProtocolFeeRewardFromLaunchPad func(int, .uverse.realm, .uverse.address, string); CollectReward func(int, .uverse.realm); CollectRewardFromLaunchPad func(int, .uverse.realm, .uverse.address); CollectUndelegatedGns func(int, .uverse.realm) int64; Delegate func(int, .uverse.realm, .uverse.address, int64, string) int64; ExistsDelegation func(int64) bool; GetClaimableRewardByAddress func(.uverse.address) (int64, map[string]int64, .uverse.error); GetClaimableRewardByLaunchpad func(.uverse.address) (int64, map[string]int64, .uverse.error); GetClaimableRewardByRewardID func(string) (int64, map[string]int64, .uverse.error); GetCollectableWithdrawAmount func(int64) int64; GetDelegationWithdrawCount func(int64) int; GetDelegationWithdraws func(int64, int, int) ([]gno.land/r/gnoswap/gov/staker.DelegationWithdraw, .uverse.error); GetDelegations func() *gno.land/p/nt/bptree/rotree/v0.ReadOnlyTree; GetDelegatorDelegations func(.uverse.address) *gno.land/p/nt/bptree/rotree/v0.ReadOnlyTree; GetEmissionAccumulatedTimestamp func() int64; GetEmissionAccumulatedX128PerStake func() *gno.land/p/gnoswap/uint256/v1.Uint; GetEmissionDistributedAmount func() int64; GetLaunchpadProjectDeposit func(string) (int64, bool); GetProtocolFeeAccumulatedTimestamp func() int64; GetProtocolFeeAccumulatedX128PerStake func(string) *gno.land/p/gnoswap/uint256/v1.Uint; GetProtocolFeeAmount func(string) int64; GetTotalDelegated func() int64; GetTotalDelegationAmountAtSnapshot func(int64) (int64, bool); GetTotalLockedAmount func() int64; GetTotalxGnsSupply func() int64; GetUnDelegationLockupPeriod func() int64; GetUserDelegationAmountAtSnapshot func(.uverse.address, int64) (int64, bool); GetUserDelegationIDs func(.uverse.address, .uverse.address) []int64; HasDelegationSnapshotsKey func() bool; Redelegate func(int, .uverse.realm, .uverse.address, .uverse.address, int64) int64; Render func(string) string; SetAmountByProjectWallet func(int, .uverse.realm, .uverse.address, int64, bool); SetUnDelegationLockupPeriodByAdmin func(int, .uverse.realm, int64); Undelegate func(int, .uverse.realm, .uverse.address, int64) int64}
NewLaunchpadProjectDepositsResolver (launchpadProjectDeposits *gno.land/r/gnoswap/gov/staker.LaunchpadProjectDeposits) *gno.land/r/gnoswap/gov/staker/v1.LaunchpadProjectDepositsResolver
NewProtocolFeeRewardManagerResolver (manager *gno.land/r/gnoswap/gov/staker.ProtocolFeeRewardManager) *gno.land/r/gnoswap/gov/staker/v1.ProtocolFeeRewardManagerResolver
NewProtocolFeeRewardStateResolver (protocolFeeRewardState *gno.land/r/gnoswap/gov/staker.ProtocolFeeRewardState) *gno.land/r/gnoswap/gov/staker/v1.ProtocolFeeRewardStateResolver
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.
u256 "gno.land/p/gnoswap/uint256/v1"
9 "gno.land/r/gnoswap/gov/staker"
10 )
11
12 type EmissionRewardManagerResolver struct {
13 *staker.EmissionRewardManager
14 }
15
16 // NewEmissionRewardManagerResolver wraps an emission reward manager with reward
17 // calculation and stake-accounting helpers.
18 //
19 // Parameters:
20 // - emissionRewardManager: manager state to resolve and mutate.
21 //
22 // Returns:
23 // - *EmissionRewardManagerResolver: resolver backed by emissionRewardManager.
24 func NewEmissionRewardManagerResolver(emissionRewardManager *staker.EmissionRewardManager) *EmissionRewardManagerResolver {
25 return &EmissionRewardManagerResolver{emissionRewardManager}
26 }
27
28 // GetClaimableRewardAmount calculates the claimable reward amount for a specific address.
29 //
30 // Parameters:
31 // - currentDistributedAmount: total emission amount distributed to the staker
32 // manager at the current observation point.
33 // - address: reward-state identifier whose claimable amount is requested.
34 // - currentTimestamp: Unix timestamp used to settle the address's reward state.
35 //
36 // Returns:
37 // - int64: emission reward currently claimable by address, or zero when no
38 // reward state exists.
39 // - error: nil on success; an error from accumulated-reward or reward-state
40 // resolution when calculation fails.
41 func (self *EmissionRewardManagerResolver) GetClaimableRewardAmount(
42 currentDistributedAmount int64 ,
43 address string ,
44 currentTimestamp int64 ,
45 ) ( int64 , error ) {
46 rewardState, ok, err := self.GetRewardState(address)
47 if !ok {
48 return 0 , nil
49 }
50
51 accumulatedRewardX128PerStake, err := self.calculateAccumulatedRewardX128PerStake(
52 currentDistributedAmount,
53 currentTimestamp,
54 )
55 if err != nil {
56 return 0 , err
57 }
58
59 resolvedState := NewEmissionRewardStateResolver(rewardState)
60 return resolvedState.GetClaimableRewardAmount(accumulatedRewardX128PerStake, currentTimestamp)
61 }
62
63 // calculateAccumulatedRewardX128PerStake calculates the updated accumulated reward per stake.
64 func (self *EmissionRewardManagerResolver) calculateAccumulatedRewardX128PerStake(
65 currentDistributedAmount int64 ,
66 currentTimestamp int64 ,
67 ) (*u256.Uint, error ) {
68 // If we're looking at a past timestamp, return current state
69 if currentTimestamp < self.GetAccumulatedTimestamp() {
70 return self.GetAccumulatedRewardX128PerStake(), nil
71 }
72
73 // With no stake there is nobody to credit, so the delta accrued over that window is
74 // dropped and the caller advances the cursor past it. The protocol fee accumulator
75 // applies the same policy, see ProtocolFeeRewardManagerResolver.
76 totalStakedAmount := self.GetTotalStakedAmount()
77 if totalStakedAmount == 0 {
78 return self.GetAccumulatedRewardX128PerStake(), nil
79 }
80
81 // Newly distributed rewards since last update
82 distributedAmountDelta := gnsmath.SafeSubInt64(currentDistributedAmount, self.GetDistributedAmount())
83 if distributedAmountDelta <= 0 {
84 // Non-positive delta. nothing to do more.
85 return self.GetAccumulatedRewardX128PerStake(), nil
86 }
87
88 // Reward per stake for the new distribution
89 distributedAmountDeltaX128PerStake := u256.Zero().Div(
90 u256.Zero().Lsh(u256.NewUintFromInt64(distributedAmountDelta), 128 ),
91 u256.NewUintFromInt64(totalStakedAmount),
92 )
93
94 // Add to accumulated reward per stake
95 accumulatedReward := u256.Zero().Add(self.GetAccumulatedRewardX128PerStake(), distributedAmountDeltaX128PerStake)
96 return accumulatedReward, nil
97 }
98
99 // updateAccumulatedRewardX128PerStake updates the internal accumulated reward state.
100 // This method should be called before any stake changes to ensure accurate reward calculations.
101 // Updates accumulated reward per stake with current distribution data.
102 func (self *EmissionRewardManagerResolver) updateAccumulatedRewardX128PerStake(
103 currentDistributedAmount int64 ,
104 currentTimestamp int64 ,
105 ) error {
106 // DO NOT apply out-of-order timestamps
107 if currentTimestamp < self.GetAccumulatedTimestamp() {
108 return nil
109 }
110
111 // Update accumulated reward state
112 accumulatedRewardX128PerStake, err := self.calculateAccumulatedRewardX128PerStake(
113 currentDistributedAmount,
114 currentTimestamp,
115 )
116 if err != nil {
117 return err
118 }
119
120 self.setAccumulatedRewardX128PerStake(accumulatedRewardX128PerStake.Clone())
121 self.setDistributedAmount(currentDistributedAmount)
122 self.setAccumulatedTimestamp(currentTimestamp)
123
124 return nil
125 }
126
127 // addStake adds a stake for an address and updates their reward state.
128 // This method ensures rewards are properly calculated before the stake change.
129 // Adds stake for specified address and updates reward calculations.
130 func (self *EmissionRewardManagerResolver) addStake(address string , amount int64 , currentTimestamp int64 ) error {
131 if amount < 0 {
132 return errors.New(errAmountMustBeNonNegative)
133 }
134
135 accumulatedReward := self.GetAccumulatedRewardX128PerStake()
136
137 rewardState, ok, err := self.GetRewardState(address)
138 if err != nil {
139 return err
140 }
141 if !ok {
142 rewardState = staker.NewEmissionRewardState(accumulatedReward)
143 }
144
145 resolvedState := NewEmissionRewardStateResolver(rewardState)
146 err = resolvedState.addStakeWithUpdateRewardDebtX128(amount, accumulatedReward, currentTimestamp)
147 if err != nil {
148 return err
149 }
150
151 self.setRewardStates(address, rewardState)
152
153 currentTotal := self.GetTotalStakedAmount()
154 if amount > 0 && currentTotal > math.MaxInt64-amount {
155 return errors.New(errTotalStakedAmountOverflow)
156 }
157 self.SetTotalStakedAmount(gnsmath.SafeAddInt64(currentTotal, amount))
158 return nil
159 }
160
161 // removeStake removes a stake for an address and updates their reward state.
162 // This method ensures rewards are properly calculated before the stake change.
163 // Removes stake for specified address and updates reward calculations.
164 func (self *EmissionRewardManagerResolver) removeStake(address string , amount int64 , currentTimestamp int64 ) error {
165 if amount < 0 {
166 return errors.New(errAmountMustBeNonNegative)
167 }
168
169 updatedTotalStakedAmount := gnsmath.SafeSubInt64(self.GetTotalStakedAmount(), amount)
170 if updatedTotalStakedAmount < 0 {
171 return errors.New(errRemoveAmountExceedsTotalStaked)
172 }
173
174 accumulatedReward := self.GetAccumulatedRewardX128PerStake()
175
176 rewardState, ok, err := self.GetRewardState(address)
177 if err != nil {
178 return err
179 }
180 if !ok {
181 rewardState = staker.NewEmissionRewardState(accumulatedReward)
182 }
183
184 resolvedState := NewEmissionRewardStateResolver(rewardState)
185
186 err = resolvedState.removeStakeWithUpdateRewardDebtX128(amount, accumulatedReward, currentTimestamp)
187 if err != nil {
188 return err
189 }
190
191 // persist updated state
192 self.setRewardStates(address, rewardState)
193
194 self.SetTotalStakedAmount(updatedTotalStakedAmount)
195
196 return nil
197 }
198
199 // claimRewards processes reward claiming for an address.
200 // This method calculates and returns the amount of rewards claimed.
201 // Claims available rewards for specified address.
202 func (self *EmissionRewardManagerResolver) claimRewards(address string , currentTimestamp int64 ) (claimedRewardAmount int64 , err error ) {
203 rewardState, ok, err := self.GetRewardState(address)
204 if err != nil || !ok {
205 return 0 , err
206 }
207
208 resolvedState := NewEmissionRewardStateResolver(rewardState)
209 claimedRewardAmount, cErr := resolvedState.claimRewardsWithUpdateRewardDebtX128(self.GetAccumulatedRewardX128PerStake(), currentTimestamp)
210 if cErr != nil {
211 return 0 , cErr
212 }
213
214 self.setRewardStates(address, rewardState)
215 return claimedRewardAmount, nil
216 }
217
218 func (self *EmissionRewardManagerResolver) setRewardStates(address string , rewardState *staker.EmissionRewardState) {
219 self.SetRewardState(address, rewardState)
220 }
221
222 func (self *EmissionRewardManagerResolver) setAccumulatedRewardX128PerStake(accumulatedRewardX128PerStake *u256.Uint) {
223 self.SetAccumulatedRewardX128PerStake(accumulatedRewardX128PerStake)
224 }
225
226 func (self *EmissionRewardManagerResolver) setDistributedAmount(distributedAmount int64 ) {
227 self.SetDistributedAmount(distributedAmount)
228 }
229
230 func (self *EmissionRewardManagerResolver) setAccumulatedTimestamp(accumulatedTimestamp int64 ) {
231 self.SetAccumulatedTimestamp(accumulatedTimestamp)
232 }
233