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

     1  package keeper
     2  
     3  import (
     4  	"fmt"
     5  	sdk "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types"
     6  	"github.com/fibonacci-chain/fbc/x/farm/types"
     7  )
     8  
     9  // RegisterInvariants registers all farm invariants
    10  func RegisterInvariants(ir sdk.InvariantRegistry, k Keeper) {
    11  	ir.RegisterRoute(types.ModuleName, "module-account", moduleAccountInvariant(k))
    12  	ir.RegisterRoute(types.ModuleName, "yield-farming-account", yieldFarmingAccountInvariant(k))
    13  	ir.RegisterRoute(types.ModuleName, "mint-farming-account", mintFarmingAccountInvariant(k))
    14  }
    15  
    16  // moduleAccountInvariant checks if farm ModuleAccount is consistent with the sum of deposit amount
    17  func moduleAccountInvariant(k Keeper) sdk.Invariant {
    18  	return func(ctx sdk.Context) (string, bool) {
    19  		// iterate all pools, then calculate the total deposit amount
    20  		totalDepositAmount := sdk.SysCoins{}
    21  		pools := k.GetFarmPools(ctx)
    22  		for _, pool := range pools {
    23  			totalDepositAmount = totalDepositAmount.Add2(pool.DepositAmount.ToCoins())
    24  		}
    25  
    26  		// iterate all lock infos
    27  		totalLockedAmount := sdk.SysCoins{}
    28  		k.IterateAllLockInfos(ctx, func(lockInfo types.LockInfo) (stop bool) {
    29  			totalLockedAmount = totalLockedAmount.Add2(sdk.NewDecCoins(lockInfo.Amount))
    30  			return false
    31  		})
    32  
    33  		// get farm module account
    34  		moduleAccAmount := k.SupplyKeeper().GetModuleAccount(ctx, types.ModuleName).GetCoins()
    35  
    36  		// make a comparison
    37  		broken := !(moduleAccAmount.IsEqual(totalDepositAmount.Add2(totalLockedAmount)))
    38  
    39  		return sdk.FormatInvariant(types.ModuleName, "ModuleAccount coins",
    40  			fmt.Sprintf("\texpected farm ModuleAccount coins: %s\n"+
    41  				"\tacutal farm ModuleAccount coins: %s\n",
    42  				totalDepositAmount, moduleAccAmount)), broken
    43  	}
    44  }
    45  
    46  // yieldFarmingAccountInvariant checks if yield_farming_account ModuleAccount is consistent
    47  // with the total accumulated rewards
    48  func yieldFarmingAccountInvariant(k Keeper) sdk.Invariant {
    49  	return func(ctx sdk.Context) (string, bool) {
    50  		// iterate all pools, then calculate the total deposit amount
    51  		expectedYieldModuleAccAmount := sdk.SysCoins{}
    52  		pools := k.GetFarmPools(ctx)
    53  		for _, pool := range pools {
    54  			expectedYieldModuleAccAmount = expectedYieldModuleAccAmount.Add2(pool.TotalAccumulatedRewards)
    55  			for _, yieldInfo := range pool.YieldedTokenInfos {
    56  				expectedYieldModuleAccAmount = expectedYieldModuleAccAmount.Add2(sdk.SysCoins{yieldInfo.RemainingAmount})
    57  			}
    58  		}
    59  
    60  		// get yield_farming_account module account
    61  		actualYieldModuleAccAmount := k.SupplyKeeper().GetModuleAccount(ctx, types.YieldFarmingAccount).GetCoins()
    62  
    63  		// make a comparison
    64  		broken := !(expectedYieldModuleAccAmount.IsEqual(actualYieldModuleAccAmount))
    65  
    66  		return sdk.FormatInvariant(types.ModuleName, "yield_farming_account coins",
    67  			fmt.Sprintf("\texpected yield_farming_account coins: %s\n"+
    68  				"\tacutal yield_farming_account coins: %s\n",
    69  				expectedYieldModuleAccAmount, actualYieldModuleAccAmount)), broken
    70  	}
    71  }
    72  
    73  // mintFarmingAccountInvariant checks if mint_farming_account ModuleAccount is consistent
    74  // with the sum of yielded native tokens
    75  func mintFarmingAccountInvariant(k Keeper) sdk.Invariant {
    76  	return func(ctx sdk.Context) (string, bool) {
    77  		broken := false
    78  
    79  		// get mint_farming_account module account
    80  		moduleAcc := k.SupplyKeeper().GetModuleAccount(ctx, types.MintFarmingAccount)
    81  
    82  		// get white_lists
    83  		whiteLists := k.GetWhitelist(ctx)
    84  		if len(whiteLists) != 0 {
    85  			if !moduleAcc.GetCoins().IsZero() {
    86  				broken = true
    87  			}
    88  		}
    89  
    90  		return sdk.FormatInvariant(types.ModuleName, "mint_farming_account coins",
    91  			fmt.Sprintf("\texpected mint_farming_account coins should be zero\n"+
    92  				"\tacutal mint_farming_account coins: %s\n"+
    93  				"\twhite lists: %s\n",
    94  				moduleAcc.GetCoins(), whiteLists)), broken
    95  	}
    96  }