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

delegation_withdraw.gno

4.92 Kb · 162 lines
  1package staker
  2
  3import (
  4	"errors"
  5
  6	gnsmath "gno.land/p/gnoswap/gnsmath/v1"
  7
  8	"gno.land/r/gnoswap/gov/staker"
  9)
 10
 11type DelegationWithdrawResolver struct {
 12	withdraw *staker.DelegationWithdraw
 13}
 14
 15// NewDelegationWithdrawResolver wraps a delegation withdrawal for collection
 16// state and lockup calculations.
 17//
 18// Parameters:
 19//   - withdraw: delegation withdrawal state to resolve
 20//
 21// Returns:
 22//   - *DelegationWithdrawResolver: resolver retaining the supplied withdrawal pointer
 23func NewDelegationWithdrawResolver(withdraw *staker.DelegationWithdraw) *DelegationWithdrawResolver {
 24	return &DelegationWithdrawResolver{withdraw}
 25}
 26
 27// Get returns the wrapped delegation withdrawal value.
 28//
 29// Returns:
 30//   - *staker.DelegationWithdraw: wrapped withdrawal pointer, or nil when the resolver was constructed with nil
 31func (r *DelegationWithdrawResolver) Get() *staker.DelegationWithdraw {
 32	return r.withdraw
 33}
 34
 35// CollectableAmount calculates the amount available for collection at the given time.
 36// Returns zero if the withdrawal is not yet collectable or has been fully collected.
 37//
 38// Parameters:
 39//   - currentTime: current timestamp to check collectability against
 40//
 41// Returns:
 42//   - int64: amount available for collection
 43func (r *DelegationWithdrawResolver) CollectableAmount(currentTime int64) int64 {
 44	if r.IsCollectable(currentTime) {
 45		return gnsmath.SafeSubInt64(r.withdraw.UnDelegateAmount(), r.withdraw.CollectedAmount())
 46	}
 47
 48	return 0
 49}
 50
 51// IsCollectable determines whether the withdrawal can be collected at the given time.
 52// A withdrawal is collectable if:
 53// - The undelegated amount is positive
 54// - There is remaining uncollected amount
 55// - The current time is at or after the collectable time
 56//
 57// Parameters:
 58//   - currentTime: current timestamp to check against
 59//
 60// Returns:
 61//   - bool: true if the withdrawal can be collected, false otherwise
 62func (r *DelegationWithdrawResolver) IsCollectable(currentTime int64) bool {
 63	if r.withdraw.UnDelegateAmount() <= 0 {
 64		return false
 65	}
 66
 67	remaining := gnsmath.SafeSubInt64(r.withdraw.UnDelegateAmount(), r.withdraw.CollectedAmount())
 68	if remaining <= 0 {
 69		return false
 70	}
 71
 72	if currentTime < r.withdraw.CollectableTime() {
 73		return false
 74	}
 75
 76	return true
 77}
 78
 79// IsCollected returns whether the withdrawal has been fully collected.
 80//
 81// Returns:
 82//   - bool: true if fully collected, false otherwise
 83func (r *DelegationWithdrawResolver) IsCollected() bool {
 84	return r.withdraw.IsCollected()
 85}
 86
 87// collect processes the collection of the specified amount from this withdrawal.
 88// This method validates collectability and updates the collection state.
 89//
 90// Parameters:
 91//   - amount: GNS amount to add to this withdrawal's collected amount
 92//   - currentTime: Unix timestamp used to check lockup expiry and record collection time
 93//
 94// Returns:
 95//   - error: nil after the collection state is updated; errWithdrawNotCollectable when the withdrawal is not collectable
 96func (r *DelegationWithdrawResolver) Collect(amount int64, currentTime int64) error {
 97	if !r.IsCollectable(currentTime) {
 98		return errors.New(errWithdrawNotCollectable)
 99	}
100
101	r.withdraw.SetCollectedAmount(gnsmath.SafeAddInt64(r.withdraw.CollectedAmount(), amount))
102
103	if r.withdraw.UnDelegateAmount() == r.withdraw.CollectedAmount() {
104		r.withdraw.SetCollected(true)
105		r.withdraw.SetCollectedAt(currentTime)
106	}
107
108	return nil
109}
110
111// NewDelegationWithdraw creates a new delegation withdrawal with lockup period.
112// This is a convenience wrapper around staker.NewDelegationWithdraw.
113//
114// Parameters:
115//   - delegationID: unique identifier of the associated delegation
116//   - unDelegateAmount: amount being withdrawn
117//   - createdHeight: height when the withdrawal was created
118//   - createdAt: timestamp when the withdrawal was created
119//   - unDelegationLockupPeriod: duration of the lockup period in seconds
120//
121// Returns:
122//   - staker.DelegationWithdraw: new withdrawal instance with lockup
123func NewDelegationWithdraw(
124	delegationID,
125	unDelegateAmount,
126	createdHeight,
127	createdAt,
128	unDelegationLockupPeriod int64,
129) staker.DelegationWithdraw {
130	return staker.NewDelegationWithdraw(
131		delegationID,
132		unDelegateAmount,
133		createdHeight,
134		createdAt,
135		unDelegationLockupPeriod,
136	)
137}
138
139// NewDelegationWithdrawWithoutLockup creates a new delegation withdrawal that is immediately collectable.
140// This is a convenience wrapper around staker.NewDelegationWithdrawWithoutLockup.
141//
142// Parameters:
143//   - delegationID: unique identifier of the associated delegation
144//   - unDelegateAmount: amount being withdrawn
145//   - createdHeight: height when the withdrawal was created
146//   - createdAt: timestamp when the withdrawal was created
147//
148// Returns:
149//   - staker.DelegationWithdraw: new withdrawal instance that is immediately collectable
150func NewDelegationWithdrawWithoutLockup(
151	delegationID,
152	unDelegateAmount,
153	createdHeight,
154	createdAt int64,
155) staker.DelegationWithdraw {
156	return staker.NewDelegationWithdrawWithoutLockup(
157		delegationID,
158		unDelegateAmount,
159		createdHeight,
160		createdAt,
161	)
162}