Skip to content Search Apps Documentation Source Content File Folder Download Copy Actions State String Boolean Number Struct Map Slice Pointer Function Closure Reference Nil Package Type Interface Unknown

getter.gno

13.60 Kb · 406 lines
  1package staker
  2
  3import (
  4	"time"
  5
  6	gnsmath "gno.land/p/gnoswap/gnsmath/v1"
  7	"gno.land/p/gnoswap/uint256/v1"
  8	rotree "gno.land/p/nt/bptree/rotree/v0"
  9	ufmt "gno.land/p/nt/ufmt/v0"
 10
 11	"gno.land/r/gnoswap/emission"
 12	"gno.land/r/gnoswap/gov/staker"
 13	"gno.land/r/gnoswap/gov/xgns"
 14)
 15
 16// GetTotalxGnsSupply returns the total amount of xGNS supply, including
 17// xGNS held by the launchpad.
 18//
 19// Returns:
 20//   - int64: total xGNS supply, including the launchpad balance.
 21func (gs *govStakerV1) GetTotalxGnsSupply() int64 {
 22	return xgns.TotalSupply()
 23}
 24
 25// GetTotalDelegated returns the total amount of xGNS delegated.
 26//
 27// Returns:
 28//   - int64: total xGNS amount currently delegated.
 29func (gs *govStakerV1) GetTotalDelegated() int64 {
 30	return gs.store.GetTotalDelegatedAmount()
 31}
 32
 33// GetTotalLockedAmount returns the total amount of locked GNS.
 34//
 35// Returns:
 36//   - int64: total GNS amount currently locked.
 37func (gs *govStakerV1) GetTotalLockedAmount() int64 {
 38	return gs.store.GetTotalLockedAmount()
 39}
 40
 41// GetUnDelegationLockupPeriod returns the undelegation lockup period in seconds.
 42//
 43// Returns:
 44//   - int64: number of seconds an undelegation remains locked.
 45func (gs *govStakerV1) GetUnDelegationLockupPeriod() int64 {
 46	return gs.store.GetUnDelegationLockupPeriod()
 47}
 48
 49// GetDelegations returns a read-only view of every delegation, keyed by the
 50// decimal string form of the delegation ID.
 51//
 52// Returns:
 53//   - *rotree.ReadOnlyTree: read-only delegation tree keyed by decimal ID.
 54func (gs *govStakerV1) GetDelegations() *rotree.ReadOnlyTree {
 55	return rotree.Wrap(gs.store.GetAllDelegations(), cloneDelegationEntry)
 56}
 57
 58// ExistsDelegation checks if a delegation exists.
 59//
 60// Parameters:
 61//   - delegationID: delegation identifier to look up.
 62//
 63// Returns:
 64//   - bool: true when delegationID is stored, otherwise false.
 65func (gs *govStakerV1) ExistsDelegation(delegationID int64) bool {
 66	return gs.store.HasDelegation(delegationID)
 67}
 68
 69// GetDelegatorDelegations returns a read-only view of a delegator's delegations,
 70// keyed by delegatee address with that pair's delegation IDs as the value.
 71// nil is returned when the delegator has no delegations.
 72//
 73// Parameters:
 74//   - delegator: address whose outgoing delegations are requested.
 75//
 76// Returns:
 77//   - *rotree.ReadOnlyTree: read-only tree keyed by delegatee address, or nil
 78//     when delegator has no delegation entries.
 79func (gs *govStakerV1) GetDelegatorDelegations(delegator address) *rotree.ReadOnlyTree {
 80	delegationManager := gs.store.GetDelegationManager()
 81	delegatorTree, exists := delegationManager.GetDelegatorDelegations(delegator.String())
 82	if !exists {
 83		return nil
 84	}
 85	return rotree.Wrap(delegatorTree, cloneDelegationIDsEntry)
 86}
 87
 88// GetUserDelegationIDs returns the delegation IDs for a specific delegator and
 89// delegatee.
 90//
 91// Parameters:
 92//   - delegator: address that created the delegations.
 93//   - delegatee: address receiving the delegations.
 94//
 95// Returns:
 96//   - []int64: delegation IDs for the delegator/delegatee pair, or an empty
 97//     slice when no pair is stored.
 98func (gs *govStakerV1) GetUserDelegationIDs(delegator address, delegatee address) []int64 {
 99	delegationManager := gs.store.GetDelegationManager()
100
101	delegationIDs, exists := delegationManager.GetDelegationIDs(delegator.String(), delegatee.String())
102	if !exists {
103		return []int64{}
104	}
105
106	return delegationIDs
107}
108
109// HasDelegationSnapshotsKey reports whether delegation history has been stored.
110//
111// Returns:
112//   - bool: true when the total delegation history storage key exists.
113func (gs *govStakerV1) HasDelegationSnapshotsKey() bool {
114	return gs.store.HasTotalDelegationHistoryStoreKey()
115}
116
117// GetTotalDelegationAmountAtSnapshot returns the total delegation amount at a
118// Unix timestamp. It uses ReverseIterate to find the most recent history entry
119// at or before that timestamp; this is a timestamp lookup, not a block snapshot.
120//
121// Parameters:
122//   - snapshotTime: Unix timestamp to retrieve the history value for
123//
124// Returns:
125//   - int64: total delegation amount at the specified time
126//   - bool: true when a history entry exists at or before the timestamp
127func (gs *govStakerV1) GetTotalDelegationAmountAtSnapshot(snapshotTime int64) (int64, bool) {
128	history := gs.store.GetTotalDelegationHistory()
129	if history.Size() == 0 {
130		return 0, false
131	}
132
133	var (
134		totalAmount int64
135		exists      bool
136	)
137
138	// ReverseIterate from 0 to snapshotTime to find the most recent entry at or before snapshotTime
139	history.ReverseIterate(0, snapshotTime, func(key int64, value any) bool {
140		amountInt, ok := value.(int64)
141		if !ok {
142			panic(ufmt.Sprintf("invalid amount type: %T", value))
143		}
144
145		totalAmount = amountInt
146		exists = true
147
148		return true // stop after first (most recent) entry
149	})
150
151	return totalAmount, exists
152}
153
154// GetUserDelegationAmountAtSnapshot returns one user's delegation amount at a
155// Unix timestamp. The history is keyed by address and timestamp, and the
156// lookup returns the most recent entry at or before the requested time.
157//
158// Parameters:
159//   - userAddr: address of the user
160//   - snapshotTime: Unix timestamp to retrieve
161//
162// Returns:
163//   - int64: user delegation amount at the specified time
164//   - bool: true when a history entry exists at or before the timestamp
165func (gs *govStakerV1) GetUserDelegationAmountAtSnapshot(userAddr address, snapshotTime int64) (int64, bool) {
166	history := gs.store.GetUserDelegationHistory()
167
168	addrStr := userAddr.String()
169	lo, _ := userHistoryKeyRange(addrStr)
170	// Inclusive upper bound: largest key for this address at or before snapshotTime.
171	hi := makeUserHistoryKey(addrStr, snapshotTime)
172
173	var (
174		userAmount int64
175		exists     bool
176	)
177
178	// ReverseIterate from hi down to lo to find the most recent entry at or before snapshotTime
179	history.ReverseIterate(lo, hi, func(_ string, value any) bool {
180		amountInt, ok := value.(int64)
181		if !ok {
182			panic(ufmt.Sprintf("invalid amount type: %T", value))
183		}
184
185		userAmount = amountInt
186		exists = true
187
188		return true // stop after first (most recent) entry
189	})
190
191	return userAmount, exists
192}
193
194// GetClaimableRewardByAddress returns the claimable rewards for an address.
195//
196// Parameters:
197//   - addr: staker address whose emission and protocol fee rewards are requested.
198//
199// Returns:
200//   - int64: claimable emission reward amount.
201//   - map[string]int64: claimable protocol fee amounts keyed by token path.
202//   - error: nil on success; an error when emission or protocol fee reward
203//     resolution fails.
204func (gs *govStakerV1) GetClaimableRewardByAddress(addr address) (int64, map[string]int64, error) {
205	return gs.GetClaimableRewardByRewardID(addr.String())
206}
207
208// GetClaimableRewardByLaunchpad returns the claimable rewards for a launchpad
209// project address.
210//
211// Parameters:
212//   - addr: launchpad project address used to derive its reward ID.
213//
214// Returns:
215//   - int64: claimable emission reward amount for the launchpad project.
216//   - map[string]int64: claimable protocol fee amounts keyed by token path.
217//   - error: nil on success; an error when emission or protocol fee reward
218//     resolution fails.
219func (gs *govStakerV1) GetClaimableRewardByLaunchpad(addr address) (int64, map[string]int64, error) {
220	return gs.GetClaimableRewardByRewardID(gs.makeLaunchpadRewardID(addr.String()))
221}
222
223// GetClaimableRewardByRewardID returns the claimable rewards for a reward ID.
224//
225// Parameters:
226//   - rewardID: emission/protocol-fee reward state identifier to inspect.
227//
228// Returns:
229//   - int64: claimable emission reward amount.
230//   - map[string]int64: claimable protocol fee amounts keyed by token path.
231//   - error: nil on success; an error when emission or protocol fee reward
232//     resolution fails.
233func (gs *govStakerV1) GetClaimableRewardByRewardID(rewardID string) (int64, map[string]int64, error) {
234	emissionDistributedAmount := emission.GetAccuDistributedToGovStaker()
235	emissionRewardManager := gs.store.GetEmissionRewardManager()
236	emissionResolver := NewEmissionRewardManagerResolver(emissionRewardManager)
237	emissionReward, err := emissionResolver.GetClaimableRewardAmount(emissionDistributedAmount, rewardID, time.Now().Unix())
238	if err != nil {
239		return 0, make(map[string]int64), err
240	}
241
242	protocolFeeRewards, err := gs.getClaimableProtocolFeeRewards(rewardID)
243	if err != nil {
244		return 0, make(map[string]int64), err
245	}
246
247	return emissionReward, protocolFeeRewards, nil
248}
249
250// GetLaunchpadProjectDeposit returns the deposit amount for a launchpad project.
251//
252// Parameters:
253//   - projectAddr: launchpad project address used to derive its reward ID.
254//
255// Returns:
256//   - int64: stored launchpad project deposit amount.
257//   - bool: true when a deposit exists for projectAddr, otherwise false.
258func (gs *govStakerV1) GetLaunchpadProjectDeposit(projectAddr string) (int64, bool) {
259	launchpadDeposits := gs.store.GetLaunchpadProjectDeposits()
260	return launchpadDeposits.GetDeposit(gs.makeLaunchpadRewardID(projectAddr))
261}
262
263// GetDelegationWithdrawCount returns the total number of delegation withdraws
264// for a specific delegation.
265//
266// Parameters:
267//   - delegationID: delegation identifier whose withdrawals are counted.
268//
269// Returns:
270//   - int: number of withdrawals recorded for delegationID, or zero when the
271//     delegation does not exist.
272func (gs *govStakerV1) GetDelegationWithdrawCount(delegationID int64) int {
273	delegation, exists := gs.store.GetDelegation(delegationID)
274	if !exists {
275		return 0
276	}
277	return len(delegation.Withdraws())
278}
279
280// GetDelegationWithdraws returns a paginated list of delegation withdraws for a
281// specific delegation.
282//
283// Parameters:
284//   - delegationID: delegation identifier whose withdrawals are requested.
285//   - offset: zero-based index of the first withdrawal to return.
286//   - count: maximum number of withdrawals to return.
287//
288// Returns:
289//   - []staker.DelegationWithdraw: withdrawals in the requested range, or an
290//     empty slice when the delegation or page is absent.
291//   - error: nil; this accessor currently has no error path.
292func (gs *govStakerV1) GetDelegationWithdraws(delegationID int64, offset, count int) ([]staker.DelegationWithdraw, error) {
293	delegation, exists := gs.store.GetDelegation(delegationID)
294	if !exists {
295		return []staker.DelegationWithdraw{}, nil
296	}
297
298	withdraws := delegation.Withdraws()
299	size := len(withdraws)
300	if offset >= size {
301		return []staker.DelegationWithdraw{}, nil
302	}
303
304	end := offset + count
305	if end > size {
306		end = size
307	}
308
309	return withdraws[offset:end], nil
310}
311
312// GetCollectableWithdrawAmount returns the collectable withdraw amount for a
313// specific delegation as of the current Unix time.
314//
315// Parameters:
316//   - delegationID: delegation identifier whose matured withdrawals are summed.
317//
318// Returns:
319//   - int64: total amount currently collectable, or zero when the delegation
320//     does not exist.
321func (gs *govStakerV1) GetCollectableWithdrawAmount(delegationID int64) int64 {
322	delegation, exists := gs.store.GetDelegation(delegationID)
323	if !exists {
324		return 0
325	}
326
327	totalAmount := int64(0)
328	currentTime := time.Now().Unix()
329	for _, withdraw := range delegation.Withdraws() {
330		resolver := NewDelegationWithdrawResolver(&withdraw)
331		totalAmount = gnsmath.SafeAddInt64(totalAmount, resolver.CollectableAmount(currentTime))
332	}
333
334	return totalAmount
335}
336
337// GetProtocolFeeAccumulatedX128PerStake returns the accumulated protocol fee per
338// stake (Q128) for a token path.
339//
340// Parameters:
341//   - tokenPath: token identifier/path whose accumulator is requested.
342//
343// Returns:
344//   - *uint256.Uint: accumulated protocol fee per stake scaled by 2^128, or a
345//     zero value when no accumulator exists for tokenPath.
346func (gs *govStakerV1) GetProtocolFeeAccumulatedX128PerStake(tokenPath string) *uint256.Uint {
347	protocolFeeRewardManager := gs.store.GetProtocolFeeRewardManager()
348	accumulatedFee := protocolFeeRewardManager.GetAccumulatedProtocolFeeX128PerStake(tokenPath)
349	if accumulatedFee == nil {
350		return uint256.NewUint(0)
351	}
352
353	return accumulatedFee
354}
355
356// GetProtocolFeeAmount returns the protocol fee amount accumulated for a token
357// path.
358//
359// Parameters:
360//   - tokenPath: token identifier/path whose folded fee amount is requested.
361//
362// Returns:
363//   - int64: accumulated protocol fee amount for tokenPath.
364func (gs *govStakerV1) GetProtocolFeeAmount(tokenPath string) int64 {
365	protocolFeeRewardManager := gs.store.GetProtocolFeeRewardManager()
366	return protocolFeeRewardManager.GetProtocolFeeAmount(tokenPath)
367}
368
369// GetProtocolFeeAccumulatedTimestamp returns the accumulated timestamp for
370// protocol fee rewards.
371//
372// Returns:
373//   - int64: Unix timestamp represented by protocol fee accumulation state.
374func (gs *govStakerV1) GetProtocolFeeAccumulatedTimestamp() int64 {
375	protocolFeeRewardManager := gs.store.GetProtocolFeeRewardManager()
376	return protocolFeeRewardManager.GetAccumulatedTimestamp()
377}
378
379// GetEmissionAccumulatedX128PerStake returns the accumulated emission per stake
380// (Q128).
381//
382// Returns:
383//   - *uint256.Uint: accumulated emission reward per stake scaled by 2^128.
384func (gs *govStakerV1) GetEmissionAccumulatedX128PerStake() *uint256.Uint {
385	emissionRewardManager := gs.store.GetEmissionRewardManager()
386	return emissionRewardManager.GetAccumulatedRewardX128PerStake()
387}
388
389// GetEmissionDistributedAmount returns the total distributed emission amount.
390//
391// Returns:
392//   - int64: total emission amount recorded as distributed to governance stakers.
393func (gs *govStakerV1) GetEmissionDistributedAmount() int64 {
394	emissionRewardManager := gs.store.GetEmissionRewardManager()
395	return emissionRewardManager.GetDistributedAmount()
396}
397
398// GetEmissionAccumulatedTimestamp returns the accumulated timestamp for emission
399// rewards.
400//
401// Returns:
402//   - int64: Unix timestamp represented by emission accumulation state.
403func (gs *govStakerV1) GetEmissionAccumulatedTimestamp() int64 {
404	emissionRewardManager := gs.store.GetEmissionRewardManager()
405	return emissionRewardManager.GetAccumulatedTimestamp()
406}