package keeper_test import ( "fmt" "strconv" "testing" sdkmath "cosmossdk.io/math" "github.com/stretchr/testify/suite" sdk "github.com/cosmos/cosmos-sdk/types" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" tmproto "github.com/cometbft/cometbft/proto/tendermint/types" tmtime "github.com/cometbft/cometbft/types/time" "github.com/kava-labs/kava/app" auctionkeeper "github.com/kava-labs/kava/x/auction/keeper" "github.com/kava-labs/kava/x/hard/keeper" "github.com/kava-labs/kava/x/hard/types" ) // Test suite used for all keeper tests type KeeperTestSuite struct { suite.Suite keeper keeper.Keeper auctionKeeper auctionkeeper.Keeper app app.TestApp ctx sdk.Context addrs []sdk.AccAddress } // The default state used by each test func (suite *KeeperTestSuite) SetupTest() { config := sdk.GetConfig() app.SetBech32AddressPrefixes(config) tApp := app.NewTestApp() ctx := tApp.NewContext(true, tmproto.Header{Height: 1, Time: tmtime.Now()}) tApp.InitializeFromGenesisStates() _, addrs := app.GeneratePrivKeyAddressPairs(1) keeper := tApp.GetHardKeeper() suite.app = tApp suite.ctx = ctx suite.keeper = keeper suite.addrs = addrs } func (suite *KeeperTestSuite) TestGetSetDeleteDeposit() { addr := suite.addrs[0] dep := types.NewDeposit( addr, sdk.NewCoins(sdk.NewCoin("bnb", sdkmath.NewInt(100))), types.SupplyInterestFactors{types.NewSupplyInterestFactor("bnb", sdk.MustNewDecFromStr("1.12"))}, ) _, f := suite.keeper.GetDeposit(suite.ctx, addr) suite.Require().False(f) suite.keeper.SetDeposit(suite.ctx, dep) storedDeposit, f := suite.keeper.GetDeposit(suite.ctx, addr) suite.Require().True(f) suite.Require().Equal(dep, storedDeposit) suite.Require().NotPanics(func() { suite.keeper.DeleteDeposit(suite.ctx, dep) }) _, f = suite.keeper.GetDeposit(suite.ctx, addr) suite.Require().False(f) } func (suite *KeeperTestSuite) TestIterateDeposits() { var deposits types.Deposits for i := 0; i < 5; i++ { dep := types.NewDeposit( sdk.AccAddress("test"+fmt.Sprint(i)), sdk.NewCoins(sdk.NewCoin("bnb", sdkmath.NewInt(100))), types.SupplyInterestFactors{types.NewSupplyInterestFactor("bnb", sdk.MustNewDecFromStr("1.12"))}, ) deposits = append(deposits, dep) suite.keeper.SetDeposit(suite.ctx, dep) } var storedDeposits types.Deposits suite.keeper.IterateDeposits(suite.ctx, func(d types.Deposit) bool { storedDeposits = append(storedDeposits, d) return false }) suite.Require().Equal(deposits, storedDeposits) } func (suite *KeeperTestSuite) TestGetSetDeleteBorrow() { addr := suite.addrs[0] borrow := types.NewBorrow( addr, sdk.NewCoins(sdk.NewInt64Coin("bnb", 1e9)), types.BorrowInterestFactors{types.NewBorrowInterestFactor("bnb", sdk.MustNewDecFromStr("1.12"))}, ) _, f := suite.keeper.GetBorrow(suite.ctx, addr) suite.Require().False(f) suite.keeper.SetBorrow(suite.ctx, borrow) storedBorrow, f := suite.keeper.GetBorrow(suite.ctx, addr) suite.Require().True(f) suite.Require().Equal(borrow, storedBorrow) suite.Require().NotPanics(func() { suite.keeper.DeleteBorrow(suite.ctx, borrow) }) _, f = suite.keeper.GetBorrow(suite.ctx, addr) suite.Require().False(f) } func (suite *KeeperTestSuite) TestIterateBorrows() { var borrows types.Borrows for i := 0; i < 5; i++ { borrow := types.NewBorrow( sdk.AccAddress("test"+fmt.Sprint(i)), sdk.NewCoins(sdk.NewInt64Coin("bnb", 1e9)), types.BorrowInterestFactors{types.NewBorrowInterestFactor("bnb", sdk.MustNewDecFromStr("1.12"))}, ) borrows = append(borrows, borrow) suite.keeper.SetBorrow(suite.ctx, borrow) } var storedBorrows types.Borrows suite.keeper.IterateBorrows(suite.ctx, func(b types.Borrow) bool { storedBorrows = append(storedBorrows, b) return false }) suite.Require().Equal(borrows, storedBorrows) } func (suite *KeeperTestSuite) TestGetSetDeleteInterestRateModel() { denom := "test" model := types.NewInterestRateModel(sdk.MustNewDecFromStr("0.05"), sdk.MustNewDecFromStr("2"), sdk.MustNewDecFromStr("0.8"), sdk.MustNewDecFromStr("10")) borrowLimit := types.NewBorrowLimit(false, sdk.MustNewDecFromStr("0.2"), sdk.MustNewDecFromStr("0.5")) moneyMarket := types.NewMoneyMarket(denom, borrowLimit, denom+":usd", sdkmath.NewInt(1000000), model, sdk.MustNewDecFromStr("0.05"), sdk.ZeroDec()) _, f := suite.keeper.GetMoneyMarket(suite.ctx, denom) suite.Require().False(f) suite.keeper.SetMoneyMarket(suite.ctx, denom, moneyMarket) testMoneyMarket, f := suite.keeper.GetMoneyMarket(suite.ctx, denom) suite.Require().True(f) suite.Require().Equal(moneyMarket, testMoneyMarket) suite.Require().NotPanics(func() { suite.keeper.DeleteMoneyMarket(suite.ctx, denom) }) _, f = suite.keeper.GetMoneyMarket(suite.ctx, denom) suite.Require().False(f) } func (suite *KeeperTestSuite) TestIterateInterestRateModels() { testDenom := "test" var setMMs types.MoneyMarkets var setDenoms []string for i := 0; i < 5; i++ { // Initialize a new money market denom := testDenom + strconv.Itoa(i) model := types.NewInterestRateModel(sdk.MustNewDecFromStr("0.05"), sdk.MustNewDecFromStr("2"), sdk.MustNewDecFromStr("0.8"), sdk.MustNewDecFromStr("10")) borrowLimit := types.NewBorrowLimit(false, sdk.MustNewDecFromStr("0.2"), sdk.MustNewDecFromStr("0.5")) moneyMarket := types.NewMoneyMarket(denom, borrowLimit, denom+":usd", sdkmath.NewInt(1000000), model, sdk.MustNewDecFromStr("0.05"), sdk.ZeroDec()) // Store money market in the module's store suite.Require().NotPanics(func() { suite.keeper.SetMoneyMarket(suite.ctx, denom, moneyMarket) }) // Save the denom and model setDenoms = append(setDenoms, denom) setMMs = append(setMMs, moneyMarket) } var seenMMs types.MoneyMarkets var seenDenoms []string suite.keeper.IterateMoneyMarkets(suite.ctx, func(denom string, i types.MoneyMarket) bool { seenDenoms = append(seenDenoms, denom) seenMMs = append(seenMMs, i) return false }) suite.Require().Equal(setMMs, seenMMs) suite.Require().Equal(setDenoms, seenDenoms) } func (suite *KeeperTestSuite) TestGetSetBorrowedCoins() { suite.keeper.SetBorrowedCoins(suite.ctx, sdk.Coins{c("ukava", 123)}) coins, found := suite.keeper.GetBorrowedCoins(suite.ctx) suite.Require().True(found) suite.Require().Len(coins, 1) suite.Require().Equal(coins, cs(c("ukava", 123))) } func (suite *KeeperTestSuite) TestGetSetBorrowedCoins_Empty() { coins, found := suite.keeper.GetBorrowedCoins(suite.ctx) suite.Require().False(found) suite.Require().Empty(coins) // None set and setting empty coins should both be the same suite.keeper.SetBorrowedCoins(suite.ctx, sdk.Coins{}) coins, found = suite.keeper.GetBorrowedCoins(suite.ctx) suite.Require().False(found) suite.Require().Empty(coins) } func (suite *KeeperTestSuite) getAccountCoins(acc authtypes.AccountI) sdk.Coins { bk := suite.app.GetBankKeeper() return bk.GetAllBalances(suite.ctx, acc.GetAddress()) } func (suite *KeeperTestSuite) getAccount(addr sdk.AccAddress) authtypes.AccountI { ak := suite.app.GetAccountKeeper() return ak.GetAccount(suite.ctx, addr) } func (suite *KeeperTestSuite) getAccountAtCtx(addr sdk.AccAddress, ctx sdk.Context) authtypes.AccountI { ak := suite.app.GetAccountKeeper() return ak.GetAccount(ctx, addr) } func (suite *KeeperTestSuite) getModuleAccount(name string) authtypes.ModuleAccountI { ak := suite.app.GetAccountKeeper() return ak.GetModuleAccount(suite.ctx, name) } func (suite *KeeperTestSuite) getModuleAccountAtCtx(name string, ctx sdk.Context) authtypes.ModuleAccountI { ak := suite.app.GetAccountKeeper() return ak.GetModuleAccount(ctx, name) } func TestKeeperTestSuite(t *testing.T) { suite.Run(t, new(KeeperTestSuite)) }