Search Apps Documentation Source Content File Folder Download Copy Actions Download 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}