Optimize calculation in savings distribution (#573)

* fix exhibit 33 by storing remaining surplus

* simplify with sdk.MinInt - if statement logic & assignment is just
taking the minimum
This commit is contained in:
Nick DeLuca 2020-06-11 14:25:32 -05:00 committed by GitHub
parent 7ae76b8440
commit 5ba2706d56
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -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