Search Apps Documentation Source Content File Folder Download Copy Actions Download

delegation.gno

3.87 Kb ยท 148 lines
  1package v1
  2
  3import (
  4	"errors"
  5
  6	"gno.land/r/gnoswap/gov/staker"
  7)
  8
  9var (
 10	errCollectAmountExceedsCollectable = errors.New("amount to collect is greater than collectable amount")
 11)
 12
 13type DelegationResolver struct {
 14	delegation *staker.Delegation
 15}
 16
 17func NewDelegationResolver(delegation *staker.Delegation) *DelegationResolver {
 18	return &DelegationResolver{delegation}
 19}
 20
 21func (r *DelegationResolver) Get() *staker.Delegation {
 22	return r.delegation
 23}
 24
 25func (r *DelegationResolver) DelegatedAmount() int64 {
 26	return safeSubInt64(r.delegation.TotalDelegatedAmount(), r.delegation.UnDelegatedAmount())
 27}
 28
 29func (r *DelegationResolver) LockedAmount() int64 {
 30	return safeSubInt64(r.delegation.TotalDelegatedAmount(), r.delegation.CollectedAmount())
 31}
 32
 33func (r *DelegationResolver) IsEmpty() bool {
 34	return r.LockedAmount() == 0
 35}
 36
 37// CollectableAmount calculates the total amount that can be collected at the given time
 38func (r *DelegationResolver) CollectableAmount(currentTime int64) (total int64) {
 39	for _, withdraw := range r.delegation.Withdraws() {
 40		total = safeAddInt64(total, NewDelegationWithdrawResolver(withdraw).CollectableAmount(currentTime))
 41	}
 42	return total
 43}
 44
 45// UnDelegate processes an undelegation with lockup period
 46func (r *DelegationResolver) UnDelegate(
 47	amount, currentHeight, currentTimestamp, unDelegationLockupPeriod int64,
 48) {
 49	r.delegation.SetUnDelegateAmount(safeAddInt64(r.delegation.UnDelegatedAmount(), amount))
 50
 51	withdraw := NewDelegationWithdraw(
 52		r.delegation.ID(),
 53		amount,
 54		currentHeight,
 55		currentTimestamp,
 56		unDelegationLockupPeriod,
 57	)
 58	r.delegation.AddWithdraw(withdraw)
 59}
 60
 61// UnDelegateWithoutLockup processes an immediate undelegation without lockup
 62func (r *DelegationResolver) UnDelegateWithoutLockup(
 63	amount, currentHeight, currentTime int64,
 64) {
 65	r.delegation.SetUnDelegateAmount(safeAddInt64(r.delegation.UnDelegatedAmount(), amount))
 66	r.delegation.SetCollectedAmount(safeAddInt64(r.delegation.CollectedAmount(), amount))
 67}
 68
 69// processCollection handles the actual collection logic
 70func (r *DelegationResolver) processCollection(currentTime int64) (int64, error) {
 71	collectedAmount := int64(0)
 72	withdraws := r.delegation.Withdraws()
 73
 74	for _, withdraw := range withdraws {
 75		resolver := NewDelegationWithdrawResolver(withdraw)
 76
 77		collectableAmount := resolver.CollectableAmount(currentTime)
 78		if collectableAmount <= 0 {
 79			continue
 80		}
 81
 82		err := resolver.Collect(collectableAmount, currentTime)
 83		if err != nil {
 84			return 0, err
 85		}
 86
 87		updatedAmount, err := addToCollectedAmount(r.delegation.CollectedAmount(), collectableAmount)
 88		if err != nil {
 89			return 0, err
 90		}
 91
 92		r.delegation.SetCollectedAmount(updatedAmount)
 93		collectedAmount = safeAddInt64(collectedAmount, collectableAmount)
 94	}
 95
 96	// Skip filtering if nothing was collected
 97	if collectedAmount == 0 {
 98		return collectedAmount, nil
 99	}
100
101	currentIndex := 0
102
103	for _, withdraw := range withdraws {
104		if !withdraw.IsCollected() {
105			withdraws[currentIndex] = withdraw
106			currentIndex++
107		}
108	}
109
110	r.delegation.SetWithdraws(withdraws[:currentIndex])
111
112	return collectedAmount, nil
113}
114
115func addToCollectedAmount(collectedAmount, amount int64) (int64, error) {
116	if amount < 0 {
117		return 0, errors.New("amount must be non-negative")
118	}
119	return safeAddInt64(collectedAmount, amount), nil
120}
121
122// NewDelegation creates a new delegation.
123// This is a convenience wrapper around staker.NewDelegation.
124//
125// Parameters:
126//   - id: delegation ID
127//   - delegateFrom: delegator's address
128//   - delegateTo: delegatee's address
129//   - delegateAmount: amount to delegate
130//   - createdHeight: creation block height
131//   - createdAt: creation timestamp
132//
133// Returns:
134//   - *staker.Delegation: new delegation instance
135func NewDelegation(
136	id int64,
137	delegateFrom, delegateTo address,
138	delegateAmount, createdHeight, createdAt int64,
139) *staker.Delegation {
140	return staker.NewDelegation(
141		id,
142		delegateFrom,
143		delegateTo,
144		delegateAmount,
145		createdHeight,
146		createdAt,
147	)
148}