github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/x/distribution/keeper/invariants.go (about)

     1  package keeper
     2  
     3  import (
     4  	"fmt"
     5  
     6  	sdk "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types"
     7  
     8  	"github.com/fibonacci-chain/fbc/x/distribution/types"
     9  	"github.com/fibonacci-chain/fbc/x/staking/exported"
    10  )
    11  
    12  // RegisterInvariants registers all distribution invariants
    13  func RegisterInvariants(ir sdk.InvariantRegistry, k Keeper) {
    14  	ir.RegisterRoute(types.ModuleName, "nonnegative-commission", NonNegativeCommissionsInvariant(k))
    15  	ir.RegisterRoute(types.ModuleName, "can-withdraw", CanWithdrawInvariant(k))
    16  	ir.RegisterRoute(types.ModuleName, "module-account", ModuleAccountInvariant(k))
    17  }
    18  
    19  // NonNegativeCommissionsInvariant checks that accumulated commissions unwithdrawned fees are never negative
    20  func NonNegativeCommissionsInvariant(k Keeper) sdk.Invariant {
    21  	return func(ctx sdk.Context) (string, bool) {
    22  		var msg string
    23  		var count int
    24  		var commission sdk.SysCoins
    25  
    26  		k.IterateValidatorAccumulatedCommissions(ctx,
    27  			func(addr sdk.ValAddress, c types.ValidatorAccumulatedCommission) (stop bool) {
    28  				commission = c
    29  				if commission.IsAnyNegative() {
    30  					count++
    31  					msg += fmt.Sprintf("\t%v has negative accumulated commission coins: %v\n", addr, commission)
    32  				}
    33  				return false
    34  			})
    35  		broken := count != 0
    36  
    37  		return sdk.FormatInvariant(types.ModuleName, "nonnegative accumulated commission",
    38  			fmt.Sprintf("found %d validators with negative accumulated commission\n%s", count, msg)), broken
    39  	}
    40  }
    41  
    42  // CanWithdrawInvariant checks that current commission can be completely withdrawn
    43  func CanWithdrawInvariant(k Keeper) sdk.Invariant {
    44  	return func(ctx sdk.Context) (string, bool) {
    45  		var msg string
    46  		var count int
    47  
    48  		// cache, we don't want to write changes
    49  		ctx, _ = ctx.CacheContext()
    50  
    51  		// iterate over all validators
    52  		k.stakingKeeper.IterateValidators(ctx, func(_ int64, val exported.ValidatorI) (stop bool) {
    53  			valAddr := val.GetOperator()
    54  			accumCommission := k.GetValidatorAccumulatedCommission(ctx, valAddr)
    55  			if accumCommission.IsZero() {
    56  				return false
    57  			}
    58  			if _, err := k.WithdrawValidatorCommission(ctx, valAddr); err != nil {
    59  				count++
    60  				msg += fmt.Sprintf("\t%v failed to withdraw accumulated commission coins: %v. error: %v\n",
    61  					valAddr, accumCommission, err)
    62  			}
    63  			return false
    64  		})
    65  
    66  		broken := count != 0
    67  		return sdk.FormatInvariant(types.ModuleName, "withdraw commission", msg), broken
    68  	}
    69  }
    70  
    71  // ModuleAccountInvariant checks that the coins held by the distr ModuleAccount
    72  // is consistent with the sum of accumulated commissions
    73  func ModuleAccountInvariant(k Keeper) sdk.Invariant {
    74  	return func(ctx sdk.Context) (string, bool) {
    75  		var accumulatedCommission sdk.SysCoins
    76  		k.IterateValidatorAccumulatedCommissions(ctx,
    77  			func(_ sdk.ValAddress, commission types.ValidatorAccumulatedCommission) (stop bool) {
    78  				accumulatedCommission = accumulatedCommission.Add(commission...)
    79  				return false
    80  			})
    81  		communityPool := k.GetFeePoolCommunityCoins(ctx)
    82  		macc := k.GetDistributionAccount(ctx)
    83  		broken := !macc.GetCoins().IsEqual(communityPool.Add(accumulatedCommission...))
    84  		return sdk.FormatInvariant(types.ModuleName, "ModuleAccount coins",
    85  			fmt.Sprintf("\texpected distribution ModuleAccount coins:     %s\n"+
    86  				"\tacutal distribution ModuleAccount coins: %s\n",
    87  				accumulatedCommission, macc.GetCoins())), broken
    88  	}
    89  }