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