diff --git a/x/cdp/keeper/savings.go b/x/cdp/keeper/savings.go index c9d3fe53..37dda6ec 100644 --- a/x/cdp/keeper/savings.go +++ b/x/cdp/keeper/savings.go @@ -26,7 +26,10 @@ func (k Keeper) DistributeSavingsRate(ctx sdk.Context, debtDenom string) error { modAccountCoins := k.getModuleAccountCoins(ctx, dp.Denom) totalSupplyLessModAccounts := k.supplyKeeper.GetSupply(ctx).GetTotal().Sub(modAccountCoins) - surplusDistributed := sdk.ZeroInt() + // values to use in interest calculation + totalSurplus := sdk.NewDecFromInt(surplusToDistribute) + totalSupply := sdk.NewDecFromInt(totalSupplyLessModAccounts.AmountOf(debtDenom)) + var iterationErr error k.accountKeeper.IterateAccounts(ctx, func(acc authexported.Account) (stop bool) { _, ok := acc.(supplyexported.ModuleAccountI) @@ -40,11 +43,10 @@ func (k Keeper) DistributeSavingsRate(ctx sdk.Context, debtDenom string) error { } // (balance * rewardToDisribute) / totalSupply // interest is the ratable fraction of savings rate owed to that account, rounded using bankers rounding - interest := (sdk.NewDecFromInt(debtAmount).Mul(sdk.NewDecFromInt(surplusToDistribute))).Quo(sdk.NewDecFromInt(totalSupplyLessModAccounts.AmountOf(debtDenom))).RoundInt() + interest := (sdk.NewDecFromInt(debtAmount).Mul(totalSurplus)).Quo(totalSupply).RoundInt() // sanity check, if we are going to over-distribute due to rounding, distribute only the remaining savings rate that hasn't been distributed. - if interest.GT(surplusToDistribute.Sub(surplusDistributed)) { - interest = surplusToDistribute.Sub(surplusDistributed) - } + interest = sdk.MinInt(interest, surplusToDistribute) + // sanity check - don't send saving rate if the rounded amount is zero if !interest.IsPositive() { return false @@ -55,7 +57,7 @@ func (k Keeper) DistributeSavingsRate(ctx sdk.Context, debtDenom string) error { iterationErr = err return true } - surplusDistributed = surplusDistributed.Add(interest) + surplusToDistribute = surplusToDistribute.Sub(interest) return false }) return iterationErr