Skip to content
This repository was archived by the owner on Dec 1, 2025. It is now read-only.

Commit 0e6face

Browse files
authored
Negative coin error fix (#390)
* Adding the condition which avoids negative coin error. * Adding condition to return error when undelegation tokens are more than delegated tokens. * Adding big test cases for delegate and undelegate validator-amount generation. * Using sdk errors to report insufficient funds to undelegate. * Changing the way of sorting WeightedAddressAmounts.
1 parent eacaf52 commit 0e6face

File tree

4 files changed

+1846
-9
lines changed

4 files changed

+1846
-9
lines changed

x/lscosmos/keeper/delegation_strategy.go

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -91,23 +91,33 @@ func (k Keeper) UndelegateMsgs(ctx sdk.Context, amount sdk.Int, denom string, de
9191

9292
// FetchValidatorsToDelegate gives a list of all validators having weighted amount for few and 1uatom for rest in order to auto claim all rewards accumulated in current epoch
9393
func FetchValidatorsToDelegate(valList types.AllowListedValidators, delegationState types.DelegationState, amount sdk.Coin) (types.ValAddressAmounts, error) {
94-
curDiffDistribution := GetIdealCurrentDelegations(valList, delegationState, amount, false)
94+
curDiffDistribution, err := GetIdealCurrentDelegations(valList, delegationState, amount, false)
95+
if err != nil {
96+
return nil, err
97+
}
9598
sort.Sort(sort.Reverse(curDiffDistribution))
9699

97100
return DivideAmountIntoValidatorSet(curDiffDistribution, amount)
98101
}
99102

100103
// FetchValidatorsToUndelegate gives a list of all validators having weighted amount for few and 1uatom for rest in order to auto claim all rewards accumulated in current epoch
101104
func FetchValidatorsToUndelegate(valList types.AllowListedValidators, delegationState types.DelegationState, amount sdk.Coin) (types.ValAddressAmounts, error) {
102-
currDiffDistribution := GetIdealCurrentDelegations(valList, delegationState, amount, true)
105+
currDiffDistribution, err := GetIdealCurrentDelegations(valList, delegationState, amount, true)
106+
if err != nil {
107+
return nil, err
108+
}
103109
sort.Sort(sort.Reverse(currDiffDistribution))
104110
return DivideUndelegateAmountIntoValidatorSet(currDiffDistribution, amount)
105111
}
106112

107113
// GetIdealCurrentDelegations returns ideal amount of delegations to validators on host chain
108-
func GetIdealCurrentDelegations(valList types.AllowListedValidators, delegationState types.DelegationState, amt sdk.Coin, reverse bool) types.WeightedAddressAmounts {
114+
func GetIdealCurrentDelegations(valList types.AllowListedValidators, delegationState types.DelegationState, amt sdk.Coin, reverse bool) (types.WeightedAddressAmounts, error) {
109115
totalDelegations := delegationState.TotalDelegations(amt.Denom)
110116

117+
if reverse && totalDelegations.IsLT(amt) {
118+
return nil, sdkerrors.Wrapf(types.ErrInsufficientFundsToUndelegate, "staked: %s, undelegate : %s", totalDelegations, amt)
119+
}
120+
111121
curDiffDistribution := types.WeightedAddressAmounts{}
112122
delegationMap := types.GetHostAccountDelegationMap(delegationState.HostAccountDelegations)
113123
var idealTokens, curTokens sdk.Int
@@ -135,7 +145,7 @@ func GetIdealCurrentDelegations(valList types.AllowListedValidators, delegationS
135145
})
136146
}
137147

138-
return curDiffDistribution
148+
return curDiffDistribution, nil
139149
}
140150

141151
// divideAmountWeightedSet : divides amount to be delegated or undelegated w.r.t weights.
@@ -168,8 +178,14 @@ func distributeCoinsAmongstValSet(ws types.WeightedAddressAmounts, coin sdk.Coin
168178
valAddrAmts = append(valAddrAmts, types.ValAddressAmount{ValidatorAddr: w.Address, Amount: coin})
169179
return valAddrAmts, sdk.NewInt64Coin(coin.Denom, 0)
170180
}
171-
valAddrAmts = append(valAddrAmts, types.ValAddressAmount{ValidatorAddr: w.Address, Amount: w.Coin()})
172-
coin = coin.SubAmount(w.Amount)
181+
182+
tempAmount := w.Amount
183+
if w.Amount.IsNegative() {
184+
tempAmount = sdk.ZeroInt()
185+
}
186+
187+
valAddrAmts = append(valAddrAmts, types.ValAddressAmount{ValidatorAddr: w.Address, Amount: sdk.NewCoin(w.Denom, tempAmount)})
188+
coin = coin.SubAmount(tempAmount)
173189
}
174190

175191
return valAddrAmts, coin

0 commit comments

Comments
 (0)