github.com/Finschia/finschia-sdk@v0.48.1/x/bank/keeper/keeper_test.go (about)

     1  package keeper_test
     2  
     3  import (
     4  	"fmt"
     5  	"testing"
     6  	"time"
     7  
     8  	"github.com/stretchr/testify/suite"
     9  	abci "github.com/tendermint/tendermint/abci/types"
    10  	tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
    11  
    12  	osttime "github.com/Finschia/ostracon/types/time"
    13  
    14  	"github.com/Finschia/finschia-sdk/baseapp"
    15  	"github.com/Finschia/finschia-sdk/simapp"
    16  	sdk "github.com/Finschia/finschia-sdk/types"
    17  	"github.com/Finschia/finschia-sdk/types/query"
    18  	authkeeper "github.com/Finschia/finschia-sdk/x/auth/keeper"
    19  	authtypes "github.com/Finschia/finschia-sdk/x/auth/types"
    20  	"github.com/Finschia/finschia-sdk/x/auth/vesting/exported"
    21  	vesting "github.com/Finschia/finschia-sdk/x/auth/vesting/types"
    22  	"github.com/Finschia/finschia-sdk/x/bank/keeper"
    23  	"github.com/Finschia/finschia-sdk/x/bank/types"
    24  	minttypes "github.com/Finschia/finschia-sdk/x/mint/types"
    25  )
    26  
    27  const (
    28  	fooDenom     = "foo"
    29  	barDenom     = "bar"
    30  	initialPower = int64(100)
    31  	holder       = "holder"
    32  	multiPerm    = "multiple permissions account"
    33  	randomPerm   = "random permission"
    34  )
    35  
    36  var (
    37  	holderAcc     = authtypes.NewEmptyModuleAccount(holder)
    38  	burnerAcc     = authtypes.NewEmptyModuleAccount(authtypes.Burner, authtypes.Burner)
    39  	minterAcc     = authtypes.NewEmptyModuleAccount(authtypes.Minter, authtypes.Minter)
    40  	multiPermAcc  = authtypes.NewEmptyModuleAccount(multiPerm, authtypes.Burner, authtypes.Minter, authtypes.Staking)
    41  	randomPermAcc = authtypes.NewEmptyModuleAccount(randomPerm, "random")
    42  
    43  	// The default power validators are initialized to have within tests
    44  	initTokens = sdk.TokensFromConsensusPower(initialPower, sdk.DefaultPowerReduction)
    45  	initCoins  = sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, initTokens))
    46  )
    47  
    48  func newFooCoin(amt int64) sdk.Coin {
    49  	return sdk.NewInt64Coin(fooDenom, amt)
    50  }
    51  
    52  func newBarCoin(amt int64) sdk.Coin {
    53  	return sdk.NewInt64Coin(barDenom, amt)
    54  }
    55  
    56  // nolint: interfacer
    57  func getCoinsByName(ctx sdk.Context, bk keeper.Keeper, ak types.AccountKeeper, moduleName string) sdk.Coins {
    58  	moduleAddress := ak.GetModuleAddress(moduleName)
    59  	macc := ak.GetAccount(ctx, moduleAddress)
    60  	if macc == nil {
    61  		return sdk.Coins(nil)
    62  	}
    63  
    64  	return bk.GetAllBalances(ctx, macc.GetAddress())
    65  }
    66  
    67  type IntegrationTestSuite struct {
    68  	suite.Suite
    69  
    70  	app         *simapp.SimApp
    71  	ctx         sdk.Context
    72  	queryClient types.QueryClient
    73  }
    74  
    75  func (suite *IntegrationTestSuite) initKeepersWithmAccPerms(blockedAddrs map[string]bool) (authkeeper.AccountKeeper, keeper.BaseKeeper) {
    76  	app := suite.app
    77  	maccPerms := simapp.GetMaccPerms()
    78  	appCodec := simapp.MakeTestEncodingConfig().Marshaler
    79  
    80  	maccPerms[holder] = nil
    81  	maccPerms[authtypes.Burner] = []string{authtypes.Burner}
    82  	maccPerms[authtypes.Minter] = []string{authtypes.Minter}
    83  	maccPerms[multiPerm] = []string{authtypes.Burner, authtypes.Minter, authtypes.Staking}
    84  	maccPerms[randomPerm] = []string{"random"}
    85  	authKeeper := authkeeper.NewAccountKeeper(
    86  		appCodec, app.GetKey(types.StoreKey), app.GetSubspace(types.ModuleName),
    87  		authtypes.ProtoBaseAccount, maccPerms,
    88  	)
    89  	keeper := keeper.NewBaseKeeper(
    90  		appCodec, app.GetKey(types.StoreKey), authKeeper,
    91  		app.GetSubspace(types.ModuleName), blockedAddrs,
    92  	)
    93  
    94  	return authKeeper, keeper
    95  }
    96  
    97  func (suite *IntegrationTestSuite) SetupTest() {
    98  	app := simapp.Setup(false)
    99  	ctx := app.BaseApp.NewContext(false, tmproto.Header{Time: time.Now()})
   100  
   101  	app.AccountKeeper.SetParams(ctx, authtypes.DefaultParams())
   102  	app.BankKeeper.SetParams(ctx, types.DefaultParams())
   103  
   104  	queryHelper := baseapp.NewQueryServerTestHelper(ctx, app.InterfaceRegistry())
   105  	types.RegisterQueryServer(queryHelper, app.BankKeeper)
   106  	queryClient := types.NewQueryClient(queryHelper)
   107  
   108  	suite.app = app
   109  	suite.ctx = ctx
   110  	suite.queryClient = queryClient
   111  }
   112  
   113  func (suite *IntegrationTestSuite) TestSupply() {
   114  	ctx := suite.ctx
   115  
   116  	require := suite.Require()
   117  
   118  	// add module accounts to supply keeper
   119  	authKeeper, keeper := suite.initKeepersWithmAccPerms(make(map[string]bool))
   120  
   121  	initialPower := int64(100)
   122  	initTokens := suite.app.StakingKeeper.TokensFromConsensusPower(ctx, initialPower)
   123  	totalSupply := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, initTokens))
   124  
   125  	// set burnerAcc balance
   126  	authKeeper.SetModuleAccount(ctx, burnerAcc)
   127  	require.NoError(keeper.MintCoins(ctx, authtypes.Minter, totalSupply))
   128  	require.NoError(keeper.SendCoinsFromModuleToAccount(ctx, authtypes.Minter, burnerAcc.GetAddress(), totalSupply))
   129  
   130  	total, _, err := keeper.GetPaginatedTotalSupply(ctx, &query.PageRequest{})
   131  	require.NoError(err)
   132  	require.Equal(totalSupply, total)
   133  
   134  	// burning all supplied tokens
   135  	err = keeper.BurnCoins(ctx, authtypes.Burner, totalSupply)
   136  	require.NoError(err)
   137  
   138  	total, _, err = keeper.GetPaginatedTotalSupply(ctx, &query.PageRequest{})
   139  	require.NoError(err)
   140  	require.Equal(total.String(), "")
   141  }
   142  
   143  func (suite *IntegrationTestSuite) TestSendCoinsFromModuleToAccount_Blacklist() {
   144  	app := suite.app
   145  	ctx := app.BaseApp.NewContext(false, tmproto.Header{Height: 1})
   146  	maccPerms := simapp.GetMaccPerms()
   147  	appCodec := app.AppCodec()
   148  
   149  	// add module accounts to supply keeper
   150  	maccPerms[holder] = nil
   151  	maccPerms[authtypes.Burner] = []string{authtypes.Burner}
   152  	maccPerms[authtypes.Minter] = []string{authtypes.Minter}
   153  	maccPerms[multiPerm] = []string{authtypes.Burner, authtypes.Minter, authtypes.Staking}
   154  	maccPerms[randomPerm] = []string{"random"}
   155  
   156  	addr1 := sdk.AccAddress([]byte("addr1_______________"))
   157  
   158  	authKeeper := authkeeper.NewAccountKeeper(
   159  		appCodec, app.GetKey(types.StoreKey), app.GetSubspace(types.ModuleName),
   160  		authtypes.ProtoBaseAccount, maccPerms,
   161  	)
   162  	keeper := keeper.NewBaseKeeper(
   163  		appCodec, app.GetKey(types.StoreKey), authKeeper,
   164  		app.GetSubspace(types.ModuleName), map[string]bool{addr1.String(): true},
   165  	)
   166  
   167  	suite.Require().NoError(keeper.MintCoins(ctx, minttypes.ModuleName, initCoins))
   168  	suite.Require().Error(keeper.SendCoinsFromModuleToAccount(
   169  		ctx, minttypes.ModuleName, addr1, initCoins,
   170  	))
   171  }
   172  
   173  func (suite *IntegrationTestSuite) TestSupply_SendCoins() {
   174  	ctx := suite.ctx
   175  
   176  	// add module accounts to supply keeper
   177  	authKeeper, keeper := suite.initKeepersWithmAccPerms(make(map[string]bool))
   178  
   179  	baseAcc := authKeeper.NewAccountWithAddress(ctx, authtypes.NewModuleAddress("baseAcc"))
   180  
   181  	// set initial balances
   182  	suite.
   183  		Require().
   184  		NoError(keeper.MintCoins(ctx, minttypes.ModuleName, initCoins))
   185  
   186  	suite.
   187  		Require().
   188  		NoError(keeper.SendCoinsFromModuleToAccount(ctx, minttypes.ModuleName, holderAcc.GetAddress(), initCoins))
   189  
   190  	authKeeper.SetModuleAccount(ctx, holderAcc)
   191  	authKeeper.SetModuleAccount(ctx, burnerAcc)
   192  	authKeeper.SetAccount(ctx, baseAcc)
   193  
   194  	suite.Require().Panics(func() {
   195  		_ = keeper.SendCoinsFromModuleToModule(ctx, "", holderAcc.GetName(), initCoins) // nolint:errcheck
   196  	})
   197  
   198  	suite.Require().Panics(func() {
   199  		_ = keeper.SendCoinsFromModuleToModule(ctx, authtypes.Burner, "", initCoins) // nolint:errcheck
   200  	})
   201  
   202  	suite.Require().Panics(func() {
   203  		_ = keeper.SendCoinsFromModuleToAccount(ctx, "", baseAcc.GetAddress(), initCoins) // nolint:errcheck
   204  	})
   205  
   206  	suite.Require().Error(
   207  		keeper.SendCoinsFromModuleToAccount(ctx, holderAcc.GetName(), baseAcc.GetAddress(), initCoins.Add(initCoins...)),
   208  	)
   209  
   210  	suite.Require().NoError(
   211  		keeper.SendCoinsFromModuleToModule(ctx, holderAcc.GetName(), authtypes.Burner, initCoins),
   212  	)
   213  	suite.Require().Equal(sdk.NewCoins().String(), getCoinsByName(ctx, keeper, authKeeper, holderAcc.GetName()).String())
   214  	suite.Require().Equal(initCoins, getCoinsByName(ctx, keeper, authKeeper, authtypes.Burner))
   215  
   216  	suite.Require().NoError(
   217  		keeper.SendCoinsFromModuleToAccount(ctx, authtypes.Burner, baseAcc.GetAddress(), initCoins),
   218  	)
   219  	suite.Require().Equal(sdk.NewCoins().String(), getCoinsByName(ctx, keeper, authKeeper, authtypes.Burner).String())
   220  	suite.Require().Equal(initCoins, keeper.GetAllBalances(ctx, baseAcc.GetAddress()))
   221  
   222  	suite.Require().NoError(keeper.SendCoinsFromAccountToModule(ctx, baseAcc.GetAddress(), authtypes.Burner, initCoins))
   223  	suite.Require().Equal(sdk.NewCoins().String(), keeper.GetAllBalances(ctx, baseAcc.GetAddress()).String())
   224  	suite.Require().Equal(initCoins, getCoinsByName(ctx, keeper, authKeeper, authtypes.Burner))
   225  }
   226  
   227  func (suite *IntegrationTestSuite) TestSupply_MintCoins() {
   228  	ctx := suite.ctx
   229  
   230  	// add module accounts to supply keeper
   231  	authKeeper, keeper := suite.initKeepersWithmAccPerms(make(map[string]bool))
   232  
   233  	authKeeper.SetModuleAccount(ctx, burnerAcc)
   234  	authKeeper.SetModuleAccount(ctx, minterAcc)
   235  	authKeeper.SetModuleAccount(ctx, multiPermAcc)
   236  	authKeeper.SetModuleAccount(ctx, randomPermAcc)
   237  
   238  	initialSupply, _, err := keeper.GetPaginatedTotalSupply(ctx, &query.PageRequest{})
   239  	suite.Require().NoError(err)
   240  
   241  	suite.Require().Panics(func() { keeper.MintCoins(ctx, "", initCoins) }, "no module account")                // nolint:errcheck
   242  	suite.Require().Panics(func() { keeper.MintCoins(ctx, authtypes.Burner, initCoins) }, "invalid permission") // nolint:errcheck
   243  
   244  	err = keeper.MintCoins(ctx, authtypes.Minter, sdk.Coins{sdk.Coin{Denom: "denom", Amount: sdk.NewInt(-10)}})
   245  	suite.Require().Error(err, "insufficient coins")
   246  
   247  	suite.Require().Panics(func() { keeper.MintCoins(ctx, randomPerm, initCoins) }) // nolint:errcheck
   248  
   249  	err = keeper.MintCoins(ctx, authtypes.Minter, initCoins)
   250  	suite.Require().NoError(err)
   251  
   252  	suite.Require().Equal(initCoins, getCoinsByName(ctx, keeper, authKeeper, authtypes.Minter))
   253  	totalSupply, _, err := keeper.GetPaginatedTotalSupply(ctx, &query.PageRequest{})
   254  	suite.Require().NoError(err)
   255  
   256  	suite.Require().Equal(initialSupply.Add(initCoins...), totalSupply)
   257  
   258  	// test same functionality on module account with multiple permissions
   259  	initialSupply, _, err = keeper.GetPaginatedTotalSupply(ctx, &query.PageRequest{})
   260  	suite.Require().NoError(err)
   261  
   262  	err = keeper.MintCoins(ctx, multiPermAcc.GetName(), initCoins)
   263  	suite.Require().NoError(err)
   264  
   265  	totalSupply, _, err = keeper.GetPaginatedTotalSupply(ctx, &query.PageRequest{})
   266  	suite.Require().NoError(err)
   267  	suite.Require().Equal(initCoins, getCoinsByName(ctx, keeper, authKeeper, multiPermAcc.GetName()))
   268  	suite.Require().Equal(initialSupply.Add(initCoins...), totalSupply)
   269  	suite.Require().Panics(func() { keeper.MintCoins(ctx, authtypes.Burner, initCoins) }) // nolint:errcheck
   270  }
   271  
   272  func (suite *IntegrationTestSuite) TestSupply_BurnCoins() {
   273  	ctx := suite.ctx
   274  	// add module accounts to supply keeper
   275  	authKeeper, keeper := suite.initKeepersWithmAccPerms(make(map[string]bool))
   276  
   277  	// set burnerAcc balance
   278  	authKeeper.SetModuleAccount(ctx, burnerAcc)
   279  	suite.
   280  		Require().
   281  		NoError(keeper.MintCoins(ctx, authtypes.Minter, initCoins))
   282  	suite.
   283  		Require().
   284  		NoError(keeper.SendCoinsFromModuleToAccount(ctx, authtypes.Minter, burnerAcc.GetAddress(), initCoins))
   285  
   286  	// inflate supply
   287  	suite.
   288  		Require().
   289  		NoError(keeper.MintCoins(ctx, authtypes.Minter, initCoins))
   290  	supplyAfterInflation, _, err := keeper.GetPaginatedTotalSupply(ctx, &query.PageRequest{})
   291  
   292  	suite.Require().Panics(func() { keeper.BurnCoins(ctx, "", initCoins) }, "no module account")                    // nolint:errcheck
   293  	suite.Require().Panics(func() { keeper.BurnCoins(ctx, authtypes.Minter, initCoins) }, "invalid permission")     // nolint:errcheck
   294  	suite.Require().Panics(func() { keeper.BurnCoins(ctx, randomPerm, supplyAfterInflation) }, "random permission") // nolint:errcheck
   295  	err = keeper.BurnCoins(ctx, authtypes.Burner, supplyAfterInflation)
   296  	suite.Require().Error(err, "insufficient coins")
   297  
   298  	err = keeper.BurnCoins(ctx, authtypes.Burner, initCoins)
   299  	suite.Require().NoError(err)
   300  	supplyAfterBurn, _, err := keeper.GetPaginatedTotalSupply(ctx, &query.PageRequest{})
   301  	suite.Require().NoError(err)
   302  	suite.Require().Equal(sdk.NewCoins().String(), getCoinsByName(ctx, keeper, authKeeper, authtypes.Burner).String())
   303  	suite.Require().Equal(supplyAfterInflation.Sub(initCoins), supplyAfterBurn)
   304  
   305  	// test same functionality on module account with multiple permissions
   306  	suite.
   307  		Require().
   308  		NoError(keeper.MintCoins(ctx, authtypes.Minter, initCoins))
   309  
   310  	supplyAfterInflation, _, err = keeper.GetPaginatedTotalSupply(ctx, &query.PageRequest{})
   311  	suite.Require().NoError(err)
   312  	suite.Require().NoError(keeper.SendCoins(ctx, authtypes.NewModuleAddress(authtypes.Minter), multiPermAcc.GetAddress(), initCoins))
   313  	authKeeper.SetModuleAccount(ctx, multiPermAcc)
   314  
   315  	err = keeper.BurnCoins(ctx, multiPermAcc.GetName(), initCoins)
   316  	supplyAfterBurn, _, err = keeper.GetPaginatedTotalSupply(ctx, &query.PageRequest{})
   317  	suite.Require().NoError(err)
   318  	suite.Require().NoError(err)
   319  	suite.Require().Equal(sdk.NewCoins().String(), getCoinsByName(ctx, keeper, authKeeper, multiPermAcc.GetName()).String())
   320  	suite.Require().Equal(supplyAfterInflation.Sub(initCoins), supplyAfterBurn)
   321  }
   322  
   323  func (suite *IntegrationTestSuite) TestSendCoinsNewAccount() {
   324  	app, ctx := suite.app, suite.ctx
   325  	balances := sdk.NewCoins(newFooCoin(100), newBarCoin(50))
   326  
   327  	addr1 := sdk.AccAddress([]byte("addr1_______________"))
   328  	acc1 := app.AccountKeeper.NewAccountWithAddress(ctx, addr1)
   329  	app.AccountKeeper.SetAccount(ctx, acc1)
   330  	suite.Require().NoError(simapp.FundAccount(app, ctx, addr1, balances))
   331  
   332  	acc1Balances := app.BankKeeper.GetAllBalances(ctx, addr1)
   333  	suite.Require().Equal(balances, acc1Balances)
   334  
   335  	addr2 := sdk.AccAddress([]byte("addr2_______________"))
   336  
   337  	suite.Require().Nil(app.AccountKeeper.GetAccount(ctx, addr2))
   338  	app.BankKeeper.GetAllBalances(ctx, addr2)
   339  	suite.Require().Empty(app.BankKeeper.GetAllBalances(ctx, addr2))
   340  
   341  	sendAmt := sdk.NewCoins(newFooCoin(50), newBarCoin(50))
   342  	suite.Require().NoError(app.BankKeeper.SendCoins(ctx, addr1, addr2, sendAmt))
   343  
   344  	acc2Balances := app.BankKeeper.GetAllBalances(ctx, addr2)
   345  	acc1Balances = app.BankKeeper.GetAllBalances(ctx, addr1)
   346  	suite.Require().Equal(sendAmt, acc2Balances)
   347  	updatedAcc1Bal := balances.Sub(sendAmt)
   348  	suite.Require().Len(acc1Balances, len(updatedAcc1Bal))
   349  	suite.Require().Equal(acc1Balances, updatedAcc1Bal)
   350  	suite.Require().NotNil(app.AccountKeeper.GetAccount(ctx, addr2))
   351  }
   352  
   353  func (suite *IntegrationTestSuite) TestInputOutputNewAccount() {
   354  	app, ctx := suite.app, suite.ctx
   355  
   356  	balances := sdk.NewCoins(newFooCoin(100), newBarCoin(50))
   357  	addr1 := sdk.AccAddress([]byte("addr1_______________"))
   358  	acc1 := app.AccountKeeper.NewAccountWithAddress(ctx, addr1)
   359  	app.AccountKeeper.SetAccount(ctx, acc1)
   360  	suite.Require().NoError(simapp.FundAccount(app, ctx, addr1, balances))
   361  
   362  	acc1Balances := app.BankKeeper.GetAllBalances(ctx, addr1)
   363  	suite.Require().Equal(balances, acc1Balances)
   364  
   365  	addr2 := sdk.AccAddress([]byte("addr2_______________"))
   366  
   367  	suite.Require().Nil(app.AccountKeeper.GetAccount(ctx, addr2))
   368  	suite.Require().Empty(app.BankKeeper.GetAllBalances(ctx, addr2))
   369  
   370  	inputs := []types.Input{
   371  		{Address: addr1.String(), Coins: sdk.NewCoins(newFooCoin(30), newBarCoin(10))},
   372  	}
   373  	outputs := []types.Output{
   374  		{Address: addr2.String(), Coins: sdk.NewCoins(newFooCoin(30), newBarCoin(10))},
   375  	}
   376  
   377  	suite.Require().NoError(app.BankKeeper.InputOutputCoins(ctx, inputs, outputs))
   378  
   379  	expected := sdk.NewCoins(newFooCoin(30), newBarCoin(10))
   380  	acc2Balances := app.BankKeeper.GetAllBalances(ctx, addr2)
   381  	suite.Require().Equal(expected, acc2Balances)
   382  	suite.Require().NotNil(app.AccountKeeper.GetAccount(ctx, addr2))
   383  }
   384  
   385  func (suite *IntegrationTestSuite) TestInputOutputCoins() {
   386  	app, ctx := suite.app, suite.ctx
   387  	balances := sdk.NewCoins(newFooCoin(90), newBarCoin(30))
   388  
   389  	addr1 := sdk.AccAddress([]byte("addr1_______________"))
   390  	acc1 := app.AccountKeeper.NewAccountWithAddress(ctx, addr1)
   391  	app.AccountKeeper.SetAccount(ctx, acc1)
   392  
   393  	addr2 := sdk.AccAddress([]byte("addr2_______________"))
   394  	acc2 := app.AccountKeeper.NewAccountWithAddress(ctx, addr2)
   395  	app.AccountKeeper.SetAccount(ctx, acc2)
   396  
   397  	addr3 := sdk.AccAddress([]byte("addr3_______________"))
   398  	acc3 := app.AccountKeeper.NewAccountWithAddress(ctx, addr3)
   399  	app.AccountKeeper.SetAccount(ctx, acc3)
   400  
   401  	inputs := []types.Input{
   402  		{Address: addr1.String(), Coins: sdk.NewCoins(newFooCoin(30), newBarCoin(10))},
   403  		{Address: addr1.String(), Coins: sdk.NewCoins(newFooCoin(30), newBarCoin(10))},
   404  	}
   405  	outputs := []types.Output{
   406  		{Address: addr2.String(), Coins: sdk.NewCoins(newFooCoin(30), newBarCoin(10))},
   407  		{Address: addr3.String(), Coins: sdk.NewCoins(newFooCoin(30), newBarCoin(10))},
   408  	}
   409  
   410  	suite.Require().Error(app.BankKeeper.InputOutputCoins(ctx, inputs, []types.Output{}))
   411  	suite.Require().Error(app.BankKeeper.InputOutputCoins(ctx, inputs, outputs))
   412  
   413  	suite.Require().NoError(simapp.FundAccount(app, ctx, addr1, balances))
   414  
   415  	insufficientInputs := []types.Input{
   416  		{Address: addr1.String(), Coins: sdk.NewCoins(newFooCoin(300), newBarCoin(100))},
   417  		{Address: addr1.String(), Coins: sdk.NewCoins(newFooCoin(300), newBarCoin(100))},
   418  	}
   419  	insufficientOutputs := []types.Output{
   420  		{Address: addr2.String(), Coins: sdk.NewCoins(newFooCoin(300), newBarCoin(100))},
   421  		{Address: addr3.String(), Coins: sdk.NewCoins(newFooCoin(300), newBarCoin(100))},
   422  	}
   423  	suite.Require().Error(app.BankKeeper.InputOutputCoins(ctx, insufficientInputs, insufficientOutputs))
   424  	suite.Require().NoError(app.BankKeeper.InputOutputCoins(ctx, inputs, outputs))
   425  
   426  	acc1Balances := app.BankKeeper.GetAllBalances(ctx, addr1)
   427  	expected := sdk.NewCoins(newFooCoin(30), newBarCoin(10))
   428  	suite.Require().Equal(expected, acc1Balances)
   429  
   430  	acc2Balances := app.BankKeeper.GetAllBalances(ctx, addr2)
   431  	suite.Require().Equal(expected, acc2Balances)
   432  
   433  	acc3Balances := app.BankKeeper.GetAllBalances(ctx, addr3)
   434  	suite.Require().Equal(expected, acc3Balances)
   435  }
   436  
   437  func (suite *IntegrationTestSuite) TestSendCoins() {
   438  	app, ctx := suite.app, suite.ctx
   439  	balances := sdk.NewCoins(newFooCoin(100), newBarCoin(50))
   440  
   441  	addr1 := sdk.AccAddress("addr1_______________")
   442  	acc1 := app.AccountKeeper.NewAccountWithAddress(ctx, addr1)
   443  	app.AccountKeeper.SetAccount(ctx, acc1)
   444  
   445  	addr2 := sdk.AccAddress("addr2_______________")
   446  	acc2 := app.AccountKeeper.NewAccountWithAddress(ctx, addr2)
   447  	app.AccountKeeper.SetAccount(ctx, acc2)
   448  	suite.Require().NoError(simapp.FundAccount(app, ctx, addr2, balances))
   449  
   450  	sendAmt := sdk.NewCoins(newFooCoin(50), newBarCoin(25))
   451  	suite.Require().Error(app.BankKeeper.SendCoins(ctx, addr1, addr2, sendAmt))
   452  
   453  	suite.Require().NoError(simapp.FundAccount(app, ctx, addr1, balances))
   454  	suite.Require().NoError(app.BankKeeper.SendCoins(ctx, addr1, addr2, sendAmt))
   455  
   456  	acc1Balances := app.BankKeeper.GetAllBalances(ctx, addr1)
   457  	expected := sdk.NewCoins(newFooCoin(50), newBarCoin(25))
   458  	suite.Require().Equal(expected, acc1Balances)
   459  
   460  	acc2Balances := app.BankKeeper.GetAllBalances(ctx, addr2)
   461  	expected = sdk.NewCoins(newFooCoin(150), newBarCoin(75))
   462  	suite.Require().Equal(expected, acc2Balances)
   463  
   464  	// we sent all foo coins to acc2, so foo balance should be deleted for acc1 and bar should be still there
   465  	var coins []sdk.Coin
   466  	app.BankKeeper.IterateAccountBalances(ctx, addr1, func(c sdk.Coin) (stop bool) {
   467  		coins = append(coins, c)
   468  		return true
   469  	})
   470  	suite.Require().Len(coins, 1)
   471  	suite.Require().Equal(newBarCoin(25), coins[0], "expected only bar coins in the account balance, got: %v", coins)
   472  }
   473  
   474  func (suite *IntegrationTestSuite) TestValidateBalance() {
   475  	app, ctx := suite.app, suite.ctx
   476  	now := osttime.Now()
   477  	ctx = ctx.WithBlockHeader(tmproto.Header{Time: now})
   478  	endTime := now.Add(24 * time.Hour)
   479  
   480  	addr1 := sdk.AccAddress([]byte("addr1_______________"))
   481  	addr2 := sdk.AccAddress([]byte("addr2_______________"))
   482  
   483  	suite.Require().Error(app.BankKeeper.ValidateBalance(ctx, addr1))
   484  
   485  	acc := app.AccountKeeper.NewAccountWithAddress(ctx, addr1)
   486  	app.AccountKeeper.SetAccount(ctx, acc)
   487  
   488  	balances := sdk.NewCoins(newFooCoin(100))
   489  	suite.Require().NoError(simapp.FundAccount(app, ctx, addr1, balances))
   490  	suite.Require().NoError(app.BankKeeper.ValidateBalance(ctx, addr1))
   491  
   492  	bacc := authtypes.NewBaseAccountWithAddress(addr2)
   493  	vacc := vesting.NewContinuousVestingAccount(bacc, balances.Add(balances...), now.Unix(), endTime.Unix())
   494  
   495  	app.AccountKeeper.SetAccount(ctx, vacc)
   496  	suite.Require().NoError(simapp.FundAccount(app, ctx, addr2, balances))
   497  	suite.Require().Error(app.BankKeeper.ValidateBalance(ctx, addr2))
   498  }
   499  
   500  func (suite *IntegrationTestSuite) TestSendEnabled() {
   501  	app, ctx := suite.app, suite.ctx
   502  	enabled := true
   503  	params := types.DefaultParams()
   504  	suite.Require().Equal(enabled, params.DefaultSendEnabled)
   505  
   506  	app.BankKeeper.SetParams(ctx, params)
   507  
   508  	bondCoin := sdk.NewCoin(sdk.DefaultBondDenom, sdk.OneInt())
   509  	fooCoin := sdk.NewCoin("foocoin", sdk.OneInt())
   510  	barCoin := sdk.NewCoin("barcoin", sdk.OneInt())
   511  
   512  	// assert with default (all denom) send enabled both Bar and Bond Denom are enabled
   513  	suite.Require().Equal(enabled, app.BankKeeper.IsSendEnabledCoin(ctx, barCoin))
   514  	suite.Require().Equal(enabled, app.BankKeeper.IsSendEnabledCoin(ctx, bondCoin))
   515  
   516  	// Both coins should be send enabled.
   517  	err := app.BankKeeper.IsSendEnabledCoins(ctx, fooCoin, bondCoin)
   518  	suite.Require().NoError(err)
   519  
   520  	// Set default send_enabled to !enabled, add a foodenom that overrides default as enabled
   521  	params.DefaultSendEnabled = !enabled
   522  	params = params.SetSendEnabledParam(fooCoin.Denom, enabled)
   523  	app.BankKeeper.SetParams(ctx, params)
   524  
   525  	// Expect our specific override to be enabled, others to be !enabled.
   526  	suite.Require().Equal(enabled, app.BankKeeper.IsSendEnabledCoin(ctx, fooCoin))
   527  	suite.Require().Equal(!enabled, app.BankKeeper.IsSendEnabledCoin(ctx, barCoin))
   528  	suite.Require().Equal(!enabled, app.BankKeeper.IsSendEnabledCoin(ctx, bondCoin))
   529  
   530  	// Foo coin should be send enabled.
   531  	err = app.BankKeeper.IsSendEnabledCoins(ctx, fooCoin)
   532  	suite.Require().NoError(err)
   533  
   534  	// Expect an error when one coin is not send enabled.
   535  	err = app.BankKeeper.IsSendEnabledCoins(ctx, fooCoin, bondCoin)
   536  	suite.Require().Error(err)
   537  
   538  	// Expect an error when all coins are not send enabled.
   539  	err = app.BankKeeper.IsSendEnabledCoins(ctx, bondCoin, barCoin)
   540  	suite.Require().Error(err)
   541  }
   542  
   543  func (suite *IntegrationTestSuite) TestHasBalance() {
   544  	app, ctx := suite.app, suite.ctx
   545  	addr := sdk.AccAddress([]byte("addr1_______________"))
   546  
   547  	acc := app.AccountKeeper.NewAccountWithAddress(ctx, addr)
   548  	app.AccountKeeper.SetAccount(ctx, acc)
   549  
   550  	balances := sdk.NewCoins(newFooCoin(100))
   551  	suite.Require().False(app.BankKeeper.HasBalance(ctx, addr, newFooCoin(99)))
   552  
   553  	suite.Require().NoError(simapp.FundAccount(app, ctx, addr, balances))
   554  	suite.Require().False(app.BankKeeper.HasBalance(ctx, addr, newFooCoin(101)))
   555  	suite.Require().True(app.BankKeeper.HasBalance(ctx, addr, newFooCoin(100)))
   556  	suite.Require().True(app.BankKeeper.HasBalance(ctx, addr, newFooCoin(1)))
   557  }
   558  
   559  func (suite *IntegrationTestSuite) TestMsgSendEvents() {
   560  	app, ctx := suite.app, suite.ctx
   561  	addr := sdk.AccAddress([]byte("addr1_______________"))
   562  	addr2 := sdk.AccAddress([]byte("addr2_______________"))
   563  	acc := app.AccountKeeper.NewAccountWithAddress(ctx, addr)
   564  
   565  	app.AccountKeeper.SetAccount(ctx, acc)
   566  	newCoins := sdk.NewCoins(sdk.NewInt64Coin(fooDenom, 50))
   567  	suite.Require().NoError(simapp.FundAccount(app, ctx, addr, newCoins))
   568  
   569  	suite.Require().NoError(app.BankKeeper.SendCoins(ctx, addr, addr2, newCoins))
   570  	event1 := sdk.Event{
   571  		Type:       types.EventTypeTransfer,
   572  		Attributes: []abci.EventAttribute{},
   573  	}
   574  	event1.Attributes = append(
   575  		event1.Attributes,
   576  		abci.EventAttribute{Key: []byte(types.AttributeKeyRecipient), Value: []byte(addr2.String())},
   577  	)
   578  	event1.Attributes = append(
   579  		event1.Attributes,
   580  		abci.EventAttribute{Key: []byte(types.AttributeKeySender), Value: []byte(addr.String())},
   581  	)
   582  	event1.Attributes = append(
   583  		event1.Attributes,
   584  		abci.EventAttribute{Key: []byte(sdk.AttributeKeyAmount), Value: []byte(newCoins.String())},
   585  	)
   586  
   587  	// events are shifted due to the funding account events
   588  	events := ctx.EventManager().ABCIEvents()
   589  	suite.Require().Equal(8, len(events))
   590  	suite.Require().Equal(abci.Event(event1), events[7])
   591  }
   592  
   593  func (suite *IntegrationTestSuite) TestMsgMultiSendEvents() {
   594  	app, ctx := suite.app, suite.ctx
   595  
   596  	app.BankKeeper.SetParams(ctx, types.DefaultParams())
   597  
   598  	addr := sdk.AccAddress([]byte("addr1_______________"))
   599  	addr2 := sdk.AccAddress([]byte("addr2_______________"))
   600  	addr3 := sdk.AccAddress([]byte("addr3_______________"))
   601  	addr4 := sdk.AccAddress([]byte("addr4_______________"))
   602  	acc := app.AccountKeeper.NewAccountWithAddress(ctx, addr)
   603  	acc2 := app.AccountKeeper.NewAccountWithAddress(ctx, addr2)
   604  
   605  	app.AccountKeeper.SetAccount(ctx, acc)
   606  	app.AccountKeeper.SetAccount(ctx, acc2)
   607  
   608  	newCoins := sdk.NewCoins(sdk.NewInt64Coin(fooDenom, 50))
   609  	newCoins2 := sdk.NewCoins(sdk.NewInt64Coin(barDenom, 100))
   610  	inputs := []types.Input{
   611  		{Address: addr.String(), Coins: newCoins},
   612  		{Address: addr2.String(), Coins: newCoins2},
   613  	}
   614  	outputs := []types.Output{
   615  		{Address: addr3.String(), Coins: newCoins},
   616  		{Address: addr4.String(), Coins: newCoins2},
   617  	}
   618  
   619  	suite.Require().Error(app.BankKeeper.InputOutputCoins(ctx, inputs, outputs))
   620  
   621  	events := ctx.EventManager().ABCIEvents()
   622  	suite.Require().Equal(0, len(events))
   623  
   624  	// Set addr's coins but not addr2's coins
   625  	suite.Require().NoError(simapp.FundAccount(app, ctx, addr, sdk.NewCoins(sdk.NewInt64Coin(fooDenom, 50))))
   626  	suite.Require().Error(app.BankKeeper.InputOutputCoins(ctx, inputs, outputs))
   627  
   628  	events = ctx.EventManager().ABCIEvents()
   629  	suite.Require().Equal(6, len(events)) // 6 events because account funding causes extra minting + coin_spent + coin_recv events
   630  
   631  	// Set addr's coins and addr2's coins
   632  	suite.Require().NoError(simapp.FundAccount(app, ctx, addr, sdk.NewCoins(sdk.NewInt64Coin(fooDenom, 50))))
   633  	newCoins = sdk.NewCoins(sdk.NewInt64Coin(fooDenom, 50))
   634  
   635  	suite.Require().NoError(simapp.FundAccount(app, ctx, addr2, sdk.NewCoins(sdk.NewInt64Coin(barDenom, 100))))
   636  	newCoins2 = sdk.NewCoins(sdk.NewInt64Coin(barDenom, 100))
   637  
   638  	suite.Require().NoError(app.BankKeeper.InputOutputCoins(ctx, inputs, outputs))
   639  
   640  	events = ctx.EventManager().ABCIEvents()
   641  	suite.Require().Equal(22, len(events)) // 22 due to account funding + coin_spent + coin_recv events
   642  
   643  	event1 := sdk.Event{
   644  		Type:       types.EventTypeTransfer,
   645  		Attributes: []abci.EventAttribute{},
   646  	}
   647  	event1.Attributes = append(
   648  		event1.Attributes,
   649  		abci.EventAttribute{Key: []byte(types.AttributeKeyRecipient), Value: []byte(addr3.String())},
   650  	)
   651  	event1.Attributes = append(
   652  		event1.Attributes,
   653  		abci.EventAttribute{Key: []byte(sdk.AttributeKeyAmount), Value: []byte(newCoins.String())})
   654  	event2 := sdk.Event{
   655  		Type:       types.EventTypeTransfer,
   656  		Attributes: []abci.EventAttribute{},
   657  	}
   658  	event2.Attributes = append(
   659  		event2.Attributes,
   660  		abci.EventAttribute{Key: []byte(types.AttributeKeyRecipient), Value: []byte(addr4.String())},
   661  	)
   662  	event2.Attributes = append(
   663  		event2.Attributes,
   664  		abci.EventAttribute{Key: []byte(sdk.AttributeKeyAmount), Value: []byte(newCoins2.String())},
   665  	)
   666  	// events are shifted due to the funding account events
   667  	suite.Require().Equal(abci.Event(event1), events[19])
   668  	suite.Require().Equal(abci.Event(event2), events[21])
   669  }
   670  
   671  func (suite *IntegrationTestSuite) TestSpendableCoins() {
   672  	app, ctx := suite.app, suite.ctx
   673  	now := osttime.Now()
   674  	ctx = ctx.WithBlockHeader(tmproto.Header{Time: now})
   675  	endTime := now.Add(24 * time.Hour)
   676  
   677  	origCoins := sdk.NewCoins(sdk.NewInt64Coin("stake", 100))
   678  	delCoins := sdk.NewCoins(sdk.NewInt64Coin("stake", 50))
   679  
   680  	addr1 := sdk.AccAddress([]byte("addr1_______________"))
   681  	addr2 := sdk.AccAddress([]byte("addr2_______________"))
   682  	addrModule := sdk.AccAddress([]byte("moduleAcc___________"))
   683  
   684  	macc := app.AccountKeeper.NewAccountWithAddress(ctx, addrModule)
   685  	bacc := authtypes.NewBaseAccountWithAddress(addr1)
   686  	vacc := vesting.NewContinuousVestingAccount(bacc, origCoins, ctx.BlockHeader().Time.Unix(), endTime.Unix())
   687  	acc := app.AccountKeeper.NewAccountWithAddress(ctx, addr2)
   688  
   689  	app.AccountKeeper.SetAccount(ctx, macc)
   690  	app.AccountKeeper.SetAccount(ctx, vacc)
   691  	app.AccountKeeper.SetAccount(ctx, acc)
   692  	suite.Require().NoError(simapp.FundAccount(app, ctx, addr1, origCoins))
   693  	suite.Require().NoError(simapp.FundAccount(app, ctx, addr2, origCoins))
   694  
   695  	suite.Require().Equal(origCoins, app.BankKeeper.SpendableCoins(ctx, addr2))
   696  
   697  	ctx = ctx.WithBlockTime(now.Add(12 * time.Hour))
   698  	suite.Require().NoError(app.BankKeeper.DelegateCoins(ctx, addr2, addrModule, delCoins))
   699  	suite.Require().Equal(origCoins.Sub(delCoins), app.BankKeeper.SpendableCoins(ctx, addr1))
   700  }
   701  
   702  func (suite *IntegrationTestSuite) TestVestingAccountSend() {
   703  	app, ctx := suite.app, suite.ctx
   704  	now := osttime.Now()
   705  	ctx = ctx.WithBlockHeader(tmproto.Header{Time: now})
   706  	endTime := now.Add(24 * time.Hour)
   707  
   708  	origCoins := sdk.NewCoins(sdk.NewInt64Coin("stake", 100))
   709  	sendCoins := sdk.NewCoins(sdk.NewInt64Coin("stake", 50))
   710  
   711  	addr1 := sdk.AccAddress([]byte("addr1_______________"))
   712  	addr2 := sdk.AccAddress([]byte("addr2_______________"))
   713  
   714  	bacc := authtypes.NewBaseAccountWithAddress(addr1)
   715  	vacc := vesting.NewContinuousVestingAccount(bacc, origCoins, now.Unix(), endTime.Unix())
   716  
   717  	app.AccountKeeper.SetAccount(ctx, vacc)
   718  	suite.Require().NoError(simapp.FundAccount(app, ctx, addr1, origCoins))
   719  
   720  	// require that no coins be sendable at the beginning of the vesting schedule
   721  	suite.Require().Error(app.BankKeeper.SendCoins(ctx, addr1, addr2, sendCoins))
   722  
   723  	// receive some coins
   724  	suite.Require().NoError(simapp.FundAccount(app, ctx, addr1, sendCoins))
   725  	// require that all vested coins are spendable plus any received
   726  	ctx = ctx.WithBlockTime(now.Add(12 * time.Hour))
   727  	suite.Require().NoError(app.BankKeeper.SendCoins(ctx, addr1, addr2, sendCoins))
   728  	suite.Require().Equal(origCoins, app.BankKeeper.GetAllBalances(ctx, addr1))
   729  }
   730  
   731  func (suite *IntegrationTestSuite) TestPeriodicVestingAccountSend() {
   732  	app, ctx := suite.app, suite.ctx
   733  	now := osttime.Now()
   734  	ctx = ctx.WithBlockHeader(tmproto.Header{Time: now})
   735  	origCoins := sdk.NewCoins(sdk.NewInt64Coin("stake", 100))
   736  	sendCoins := sdk.NewCoins(sdk.NewInt64Coin("stake", 50))
   737  
   738  	addr1 := sdk.AccAddress([]byte("addr1_______________"))
   739  	addr2 := sdk.AccAddress([]byte("addr2_______________"))
   740  	periods := vesting.Periods{
   741  		vesting.Period{Length: int64(12 * 60 * 60), Amount: sdk.Coins{sdk.NewInt64Coin("stake", 50)}},
   742  		vesting.Period{Length: int64(6 * 60 * 60), Amount: sdk.Coins{sdk.NewInt64Coin("stake", 25)}},
   743  		vesting.Period{Length: int64(6 * 60 * 60), Amount: sdk.Coins{sdk.NewInt64Coin("stake", 25)}},
   744  	}
   745  
   746  	bacc := authtypes.NewBaseAccountWithAddress(addr1)
   747  	vacc := vesting.NewPeriodicVestingAccount(bacc, origCoins, ctx.BlockHeader().Time.Unix(), periods)
   748  
   749  	app.AccountKeeper.SetAccount(ctx, vacc)
   750  	suite.Require().NoError(simapp.FundAccount(app, ctx, addr1, origCoins))
   751  
   752  	// require that no coins be sendable at the beginning of the vesting schedule
   753  	suite.Require().Error(app.BankKeeper.SendCoins(ctx, addr1, addr2, sendCoins))
   754  
   755  	// receive some coins
   756  	suite.Require().NoError(simapp.FundAccount(app, ctx, addr1, sendCoins))
   757  
   758  	// require that all vested coins are spendable plus any received
   759  	ctx = ctx.WithBlockTime(now.Add(12 * time.Hour))
   760  	suite.Require().NoError(app.BankKeeper.SendCoins(ctx, addr1, addr2, sendCoins))
   761  	suite.Require().Equal(origCoins, app.BankKeeper.GetAllBalances(ctx, addr1))
   762  }
   763  
   764  func (suite *IntegrationTestSuite) TestVestingAccountReceive() {
   765  	app, ctx := suite.app, suite.ctx
   766  	now := osttime.Now()
   767  	ctx = ctx.WithBlockHeader(tmproto.Header{Time: now})
   768  	endTime := now.Add(24 * time.Hour)
   769  
   770  	origCoins := sdk.NewCoins(sdk.NewInt64Coin("stake", 100))
   771  	sendCoins := sdk.NewCoins(sdk.NewInt64Coin("stake", 50))
   772  
   773  	addr1 := sdk.AccAddress([]byte("addr1_______________"))
   774  	addr2 := sdk.AccAddress([]byte("addr2_______________"))
   775  
   776  	bacc := authtypes.NewBaseAccountWithAddress(addr1)
   777  	vacc := vesting.NewContinuousVestingAccount(bacc, origCoins, ctx.BlockHeader().Time.Unix(), endTime.Unix())
   778  	acc := app.AccountKeeper.NewAccountWithAddress(ctx, addr2)
   779  
   780  	app.AccountKeeper.SetAccount(ctx, vacc)
   781  	app.AccountKeeper.SetAccount(ctx, acc)
   782  	suite.Require().NoError(simapp.FundAccount(app, ctx, addr1, origCoins))
   783  	suite.Require().NoError(simapp.FundAccount(app, ctx, addr2, origCoins))
   784  
   785  	// send some coins to the vesting account
   786  	suite.Require().NoError(app.BankKeeper.SendCoins(ctx, addr2, addr1, sendCoins))
   787  
   788  	// require the coins are spendable
   789  	vacc = app.AccountKeeper.GetAccount(ctx, addr1).(*vesting.ContinuousVestingAccount)
   790  	balances := app.BankKeeper.GetAllBalances(ctx, addr1)
   791  	suite.Require().Equal(origCoins.Add(sendCoins...), balances)
   792  	suite.Require().Equal(balances.Sub(vacc.LockedCoins(now)), sendCoins)
   793  
   794  	// require coins are spendable plus any that have vested
   795  	suite.Require().Equal(balances.Sub(vacc.LockedCoins(now.Add(12*time.Hour))), origCoins)
   796  }
   797  
   798  func (suite *IntegrationTestSuite) TestPeriodicVestingAccountReceive() {
   799  	app, ctx := suite.app, suite.ctx
   800  	now := osttime.Now()
   801  	ctx = ctx.WithBlockHeader(tmproto.Header{Time: now})
   802  
   803  	origCoins := sdk.NewCoins(sdk.NewInt64Coin("stake", 100))
   804  	sendCoins := sdk.NewCoins(sdk.NewInt64Coin("stake", 50))
   805  
   806  	addr1 := sdk.AccAddress([]byte("addr1_______________"))
   807  	addr2 := sdk.AccAddress([]byte("addr2_______________"))
   808  
   809  	bacc := authtypes.NewBaseAccountWithAddress(addr1)
   810  	periods := vesting.Periods{
   811  		vesting.Period{Length: int64(12 * 60 * 60), Amount: sdk.Coins{sdk.NewInt64Coin("stake", 50)}},
   812  		vesting.Period{Length: int64(6 * 60 * 60), Amount: sdk.Coins{sdk.NewInt64Coin("stake", 25)}},
   813  		vesting.Period{Length: int64(6 * 60 * 60), Amount: sdk.Coins{sdk.NewInt64Coin("stake", 25)}},
   814  	}
   815  
   816  	vacc := vesting.NewPeriodicVestingAccount(bacc, origCoins, ctx.BlockHeader().Time.Unix(), periods)
   817  	acc := app.AccountKeeper.NewAccountWithAddress(ctx, addr2)
   818  
   819  	app.AccountKeeper.SetAccount(ctx, vacc)
   820  	app.AccountKeeper.SetAccount(ctx, acc)
   821  	suite.Require().NoError(simapp.FundAccount(app, ctx, addr1, origCoins))
   822  	suite.Require().NoError(simapp.FundAccount(app, ctx, addr2, origCoins))
   823  
   824  	// send some coins to the vesting account
   825  	suite.Require().NoError(app.BankKeeper.SendCoins(ctx, addr2, addr1, sendCoins))
   826  
   827  	// require the coins are spendable
   828  	vacc = app.AccountKeeper.GetAccount(ctx, addr1).(*vesting.PeriodicVestingAccount)
   829  	balances := app.BankKeeper.GetAllBalances(ctx, addr1)
   830  	suite.Require().Equal(origCoins.Add(sendCoins...), balances)
   831  	suite.Require().Equal(balances.Sub(vacc.LockedCoins(now)), sendCoins)
   832  
   833  	// require coins are spendable plus any that have vested
   834  	suite.Require().Equal(balances.Sub(vacc.LockedCoins(now.Add(12*time.Hour))), origCoins)
   835  }
   836  
   837  func (suite *IntegrationTestSuite) TestDelegateCoins() {
   838  	app, ctx := suite.app, suite.ctx
   839  	now := osttime.Now()
   840  	ctx = ctx.WithBlockHeader(tmproto.Header{Time: now})
   841  	endTime := now.Add(24 * time.Hour)
   842  
   843  	origCoins := sdk.NewCoins(sdk.NewInt64Coin("stake", 100))
   844  	delCoins := sdk.NewCoins(sdk.NewInt64Coin("stake", 50))
   845  
   846  	addr1 := sdk.AccAddress([]byte("addr1_______________"))
   847  	addr2 := sdk.AccAddress([]byte("addr2_______________"))
   848  	addrModule := sdk.AccAddress([]byte("moduleAcc___________"))
   849  
   850  	macc := app.AccountKeeper.NewAccountWithAddress(ctx, addrModule) // we don't need to define an actual module account bc we just need the address for testing
   851  	acc := app.AccountKeeper.NewAccountWithAddress(ctx, addr2)
   852  	bacc := authtypes.NewBaseAccountWithAddress(addr1)
   853  	vacc := vesting.NewContinuousVestingAccount(bacc, origCoins, ctx.BlockHeader().Time.Unix(), endTime.Unix())
   854  
   855  	app.AccountKeeper.SetAccount(ctx, vacc)
   856  	app.AccountKeeper.SetAccount(ctx, acc)
   857  	app.AccountKeeper.SetAccount(ctx, macc)
   858  	suite.Require().NoError(simapp.FundAccount(app, ctx, addr1, origCoins))
   859  	suite.Require().NoError(simapp.FundAccount(app, ctx, addr2, origCoins))
   860  
   861  	ctx = ctx.WithBlockTime(now.Add(12 * time.Hour))
   862  
   863  	// require the ability for a non-vesting account to delegate
   864  	suite.Require().NoError(app.BankKeeper.DelegateCoins(ctx, addr2, addrModule, delCoins))
   865  	suite.Require().Equal(origCoins.Sub(delCoins), app.BankKeeper.GetAllBalances(ctx, addr2))
   866  	suite.Require().Equal(delCoins, app.BankKeeper.GetAllBalances(ctx, addrModule))
   867  
   868  	// require the ability for a vesting account to delegate
   869  	suite.Require().NoError(app.BankKeeper.DelegateCoins(ctx, addr1, addrModule, delCoins))
   870  	suite.Require().Equal(delCoins, app.BankKeeper.GetAllBalances(ctx, addr1))
   871  
   872  	// require that delegated vesting amount is equal to what was delegated with DelegateCoins
   873  	acc = app.AccountKeeper.GetAccount(ctx, addr1)
   874  	vestingAcc, ok := acc.(exported.VestingAccount)
   875  	suite.Require().True(ok)
   876  	suite.Require().Equal(delCoins, vestingAcc.GetDelegatedVesting())
   877  }
   878  
   879  func (suite *IntegrationTestSuite) TestDelegateCoins_Invalid() {
   880  	app, ctx := suite.app, suite.ctx
   881  
   882  	origCoins := sdk.NewCoins(newFooCoin(100))
   883  	delCoins := sdk.NewCoins(newFooCoin(50))
   884  
   885  	addr1 := sdk.AccAddress([]byte("addr1_______________"))
   886  	addrModule := sdk.AccAddress([]byte("moduleAcc___________"))
   887  	macc := app.AccountKeeper.NewAccountWithAddress(ctx, addrModule) // we don't need to define an actual module account bc we just need the address for testing
   888  	acc := app.AccountKeeper.NewAccountWithAddress(ctx, addr1)
   889  
   890  	suite.Require().Error(app.BankKeeper.DelegateCoins(ctx, addr1, addrModule, delCoins))
   891  	invalidCoins := sdk.Coins{sdk.Coin{Denom: "fooDenom", Amount: sdk.NewInt(-50)}}
   892  	suite.Require().Error(app.BankKeeper.DelegateCoins(ctx, addr1, addrModule, invalidCoins))
   893  
   894  	app.AccountKeeper.SetAccount(ctx, macc)
   895  	suite.Require().Error(app.BankKeeper.DelegateCoins(ctx, addr1, addrModule, delCoins))
   896  	app.AccountKeeper.SetAccount(ctx, acc)
   897  	suite.Require().Error(app.BankKeeper.DelegateCoins(ctx, addr1, addrModule, origCoins.Add(origCoins...)))
   898  }
   899  
   900  func (suite *IntegrationTestSuite) TestUndelegateCoins() {
   901  	app, ctx := suite.app, suite.ctx
   902  	now := osttime.Now()
   903  	ctx = ctx.WithBlockHeader(tmproto.Header{Time: now})
   904  	endTime := now.Add(24 * time.Hour)
   905  
   906  	origCoins := sdk.NewCoins(sdk.NewInt64Coin("stake", 100))
   907  	delCoins := sdk.NewCoins(sdk.NewInt64Coin("stake", 50))
   908  
   909  	addr1 := sdk.AccAddress([]byte("addr1_______________"))
   910  	addr2 := sdk.AccAddress([]byte("addr2_______________"))
   911  	addrModule := sdk.AccAddress([]byte("moduleAcc___________"))
   912  
   913  	bacc := authtypes.NewBaseAccountWithAddress(addr1)
   914  	macc := app.AccountKeeper.NewAccountWithAddress(ctx, addrModule) // we don't need to define an actual module account bc we just need the address for testing
   915  
   916  	vacc := vesting.NewContinuousVestingAccount(bacc, origCoins, ctx.BlockHeader().Time.Unix(), endTime.Unix())
   917  	acc := app.AccountKeeper.NewAccountWithAddress(ctx, addr2)
   918  
   919  	app.AccountKeeper.SetAccount(ctx, vacc)
   920  	app.AccountKeeper.SetAccount(ctx, acc)
   921  	app.AccountKeeper.SetAccount(ctx, macc)
   922  	suite.Require().NoError(simapp.FundAccount(app, ctx, addr1, origCoins))
   923  	suite.Require().NoError(simapp.FundAccount(app, ctx, addr2, origCoins))
   924  
   925  	ctx = ctx.WithBlockTime(now.Add(12 * time.Hour))
   926  
   927  	// require the ability for a non-vesting account to delegate
   928  	err := app.BankKeeper.DelegateCoins(ctx, addr2, addrModule, delCoins)
   929  	suite.Require().NoError(err)
   930  
   931  	suite.Require().Equal(origCoins.Sub(delCoins), app.BankKeeper.GetAllBalances(ctx, addr2))
   932  	suite.Require().Equal(delCoins, app.BankKeeper.GetAllBalances(ctx, addrModule))
   933  
   934  	// require the ability for a non-vesting account to undelegate
   935  	suite.Require().NoError(app.BankKeeper.UndelegateCoins(ctx, addrModule, addr2, delCoins))
   936  
   937  	suite.Require().Equal(origCoins, app.BankKeeper.GetAllBalances(ctx, addr2))
   938  	suite.Require().True(app.BankKeeper.GetAllBalances(ctx, addrModule).Empty())
   939  
   940  	// require the ability for a vesting account to delegate
   941  	suite.Require().NoError(app.BankKeeper.DelegateCoins(ctx, addr1, addrModule, delCoins))
   942  
   943  	suite.Require().Equal(origCoins.Sub(delCoins), app.BankKeeper.GetAllBalances(ctx, addr1))
   944  	suite.Require().Equal(delCoins, app.BankKeeper.GetAllBalances(ctx, addrModule))
   945  
   946  	// require the ability for a vesting account to undelegate
   947  	suite.Require().NoError(app.BankKeeper.UndelegateCoins(ctx, addrModule, addr1, delCoins))
   948  
   949  	suite.Require().Equal(origCoins, app.BankKeeper.GetAllBalances(ctx, addr1))
   950  	suite.Require().True(app.BankKeeper.GetAllBalances(ctx, addrModule).Empty())
   951  
   952  	// require that delegated vesting amount is completely empty, since they were completely undelegated
   953  	acc = app.AccountKeeper.GetAccount(ctx, addr1)
   954  	vestingAcc, ok := acc.(exported.VestingAccount)
   955  	suite.Require().True(ok)
   956  	suite.Require().Empty(vestingAcc.GetDelegatedVesting())
   957  }
   958  
   959  func (suite *IntegrationTestSuite) TestUndelegateCoins_Invalid() {
   960  	app, ctx := suite.app, suite.ctx
   961  
   962  	origCoins := sdk.NewCoins(newFooCoin(100))
   963  	delCoins := sdk.NewCoins(newFooCoin(50))
   964  
   965  	addr1 := sdk.AccAddress([]byte("addr1_______________"))
   966  	addrModule := sdk.AccAddress([]byte("moduleAcc___________"))
   967  	macc := app.AccountKeeper.NewAccountWithAddress(ctx, addrModule) // we don't need to define an actual module account bc we just need the address for testing
   968  	acc := app.AccountKeeper.NewAccountWithAddress(ctx, addr1)
   969  
   970  	suite.Require().Error(app.BankKeeper.UndelegateCoins(ctx, addrModule, addr1, delCoins))
   971  
   972  	app.AccountKeeper.SetAccount(ctx, macc)
   973  	suite.Require().NoError(simapp.FundAccount(app, ctx, addr1, origCoins))
   974  
   975  	suite.Require().Error(app.BankKeeper.UndelegateCoins(ctx, addrModule, addr1, delCoins))
   976  	app.AccountKeeper.SetAccount(ctx, acc)
   977  
   978  	suite.Require().Error(app.BankKeeper.UndelegateCoins(ctx, addrModule, addr1, delCoins))
   979  }
   980  
   981  func (suite *IntegrationTestSuite) TestSetDenomMetaData() {
   982  	app, ctx := suite.app, suite.ctx
   983  
   984  	metadata := suite.getTestMetadata()
   985  
   986  	for i := range []int{1, 2} {
   987  		app.BankKeeper.SetDenomMetaData(ctx, metadata[i])
   988  	}
   989  
   990  	actualMetadata, found := app.BankKeeper.GetDenomMetaData(ctx, metadata[1].Base)
   991  	suite.Require().True(found)
   992  	suite.Require().Equal(metadata[1].GetBase(), actualMetadata.GetBase())
   993  	suite.Require().Equal(metadata[1].GetDisplay(), actualMetadata.GetDisplay())
   994  	suite.Require().Equal(metadata[1].GetDescription(), actualMetadata.GetDescription())
   995  	suite.Require().Equal(metadata[1].GetDenomUnits()[1].GetDenom(), actualMetadata.GetDenomUnits()[1].GetDenom())
   996  	suite.Require().Equal(metadata[1].GetDenomUnits()[1].GetExponent(), actualMetadata.GetDenomUnits()[1].GetExponent())
   997  	suite.Require().Equal(metadata[1].GetDenomUnits()[1].GetAliases(), actualMetadata.GetDenomUnits()[1].GetAliases())
   998  }
   999  
  1000  func (suite *IntegrationTestSuite) TestIterateAllDenomMetaData() {
  1001  	app, ctx := suite.app, suite.ctx
  1002  
  1003  	expectedMetadata := suite.getTestMetadata()
  1004  	// set metadata
  1005  	for i := range []int{1, 2} {
  1006  		app.BankKeeper.SetDenomMetaData(ctx, expectedMetadata[i])
  1007  	}
  1008  	// retrieve metadata
  1009  	actualMetadata := make([]types.Metadata, 0)
  1010  	app.BankKeeper.IterateAllDenomMetaData(ctx, func(metadata types.Metadata) bool {
  1011  		actualMetadata = append(actualMetadata, metadata)
  1012  		return false
  1013  	})
  1014  	// execute checks
  1015  	for i := range []int{1, 2} {
  1016  		suite.Require().Equal(expectedMetadata[i].GetBase(), actualMetadata[i].GetBase())
  1017  		suite.Require().Equal(expectedMetadata[i].GetDisplay(), actualMetadata[i].GetDisplay())
  1018  		suite.Require().Equal(expectedMetadata[i].GetDescription(), actualMetadata[i].GetDescription())
  1019  		suite.Require().Equal(expectedMetadata[i].GetDenomUnits()[1].GetDenom(), actualMetadata[i].GetDenomUnits()[1].GetDenom())
  1020  		suite.Require().Equal(expectedMetadata[i].GetDenomUnits()[1].GetExponent(), actualMetadata[i].GetDenomUnits()[1].GetExponent())
  1021  		suite.Require().Equal(expectedMetadata[i].GetDenomUnits()[1].GetAliases(), actualMetadata[i].GetDenomUnits()[1].GetAliases())
  1022  	}
  1023  }
  1024  
  1025  func (suite *IntegrationTestSuite) TestBalanceTrackingEvents() {
  1026  	// replace account keeper and bank keeper otherwise the account keeper won't be aware of the
  1027  	// existence of the new module account because GetModuleAccount checks for the existence via
  1028  	// permissions map and not via state... weird
  1029  	maccPerms := simapp.GetMaccPerms()
  1030  	maccPerms[multiPerm] = []string{authtypes.Burner, authtypes.Minter, authtypes.Staking}
  1031  
  1032  	suite.app.AccountKeeper = authkeeper.NewAccountKeeper(
  1033  		suite.app.AppCodec(), suite.app.GetKey(authtypes.StoreKey), suite.app.GetSubspace(authtypes.ModuleName),
  1034  		authtypes.ProtoBaseAccount, maccPerms,
  1035  	)
  1036  
  1037  	suite.app.BankKeeper = keeper.NewBaseKeeper(suite.app.AppCodec(), suite.app.GetKey(types.StoreKey),
  1038  		suite.app.AccountKeeper, suite.app.GetSubspace(types.ModuleName), nil)
  1039  
  1040  	// set account with multiple permissions
  1041  	suite.app.AccountKeeper.SetModuleAccount(suite.ctx, multiPermAcc)
  1042  	// mint coins
  1043  	suite.Require().NoError(
  1044  		suite.app.BankKeeper.MintCoins(
  1045  			suite.ctx,
  1046  			multiPermAcc.Name,
  1047  			sdk.NewCoins(sdk.NewCoin("utxo", sdk.NewInt(100000)))),
  1048  	)
  1049  	// send coins to address
  1050  	addr1 := sdk.AccAddress("addr1_______________")
  1051  	suite.Require().NoError(
  1052  		suite.app.BankKeeper.SendCoinsFromModuleToAccount(
  1053  			suite.ctx,
  1054  			multiPermAcc.Name,
  1055  			addr1,
  1056  			sdk.NewCoins(sdk.NewCoin("utxo", sdk.NewInt(50000))),
  1057  		),
  1058  	)
  1059  
  1060  	// burn coins from module account
  1061  	suite.Require().NoError(
  1062  		suite.app.BankKeeper.BurnCoins(
  1063  			suite.ctx,
  1064  			multiPermAcc.Name,
  1065  			sdk.NewCoins(sdk.NewInt64Coin("utxo", 1000)),
  1066  		),
  1067  	)
  1068  
  1069  	// process balances and supply from events
  1070  	supply := sdk.NewCoins()
  1071  
  1072  	balances := make(map[string]sdk.Coins)
  1073  
  1074  	for _, e := range suite.ctx.EventManager().ABCIEvents() {
  1075  		switch e.Type {
  1076  		case types.EventTypeCoinBurn:
  1077  			burnedCoins, err := sdk.ParseCoinsNormalized((string)(e.Attributes[1].Value))
  1078  			suite.Require().NoError(err)
  1079  			supply = supply.Sub(burnedCoins)
  1080  
  1081  		case types.EventTypeCoinMint:
  1082  			mintedCoins, err := sdk.ParseCoinsNormalized((string)(e.Attributes[1].Value))
  1083  			suite.Require().NoError(err)
  1084  			supply = supply.Add(mintedCoins...)
  1085  
  1086  		case types.EventTypeCoinSpent:
  1087  			coinsSpent, err := sdk.ParseCoinsNormalized((string)(e.Attributes[1].Value))
  1088  			suite.Require().NoError(err)
  1089  			spender, err := sdk.AccAddressFromBech32((string)(e.Attributes[0].Value))
  1090  			suite.Require().NoError(err)
  1091  			balances[spender.String()] = balances[spender.String()].Sub(coinsSpent)
  1092  
  1093  		case types.EventTypeCoinReceived:
  1094  			coinsRecv, err := sdk.ParseCoinsNormalized((string)(e.Attributes[1].Value))
  1095  			suite.Require().NoError(err)
  1096  			receiver, err := sdk.AccAddressFromBech32((string)(e.Attributes[0].Value))
  1097  			suite.Require().NoError(err)
  1098  			balances[receiver.String()] = balances[receiver.String()].Add(coinsRecv...)
  1099  		}
  1100  	}
  1101  
  1102  	// check balance and supply tracking
  1103  	suite.Require().True(suite.app.BankKeeper.HasSupply(suite.ctx, "utxo"))
  1104  	savedSupply := suite.app.BankKeeper.GetSupply(suite.ctx, "utxo")
  1105  	utxoSupply := savedSupply
  1106  	suite.Require().Equal(utxoSupply.Amount, supply.AmountOf("utxo"))
  1107  	// iterate accounts and check balances
  1108  	suite.app.BankKeeper.IterateAllBalances(suite.ctx, func(address sdk.AccAddress, coin sdk.Coin) (stop bool) {
  1109  		// if it's not utxo coin then skip
  1110  		if coin.Denom != "utxo" {
  1111  			return false
  1112  		}
  1113  
  1114  		balance, exists := balances[address.String()]
  1115  		suite.Require().True(exists)
  1116  
  1117  		expectedUtxo := sdk.NewCoin("utxo", balance.AmountOf(coin.Denom))
  1118  		suite.Require().Equal(expectedUtxo.String(), coin.String())
  1119  		return false
  1120  	})
  1121  }
  1122  
  1123  func (suite *IntegrationTestSuite) getTestMetadata() []types.Metadata {
  1124  	return []types.Metadata{
  1125  		{
  1126  			Name:        "Cosmos Hub Atom",
  1127  			Symbol:      "ATOM",
  1128  			Description: "The native staking token of the Cosmos Hub.",
  1129  			DenomUnits: []*types.DenomUnit{
  1130  				{"uatom", uint32(0), []string{"microatom"}},
  1131  				{"matom", uint32(3), []string{"milliatom"}},
  1132  				{"atom", uint32(6), nil},
  1133  			},
  1134  			Base:    "uatom",
  1135  			Display: "atom",
  1136  		},
  1137  		{
  1138  			Name:        "Token",
  1139  			Symbol:      "TOKEN",
  1140  			Description: "The native staking token of the Token Hub.",
  1141  			DenomUnits: []*types.DenomUnit{
  1142  				{"1token", uint32(5), []string{"decitoken"}},
  1143  				{"2token", uint32(4), []string{"centitoken"}},
  1144  				{"3token", uint32(7), []string{"dekatoken"}},
  1145  			},
  1146  			Base:    "utoken",
  1147  			Display: "token",
  1148  		},
  1149  	}
  1150  }
  1151  
  1152  func (suite *IntegrationTestSuite) TestMintCoinRestrictions() {
  1153  	type BankMintingRestrictionFn func(ctx sdk.Context, coins sdk.Coins) error
  1154  
  1155  	maccPerms := simapp.GetMaccPerms()
  1156  	maccPerms[multiPerm] = []string{authtypes.Burner, authtypes.Minter, authtypes.Staking}
  1157  
  1158  	suite.app.AccountKeeper = authkeeper.NewAccountKeeper(
  1159  		suite.app.AppCodec(), suite.app.GetKey(authtypes.StoreKey), suite.app.GetSubspace(authtypes.ModuleName),
  1160  		authtypes.ProtoBaseAccount, maccPerms,
  1161  	)
  1162  	suite.app.AccountKeeper.SetModuleAccount(suite.ctx, multiPermAcc)
  1163  
  1164  	type testCase struct {
  1165  		coinsToTry sdk.Coin
  1166  		expectPass bool
  1167  	}
  1168  
  1169  	tests := []struct {
  1170  		name          string
  1171  		restrictionFn BankMintingRestrictionFn
  1172  		testCases     []testCase
  1173  	}{
  1174  		{
  1175  			"restriction",
  1176  			func(ctx sdk.Context, coins sdk.Coins) error {
  1177  				for _, coin := range coins {
  1178  					if coin.Denom != fooDenom {
  1179  						return fmt.Errorf("Module %s only has perms for minting %s coins, tried minting %s coins", types.ModuleName, fooDenom, coin.Denom)
  1180  					}
  1181  				}
  1182  				return nil
  1183  			},
  1184  			[]testCase{
  1185  				{
  1186  					coinsToTry: newFooCoin(100),
  1187  					expectPass: true,
  1188  				},
  1189  				{
  1190  					coinsToTry: newBarCoin(100),
  1191  					expectPass: false,
  1192  				},
  1193  			},
  1194  		},
  1195  	}
  1196  
  1197  	for _, test := range tests {
  1198  		suite.app.BankKeeper = keeper.NewBaseKeeper(suite.app.AppCodec(), suite.app.GetKey(types.StoreKey),
  1199  			suite.app.AccountKeeper, suite.app.GetSubspace(types.ModuleName), nil).WithMintCoinsRestriction(keeper.MintingRestrictionFn(test.restrictionFn))
  1200  		for _, testCase := range test.testCases {
  1201  			if testCase.expectPass {
  1202  				suite.Require().NoError(
  1203  					suite.app.BankKeeper.MintCoins(
  1204  						suite.ctx,
  1205  						multiPermAcc.Name,
  1206  						sdk.NewCoins(testCase.coinsToTry),
  1207  					),
  1208  				)
  1209  			} else {
  1210  				suite.Require().Error(
  1211  					suite.app.BankKeeper.MintCoins(
  1212  						suite.ctx,
  1213  						multiPermAcc.Name,
  1214  						sdk.NewCoins(testCase.coinsToTry),
  1215  					),
  1216  				)
  1217  			}
  1218  		}
  1219  	}
  1220  }
  1221  
  1222  func TestKeeperTestSuite(t *testing.T) {
  1223  	suite.Run(t, new(IntegrationTestSuite))
  1224  }