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}