getter.gno
11.64 Kb · 341 lines
1package v1
2
3import (
4 "strconv"
5 "time"
6
7 "gno.land/p/gnoswap/uint256"
8 ufmt "gno.land/p/nt/ufmt/v0"
9
10 "gno.land/r/gnoswap/emission"
11 "gno.land/r/gnoswap/gov/staker"
12 "gno.land/r/gnoswap/gov/xgns"
13)
14
15// GetTotalxGnsSupply returns the total amount of xGNS supply.
16func (gs *govStakerV1) GetTotalxGnsSupply() int64 {
17 return xgns.TotalSupply()
18}
19
20// GetTotalDelegated returns the total amount of xGNS delegated.
21func (gs *govStakerV1) GetTotalDelegated() int64 {
22 return gs.store.GetTotalDelegatedAmount()
23}
24
25// GetTotalLockedAmount returns the total amount of locked GNS.
26func (gs *govStakerV1) GetTotalLockedAmount() int64 {
27 return gs.store.GetTotalLockedAmount()
28}
29
30// GetUnDelegationLockupPeriod returns the undelegation lockup period in seconds.
31func (gs *govStakerV1) GetUnDelegationLockupPeriod() int64 {
32 return gs.store.GetUnDelegationLockupPeriod()
33}
34
35// GetDelegationCount returns the total number of delegations.
36func (gs *govStakerV1) GetDelegationCount() int {
37 delegations := gs.store.GetAllDelegations()
38 return delegations.Size()
39}
40
41// GetDelegationIDs returns a paginated list of delegation IDs.
42func (gs *govStakerV1) GetDelegationIDs(offset, count int) []int64 {
43 delegations := gs.store.GetAllDelegations()
44
45 ids := make([]int64, 0)
46
47 delegations.IterateByOffset(offset, count, func(key string, _ any) bool {
48 delegationID, err := strconv.ParseInt(key, 10, 64)
49 if err != nil {
50 return false
51 }
52
53 ids = append(ids, delegationID)
54 return false
55 })
56
57 return ids
58}
59
60// ExistsDelegation checks if a delegation exists.
61func (gs *govStakerV1) ExistsDelegation(delegationID int64) bool {
62 return gs.store.HasDelegation(delegationID)
63}
64
65// GetDelegation returns the delegation for the given ID.
66func (gs *govStakerV1) GetDelegation(delegationID int64) (*staker.Delegation, error) {
67 delegation, exists := gs.store.GetDelegation(delegationID)
68 if !exists {
69 return nil, makeErrorWithDetails(errDataNotFound, ufmt.Sprintf("delegation not found: %d", delegationID))
70 }
71 return delegation, nil
72}
73
74// GetDelegatorDelegateeCount returns the number of delegatees for a specific delegator.
75func (gs *govStakerV1) GetDelegatorDelegateeCount(delegator address) int {
76 delegationManager := gs.store.GetDelegationManager()
77 delegatorTree, exists := delegationManager.GetDelegatorDelegations(delegator.String())
78 if !exists {
79 return 0
80 }
81
82 return delegatorTree.Size()
83}
84
85// GetDelegatorDelegateeAddresses returns a paginated list of delegatee addresses for a specific delegator.
86func (gs *govStakerV1) GetDelegatorDelegateeAddresses(delegator address, offset, count int) []address {
87 delegationManager := gs.store.GetDelegationManager()
88 delegatorTree, exists := delegationManager.GetDelegatorDelegations(delegator.String())
89 if !exists {
90 return []address{}
91 }
92
93 delegateeAddresses := make([]address, 0)
94
95 delegatorTree.IterateByOffset(offset, count, func(delegatee string, _ any) bool {
96 delegateeAddresses = append(delegateeAddresses, address(delegatee))
97 return false
98 })
99
100 return delegateeAddresses
101}
102
103// GetUserDelegationCount returns the number of delegations for a specific delegator-delegatee pair.
104func (gs *govStakerV1) GetUserDelegationCount(delegator address, delegatee address) int {
105 delegationManager := gs.store.GetDelegationManager()
106 delegationIDs, exists := delegationManager.GetDelegationIDs(delegator.String(), delegatee.String())
107 if !exists {
108 return 0
109 }
110 return len(delegationIDs)
111}
112
113// GetUserDelegationIDs returns a paginated list of delegation IDs for a specific delegator and delegatee.
114func (gs *govStakerV1) GetUserDelegationIDs(delegator address, delegatee address) []int64 {
115 delegationManager := gs.store.GetDelegationManager()
116
117 delegationIDs, exists := delegationManager.GetDelegationIDs(delegator.String(), delegatee.String())
118 if !exists {
119 return []int64{}
120 }
121
122 return delegationIDs
123}
124
125// HasDelegationSnapshotsKey returns true if delegation history exists.
126func (gs *govStakerV1) HasDelegationSnapshotsKey() bool {
127 return gs.store.HasTotalDelegationHistoryStoreKey()
128}
129
130// GetTotalDelegationAmountAtSnapshot returns the total delegation amount at a specific snapshot time.
131// Uses ReverseIterate to find the most recent entry at or before the snapshot time.
132//
133// Parameters:
134// - snapshotTime: timestamp to retrieve the snapshot for
135//
136// Returns:
137// - int64: total delegation amount at the specified time
138// - bool: true if snapshot was exists, false otherwise
139func (gs *govStakerV1) GetTotalDelegationAmountAtSnapshot(snapshotTime int64) (int64, bool) {
140 history := gs.store.GetTotalDelegationHistory()
141 if history.Size() == 0 {
142 return 0, false
143 }
144
145 var (
146 totalAmount int64
147 exists bool
148 )
149
150 // ReverseIterate from 0 to snapshotTime to find the most recent entry at or before snapshotTime
151 history.ReverseIterate(0, snapshotTime, func(key int64, value any) bool {
152 amountInt, ok := value.(int64)
153 if !ok {
154 panic(ufmt.Sprintf("invalid amount type: %T", value))
155 }
156
157 totalAmount = amountInt
158 exists = true
159
160 return true // stop after first (most recent) entry
161 })
162
163 return totalAmount, exists
164}
165
166// GetUserDelegationAmountAtSnapshot returns the delegation amount for a specific user at a specific snapshot time.
167// Structure: single BPTree keyed by composite key "addrStr|paddedTimestamp" -> int64
168// Uses ReverseIterate over the user's prefix range to find the most recent entry at or before the snapshot time.
169//
170// Parameters:
171// - userAddr: address of the user to get delegation amount for
172// - snapshotTime: timestamp to retrieve the snapshot for
173//
174// Returns:
175// - int64: user delegation amount at the specified time
176// - bool: true if snapshot was exists, false otherwise
177func (gs *govStakerV1) GetUserDelegationAmountAtSnapshot(userAddr address, snapshotTime int64) (int64, bool) {
178 history := gs.store.GetUserDelegationHistory()
179
180 addrStr := userAddr.String()
181 lo, _ := userHistoryKeyRange(addrStr)
182 // Inclusive upper bound: largest key for this address at or before snapshotTime.
183 hi := makeUserHistoryKey(addrStr, snapshotTime)
184
185 var (
186 userAmount int64
187 exists bool
188 )
189
190 // ReverseIterate from hi down to lo to find the most recent entry at or before snapshotTime
191 history.ReverseIterate(lo, hi, func(_ string, value any) bool {
192 amountInt, ok := value.(int64)
193 if !ok {
194 panic(ufmt.Sprintf("invalid amount type: %T", value))
195 }
196
197 userAmount = amountInt
198 exists = true
199
200 return true // stop after first (most recent) entry
201 })
202
203 return userAmount, exists
204}
205
206// GetClaimableRewardByAddress returns claimable reward for address.
207//
208// Returns:
209// - int64: emission reward amount
210// - map[string]int64: protocol fee rewards by token path
211func (gs *govStakerV1) GetClaimableRewardByAddress(addr address) (int64, map[string]int64, error) {
212 return gs.GetClaimableRewardByRewardID(addr.String())
213}
214
215// GetClaimableRewardByLaunchpad returns claimable reward for launchpad.
216//
217// Returns:
218// - int64: emission reward amount
219// - map[string]int64: protocol fee rewards by token path
220func (gs *govStakerV1) GetClaimableRewardByLaunchpad(addr address) (int64, map[string]int64, error) {
221 return gs.GetClaimableRewardByRewardID(gs.makeLaunchpadRewardID(addr.String()))
222}
223
224// GetClaimableRewardByRewardID returns claimable reward by ID.
225//
226// Returns:
227// - int64: emission reward amount
228// - map[string]int64: protocol fee rewards by token path
229func (gs *govStakerV1) GetClaimableRewardByRewardID(rewardID string) (int64, map[string]int64, error) {
230 emissionDistributedAmount := emission.GetAccuDistributedToGovStaker()
231 emissionRewardManager := gs.store.GetEmissionRewardManager()
232 emissionResolver := NewEmissionRewardManagerResolver(emissionRewardManager)
233 emissionReward, err := emissionResolver.GetClaimableRewardAmount(emissionDistributedAmount, rewardID, time.Now().Unix())
234 if err != nil {
235 return 0, make(map[string]int64), err
236 }
237
238 protocolFeeDistributedAmounts := gs.getDistributedProtocolFees()
239 protocolFeeRewardManager := gs.store.GetProtocolFeeRewardManager()
240 protocolFeeResolver := NewProtocolFeeRewardManagerResolver(protocolFeeRewardManager)
241 protocolFeeRewards, err := protocolFeeResolver.GetClaimableRewardAmounts(protocolFeeDistributedAmounts, rewardID, time.Now().Unix())
242 if err != nil {
243 return 0, make(map[string]int64), err
244 }
245
246 return emissionReward, protocolFeeRewards, nil
247}
248
249// GetLaunchpadProjectDeposit returns the deposit amount for a launchpad project.
250func (gs *govStakerV1) GetLaunchpadProjectDeposit(projectAddr string) (int64, bool) {
251 launchpadDeposits := gs.store.GetLaunchpadProjectDeposits()
252 return launchpadDeposits.GetDeposit(gs.makeLaunchpadRewardID(projectAddr))
253}
254
255// GetDelegationWithdrawCount returns the total number of delegation withdraws for a specific delegation.
256func (gs *govStakerV1) GetDelegationWithdrawCount(delegationID int64) int {
257 delegation, exists := gs.store.GetDelegation(delegationID)
258 if !exists {
259 return 0
260 }
261 return len(delegation.Withdraws())
262}
263
264// GetDelegationWithdraws returns a paginated list of delegation withdraws for a specific delegation.
265func (gs *govStakerV1) GetDelegationWithdraws(delegationID int64, offset, count int) ([]staker.DelegationWithdraw, error) {
266 delegation, exists := gs.store.GetDelegation(delegationID)
267 if !exists {
268 return []staker.DelegationWithdraw{}, nil
269 }
270
271 withdraws := delegation.Withdraws()
272 size := len(withdraws)
273 if offset >= size {
274 return []staker.DelegationWithdraw{}, nil
275 }
276
277 end := offset + count
278 if end > size {
279 end = size
280 }
281
282 return withdraws[offset:end], nil
283}
284
285// GetCollectableWithdrawAmount returns the collectable withdraw amount for a specific delegation.
286func (gs *govStakerV1) GetCollectableWithdrawAmount(delegationID int64) int64 {
287 delegation, exists := gs.store.GetDelegation(delegationID)
288 if !exists {
289 return 0
290 }
291
292 totalAmount := int64(0)
293 currentTime := time.Now().Unix()
294 for _, withdraw := range delegation.Withdraws() {
295 resolver := NewDelegationWithdrawResolver(&withdraw)
296 totalAmount = safeAddInt64(totalAmount, resolver.CollectableAmount(currentTime))
297 }
298
299 return totalAmount
300}
301
302// GetProtocolFeeAccumulatedX128PerStake returns the accumulated protocol fee per stake (Q128) for a token path.
303func (gs *govStakerV1) GetProtocolFeeAccumulatedX128PerStake(tokenPath string) *uint256.Uint {
304 protocolFeeRewardManager := gs.store.GetProtocolFeeRewardManager()
305 accumulatedFee := protocolFeeRewardManager.GetAccumulatedProtocolFeeX128PerStake(tokenPath)
306 if accumulatedFee == nil {
307 return uint256.NewUint(0)
308 }
309
310 return accumulatedFee
311}
312
313// GetProtocolFeeAmount returns the protocol fee amounts for a token path.
314func (gs *govStakerV1) GetProtocolFeeAmount(tokenPath string) int64 {
315 protocolFeeRewardManager := gs.store.GetProtocolFeeRewardManager()
316 return protocolFeeRewardManager.GetProtocolFeeAmount(tokenPath)
317}
318
319// GetProtocolFeeAccumulatedTimestamp returns the accumulated timestamp for protocol fee rewards.
320func (gs *govStakerV1) GetProtocolFeeAccumulatedTimestamp() int64 {
321 protocolFeeRewardManager := gs.store.GetProtocolFeeRewardManager()
322 return protocolFeeRewardManager.GetAccumulatedTimestamp()
323}
324
325// GetEmissionAccumulatedX128PerStake returns the accumulated emission per stake (Q128).
326func (gs *govStakerV1) GetEmissionAccumulatedX128PerStake() *uint256.Uint {
327 emissionRewardManager := gs.store.GetEmissionRewardManager()
328 return emissionRewardManager.GetAccumulatedRewardX128PerStake()
329}
330
331// GetEmissionDistributedAmount returns the total distributed emission amount.
332func (gs *govStakerV1) GetEmissionDistributedAmount() int64 {
333 emissionRewardManager := gs.store.GetEmissionRewardManager()
334 return emissionRewardManager.GetDistributedAmount()
335}
336
337// GetEmissionAccumulatedTimestamp returns the accumulated timestamp for emission rewards.
338func (gs *govStakerV1) GetEmissionAccumulatedTimestamp() int64 {
339 emissionRewardManager := gs.store.GetEmissionRewardManager()
340 return emissionRewardManager.GetAccumulatedTimestamp()
341}