-
mconcat authored
package keeper
// DONTCOVER
import (
"fmt"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/osmosis-labs/osmosis/osmomath"
"github.com/osmosis-labs/osmosis/x/gamm/types"
)
const poolBalanceInvariantName = "pool-account-balance-equals-expected"
// RegisterInvariants registers all governance invariants
func RegisterInvariants(ir sdk.InvariantRegistry, keeper Keeper, bk types.BankKeeper) {
ir.RegisterRoute(types.ModuleName, poolBalanceInvariantName, PoolAccountInvariant(keeper, bk))
ir.RegisterRoute(types.ModuleName, "pool-total-weight", PoolTotalWeightInvariant(keeper, bk))
// ir.RegisterRoute(types.ModuleName, "pool-product-constant", PoolProductConstantInvariant(keeper))
// ir.RegisterRoute(types.ModuleName, "spot-price", SpotPriceInvariant(keeper, bk))
}
// AllInvariants runs all invariants of the gamm module
func AllInvariants(keeper Keeper, bk types.BankKeeper) sdk.Invariant {
return func(ctx sdk.Context) (string, bool) {
msg, broke := PoolAccountInvariant(keeper, bk)(ctx)
if broke {
return msg, broke
}
msg, broke = PoolProductConstantInvariant(keeper)(ctx)
if broke {
return msg, broke
}
return PoolTotalWeightInvariant(keeper, bk)(ctx)
}
}
// PoolAccountInvariant checks that the pool account balance reflects the sum of
// pool assets
func PoolAccountInvariant(keeper Keeper, bk types.BankKeeper) sdk.Invariant {
return func(ctx sdk.Context) (string, bool) {
pools, err := keeper.GetPools(ctx)
if err != nil {
return sdk.FormatInvariant(types.ModuleName, poolBalanceInvariantName,
fmt.Sprintf("\tgamm pool retrieval failed")), true
}
for _, pool := range pools {
assetCoins := types.PoolAssetsCoins(pool.GetAllPoolAssets())
accCoins := bk.GetAllBalances(ctx, pool.GetAddress())
if !assetCoins.IsEqual(accCoins) {
return sdk.FormatInvariant(types.ModuleName, poolBalanceInvariantName,
fmt.Sprintf("\tgamm pool id %d\n\tasset coins: %s\n\taccount coins: %s\n",
pool.GetId(), assetCoins, accCoins)), true
}
}
return sdk.FormatInvariant(types.ModuleName, poolBalanceInvariantName,
fmt.Sprintf("\tgamm all pool asset coins and account coins match\n")), false
}
}
// PoolTotalWeightInvariant checks that the pool total weight reflect the sum of
// pool weights
func PoolTotalWeightInvariant(keeper Keeper, bk types.BankKeeper) sdk.Invariant {
return func(ctx sdk.Context) (string, bool) {
pools, err := keeper.GetPools(ctx)
if err != nil {
return sdk.FormatInvariant(types.ModuleName, "pool-total-weight",