github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/x/token/token_test.go (about)

     1  package token
     2  
     3  import (
     4  	"fmt"
     5  	"math/big"
     6  	"strconv"
     7  	"strings"
     8  	"testing"
     9  
    10  	app "github.com/fibonacci-chain/fbc/app/types"
    11  
    12  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/codec"
    13  	sdk "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types"
    14  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/auth"
    15  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/bank"
    16  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/mock"
    17  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/supply"
    18  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/supply/exported"
    19  	abci "github.com/fibonacci-chain/fbc/libs/tendermint/abci/types"
    20  	"github.com/fibonacci-chain/fbc/libs/tendermint/crypto"
    21  	"github.com/fibonacci-chain/fbc/libs/tendermint/crypto/secp256k1"
    22  	"github.com/fibonacci-chain/fbc/x/common"
    23  	"github.com/fibonacci-chain/fbc/x/common/version"
    24  	"github.com/fibonacci-chain/fbc/x/token/types"
    25  	"github.com/stretchr/testify/require"
    26  )
    27  
    28  var mockBlockHeight int64 = -1
    29  
    30  type MockDexApp struct {
    31  	*mock.App
    32  
    33  	keyToken  *sdk.KVStoreKey
    34  	keyLock   *sdk.KVStoreKey
    35  	keySupply *sdk.KVStoreKey
    36  
    37  	bankKeeper   bank.Keeper
    38  	tokenKeeper  Keeper
    39  	supplyKeeper supply.Keeper
    40  }
    41  
    42  func registerCodec(cdc *codec.Codec) {
    43  	RegisterCodec(cdc)
    44  	supply.RegisterCodec(cdc)
    45  }
    46  
    47  func getEndBlocker(keeper Keeper) sdk.EndBlocker {
    48  	return func(ctx sdk.Context, req abci.RequestEndBlock) abci.ResponseEndBlock {
    49  		return abci.ResponseEndBlock{}
    50  	}
    51  }
    52  
    53  // initialize the mock application for this module
    54  func getMockDexApp(t *testing.T, numGenAccs int) (mockDexApp *MockDexApp, keeper Keeper, addrs []sdk.AccAddress) {
    55  
    56  	mapp := mock.NewApp()
    57  	//mapp.Cdc = makeCodec()
    58  	registerCodec(mapp.Cdc.GetCdc())
    59  	app.RegisterCodec(mapp.Cdc.GetCdc())
    60  
    61  	mockDexApp = &MockDexApp{
    62  		App: mapp,
    63  
    64  		keyToken:  sdk.NewKVStoreKey("token"),
    65  		keyLock:   sdk.NewKVStoreKey("lock"),
    66  		keySupply: sdk.NewKVStoreKey(supply.StoreKey),
    67  	}
    68  
    69  	feeCollectorAcc := supply.NewEmptyModuleAccount(auth.FeeCollectorName)
    70  	blacklistedAddrs := make(map[string]bool)
    71  	blacklistedAddrs[feeCollectorAcc.Address.String()] = true
    72  
    73  	mockDexApp.bankKeeper = bank.NewBaseKeeper(
    74  		mockDexApp.AccountKeeper,
    75  		mockDexApp.ParamsKeeper.Subspace(bank.DefaultParamspace),
    76  		blacklistedAddrs,
    77  	)
    78  
    79  	maccPerms := map[string][]string{
    80  		auth.FeeCollectorName: nil,
    81  		types.ModuleName:      {supply.Minter, supply.Burner},
    82  	}
    83  	mockDexApp.supplyKeeper = supply.NewKeeper(mockDexApp.Cdc.GetCdc(), mockDexApp.keySupply, mockDexApp.AccountKeeper, bank.NewBankKeeperAdapter(mockDexApp.bankKeeper), maccPerms)
    84  	mockDexApp.tokenKeeper = NewKeeper(
    85  		mockDexApp.bankKeeper,
    86  		mockDexApp.ParamsKeeper.Subspace(DefaultParamspace),
    87  		auth.FeeCollectorName,
    88  		mockDexApp.supplyKeeper,
    89  		mockDexApp.keyToken,
    90  		mockDexApp.keyLock,
    91  		mockDexApp.Cdc.GetCdc(),
    92  		true, mapp.AccountKeeper)
    93  
    94  	handler := NewTokenHandler(mockDexApp.tokenKeeper, version.CurrentProtocolVersion)
    95  
    96  	mockDexApp.Router().AddRoute(RouterKey, handler)
    97  	mockDexApp.QueryRouter().AddRoute(QuerierRoute, NewQuerier(mockDexApp.tokenKeeper))
    98  
    99  	mockDexApp.SetEndBlocker(getEndBlocker(mockDexApp.tokenKeeper))
   100  	mockDexApp.SetInitChainer(getInitChainer(mockDexApp.App, mockDexApp.bankKeeper, mockDexApp.supplyKeeper, []exported.ModuleAccountI{feeCollectorAcc}))
   101  
   102  	intQuantity := int64(100000)
   103  	valTokens := sdk.NewDec(intQuantity)
   104  	coins := sdk.SysCoins{
   105  		sdk.NewDecCoinFromDec(common.NativeToken, valTokens),
   106  		sdk.NewDecCoinFromDec(common.TestToken, valTokens),
   107  	}
   108  
   109  	genAccs, addrs, _, _ := mock.CreateGenAccounts(numGenAccs, coins)
   110  
   111  	// todo: checkTx in mock app
   112  	mockDexApp.SetAnteHandler(nil)
   113  
   114  	app := mockDexApp
   115  	require.NoError(t, app.CompleteSetup(
   116  		app.keyToken,
   117  		app.keyLock,
   118  		app.keySupply,
   119  	))
   120  	// TODO: set genesis
   121  	app.BaseApp.NewContext(true, abci.Header{})
   122  	mock.SetGenesis(mockDexApp.App, genAccs)
   123  
   124  	for i := 0; i < numGenAccs; i++ {
   125  		mock.CheckBalance(t, app.App, addrs[i], coins)
   126  		mockDexApp.TotalCoinsSupply = mockDexApp.TotalCoinsSupply.Add2(coins)
   127  	}
   128  
   129  	return mockDexApp, mockDexApp.tokenKeeper, addrs
   130  }
   131  
   132  // initialize the mock application for this module
   133  func getMockDexAppEx(t *testing.T, numGenAccs int) (mockDexApp *MockDexApp, keeper Keeper, h sdk.Handler) {
   134  
   135  	mapp := mock.NewApp()
   136  	//mapp.Cdc = makeCodec()
   137  	registerCodec(mapp.Cdc.GetCdc())
   138  
   139  	mockDexApp = &MockDexApp{
   140  		App: mapp,
   141  
   142  		keySupply: sdk.NewKVStoreKey(supply.StoreKey),
   143  		keyToken:  sdk.NewKVStoreKey("token"),
   144  		keyLock:   sdk.NewKVStoreKey("lock"),
   145  	}
   146  
   147  	feeCollectorAcc := supply.NewEmptyModuleAccount(auth.FeeCollectorName)
   148  	blacklistedAddrs := make(map[string]bool)
   149  	blacklistedAddrs[feeCollectorAcc.String()] = true
   150  
   151  	mockDexApp.bankKeeper = bank.NewBaseKeeper(
   152  		mockDexApp.AccountKeeper,
   153  		mockDexApp.ParamsKeeper.Subspace(bank.DefaultParamspace),
   154  		blacklistedAddrs,
   155  	)
   156  
   157  	maccPerms := map[string][]string{
   158  		auth.FeeCollectorName: nil,
   159  		types.ModuleName:      nil,
   160  	}
   161  	mockDexApp.supplyKeeper = supply.NewKeeper(
   162  		mockDexApp.Cdc.GetCdc(),
   163  		mockDexApp.keySupply,
   164  		mockDexApp.AccountKeeper,
   165  		bank.NewBankKeeperAdapter(mockDexApp.bankKeeper),
   166  		maccPerms)
   167  
   168  	mockDexApp.tokenKeeper = NewKeeper(
   169  		mockDexApp.bankKeeper,
   170  		mockDexApp.ParamsKeeper.Subspace(DefaultParamspace),
   171  		auth.FeeCollectorName,
   172  		mockDexApp.supplyKeeper,
   173  		mockDexApp.keyToken,
   174  		mockDexApp.keyLock,
   175  		mockDexApp.Cdc.GetCdc(),
   176  		true, mockDexApp.AccountKeeper)
   177  
   178  	// for staking/distr rollback to cosmos-sdk
   179  	//store.NewKVStoreKey(staking.DelegatorPoolKey),
   180  	//store.NewKVStoreKey(staking.RedelegationKeyM),
   181  	//store.NewKVStoreKey(staking.RedelegationActonKey),
   182  	//store.NewKVStoreKey(staking.UnbondingKey),
   183  
   184  	handler := NewTokenHandler(mockDexApp.tokenKeeper, version.CurrentProtocolVersion)
   185  
   186  	mockDexApp.Router().AddRoute(RouterKey, handler)
   187  	mockDexApp.QueryRouter().AddRoute(QuerierRoute, NewQuerier(mockDexApp.tokenKeeper))
   188  
   189  	mockDexApp.SetEndBlocker(getEndBlocker(mockDexApp.tokenKeeper))
   190  	mockDexApp.SetInitChainer(getInitChainer(mockDexApp.App, mockDexApp.bankKeeper, mockDexApp.supplyKeeper, []exported.ModuleAccountI{feeCollectorAcc}))
   191  
   192  	intQuantity := int64(10000000)
   193  	valTokens := sdk.NewDec(intQuantity)
   194  	coins := sdk.SysCoins{
   195  		sdk.NewDecCoinFromDec(common.NativeToken, valTokens),
   196  		sdk.NewDecCoinFromDec(common.TestToken, valTokens),
   197  	}
   198  
   199  	genAccs, _, _, _ := mock.CreateGenAccounts(numGenAccs, coins)
   200  
   201  	// todo: checkTx in mock app
   202  	mockDexApp.SetAnteHandler(nil)
   203  
   204  	app := mockDexApp
   205  	mockDexApp.MountStores(
   206  		app.keyToken,
   207  		app.keyLock,
   208  		app.keySupply,
   209  	)
   210  
   211  	require.NoError(t, mockDexApp.CompleteSetup())
   212  	mock.SetGenesis(mockDexApp.App, genAccs)
   213  	//app.BaseApp.NewContext(true, abci.Header{})
   214  	return mockDexApp, mockDexApp.tokenKeeper, handler
   215  }
   216  
   217  func getInitChainer(mapp *mock.App, bankKeeper bank.Keeper, supplyKeeper supply.Keeper,
   218  	blacklistedAddrs []exported.ModuleAccountI) sdk.InitChainer {
   219  	return func(ctx sdk.Context, req abci.RequestInitChain) abci.ResponseInitChain {
   220  		mapp.InitChainer(ctx, req)
   221  		// set module accounts
   222  		for _, macc := range blacklistedAddrs {
   223  			supplyKeeper.SetModuleAccount(ctx, macc)
   224  		}
   225  		bankKeeper.SetSendEnabled(ctx, true)
   226  		supplyKeeper.SetSupply(ctx, supply.NewSupply(sdk.Coins{}))
   227  		return abci.ResponseInitChain{}
   228  	}
   229  }
   230  
   231  func getTokenSymbol(ctx sdk.Context, keeper Keeper, prefix string) string {
   232  	store := ctx.KVStore(keeper.tokenStoreKey)
   233  	iter := sdk.KVStorePrefixIterator(store, types.TokenKey)
   234  	defer iter.Close()
   235  	for iter.Valid() {
   236  		var token types.Token
   237  		tokenBytes := iter.Value()
   238  		keeper.cdc.MustUnmarshalBinaryBare(tokenBytes, &token)
   239  		if strings.HasPrefix(token.Symbol, prefix) {
   240  			return token.Symbol
   241  		}
   242  		iter.Next()
   243  	}
   244  	return ""
   245  }
   246  
   247  type testAccount struct {
   248  	addrKeys    *mock.AddrKeys
   249  	baseAccount types.DecAccount
   250  }
   251  
   252  func mockApplyBlock(t *testing.T, app *MockDexApp, txs []*auth.StdTx, height int64) sdk.Context {
   253  	mockBlockHeight++
   254  	app.BeginBlock(abci.RequestBeginBlock{Header: abci.Header{Height: height}})
   255  
   256  	ctx := app.BaseApp.NewContext(false, abci.Header{})
   257  	//ctx = ctx.WithTxBytes([]byte("90843555124EBF16EB13262400FB8CF639E6A772F437E37A0A141FE640A0B203"))
   258  	param := types.DefaultParams()
   259  	app.tokenKeeper.SetParams(ctx, param)
   260  	for _, tx := range txs {
   261  		app.Deliver(tx)
   262  	}
   263  	app.EndBlock(abci.RequestEndBlock{})
   264  	app.Commit(abci.RequestCommit{})
   265  	return ctx
   266  }
   267  
   268  func CreateGenAccounts(numAccs int, genCoins sdk.SysCoins) (genAccs []types.DecAccount, atList TestAccounts) {
   269  
   270  	for i := 0; i < numAccs; i++ {
   271  		privKey := secp256k1.GenPrivKey()
   272  		pubKey := privKey.PubKey()
   273  		addr := sdk.AccAddress(pubKey.Address())
   274  
   275  		ak := mock.NewAddrKeys(addr, pubKey, privKey)
   276  		testAccount := &testAccount{&ak,
   277  			types.DecAccount{
   278  				Address: addr,
   279  				Coins:   genCoins},
   280  		}
   281  		atList = append(atList, testAccount)
   282  
   283  		genAccs = append(genAccs, testAccount.baseAccount)
   284  	}
   285  	return
   286  }
   287  
   288  type TestAccounts []*testAccount
   289  
   290  // GenTx generates a signed mock transaction.
   291  func GenTx(msgs []sdk.Msg, accnums []uint64, seq []uint64, priv ...crypto.PrivKey) *auth.StdTx {
   292  	// Make the transaction free
   293  	fee := auth.StdFee{
   294  		// just for test - 0.01fibo as fixed fee
   295  		Amount: sdk.NewDecCoinsFromDec(sdk.DefaultBondDenom, sdk.MustNewDecFromStr("0.01")),
   296  		Gas:    200000,
   297  	}
   298  
   299  	sigs := make([]auth.StdSignature, len(priv))
   300  	memo := "testmemotestmemo"
   301  
   302  	for i, p := range priv {
   303  		sig, err := p.Sign(auth.StdSignBytes("", accnums[i], seq[i], fee, msgs, memo))
   304  		if err != nil {
   305  			panic(err)
   306  		}
   307  
   308  		sigs[i] = auth.StdSignature{
   309  			PubKey:    p.PubKey(),
   310  			Signature: sig,
   311  		}
   312  	}
   313  
   314  	return auth.NewStdTx(msgs, fee, sigs, memo)
   315  }
   316  
   317  func createTokenMsg(t *testing.T, app *MockDexApp, ctx sdk.Context, account *testAccount, tokenMsg sdk.Msg) *auth.StdTx {
   318  	accs := app.AccountKeeper.GetAccount(ctx, account.baseAccount.Address)
   319  	accNum := accs.GetAccountNumber()
   320  	seqNum := accs.GetSequence()
   321  
   322  	// todo:
   323  	//tokenIssueMsg.Sender = account.addrKeys.Address
   324  	tx := GenTx([]sdk.Msg{tokenMsg}, []uint64{accNum}, []uint64{seqNum}, account.addrKeys.PrivKey)
   325  	app.Check(tx)
   326  	//if !res.IsOK() {
   327  	//	panic("something wrong in checking transaction")
   328  	//}
   329  	return tx
   330  }
   331  
   332  type MsgFaked struct {
   333  	FakeID int
   334  }
   335  
   336  func (msg MsgFaked) Route() string { return "token" }
   337  
   338  func (msg MsgFaked) Type() string { return "issue" }
   339  
   340  func (msg MsgFaked) ValidateBasic() sdk.Error {
   341  	return nil
   342  }
   343  
   344  func (msg MsgFaked) GetSignBytes() []byte {
   345  	return sdk.MustSortJSON([]byte("1"))
   346  }
   347  
   348  func (msg MsgFaked) GetSigners() []sdk.AccAddress {
   349  	return []sdk.AccAddress{}
   350  }
   351  
   352  func newFakeMsg() MsgFaked {
   353  	return MsgFaked{
   354  		FakeID: 0,
   355  	}
   356  }
   357  
   358  func TestMsgTokenChown(t *testing.T) {
   359  	//change token owner
   360  	intQuantity := int64(30000)
   361  	// to
   362  	toPriKey := secp256k1.GenPrivKey()
   363  	toPubKey := toPriKey.PubKey()
   364  	toAddr := sdk.AccAddress(toPubKey.Address())
   365  	//init accounts
   366  	genAccs, testAccounts := CreateGenAccounts(1,
   367  		sdk.SysCoins{
   368  			sdk.NewDecCoinFromDec(common.NativeToken, sdk.NewDec(intQuantity)),
   369  		},
   370  	)
   371  
   372  	fromAddr := testAccounts[0].addrKeys.Address
   373  	//gen app and keepper
   374  	app, keeper, handler := getMockDexAppEx(t, 0)
   375  	mock.SetGenesis(app.App, types.DecAccountArrToBaseAccountArr(genAccs))
   376  
   377  	//build context
   378  	ctx := app.BaseApp.NewContext(true, abci.Header{})
   379  	ctx.SetTxBytes([]byte("90843555124EBF16EB13262400FB8CF639E6A772F437E37A0A141FE640A0B203"))
   380  	var TokenChown []*auth.StdTx
   381  	var TokenIssue []*auth.StdTx
   382  
   383  	//test fake message
   384  	if handler != nil {
   385  		handler(ctx, newFakeMsg())
   386  	}
   387  
   388  	//issue token to FromAddress
   389  	tokenIssueMsg := types.NewMsgTokenIssue(common.NativeToken, common.NativeToken, common.NativeToken, "okcoin", "1000", testAccounts[0].baseAccount.Address, true)
   390  	TokenIssue = append(TokenIssue, createTokenMsg(t, app, ctx, testAccounts[0], tokenIssueMsg))
   391  
   392  	//test error supply coin issue(TotalSupply > (9*1e10))
   393  	MsgErrorSupply := types.NewMsgTokenIssue("okc", "okc", "okc", "okccc", strconv.FormatInt(int64(10*1e10), 10), testAccounts[0].baseAccount.Address, true)
   394  	TokenIssue = append(TokenIssue, createTokenMsg(t, app, ctx, testAccounts[0], MsgErrorSupply))
   395  
   396  	//test error tokenDesc (length > 256)
   397  	MsgErrorName := types.NewMsgTokenIssue(`ok-bok-bok-bok-bok-bok-bok-bok-bok-bok-bok-bok-b
   398  ok-bok-bok-bok-bok-bok-bok-bok-bok-bok-bok-bok-bok-bok-bok-bok-bok-bok-bok-b
   399  ok-bok-bok-bok-bok-bok-bok-bok-bok-bok-bok-bok-bok-bok-bok-bok-bok-bok-bok-bok-b
   400  ok-bok-bok-bok-bok-bok-bok-bok-bok-bok-bok-bok-bok-bok-bok-bok-bok-bok-bok-bok-bok-bok-bok-bok-bok-bok-b`,
   401  		common.NativeToken, common.NativeToken, "okcoin", "2100", testAccounts[0].baseAccount.Address, true)
   402  	TokenIssue = append(TokenIssue, createTokenMsg(t, app, ctx, testAccounts[0], MsgErrorName))
   403  
   404  	ctx = mockApplyBlock(t, app, TokenIssue, 3)
   405  	_, err := handleMsgTokenIssue(ctx, keeper, MsgErrorSupply, nil)
   406  	require.NotNil(t, err)
   407  	//require.NotNil(t, handleMsgTokenIssue(ctx, keeper, MsgErrorName, nil))
   408  
   409  	//test if zzb is not exist
   410  	invalidmsg := types.NewMsgTransferOwnership(fromAddr, toAddr, "zzb")
   411  	TokenChown = append(TokenChown, createTokenMsg(t, app, ctx, testAccounts[0], invalidmsg))
   412  
   413  	//test addTokenSuffix->ValidSymbol
   414  	addTokenSuffix(ctx, keeper, "notexist")
   415  
   416  	//normal test
   417  	symbName := "okb-b85" //addTokenSuffix(ctx,keeper,common.NativeToken)
   418  	//change owner from F to T
   419  	tokenChownMsg := types.NewMsgTransferOwnership(fromAddr, toAddr, symbName)
   420  	TokenChown = append(TokenChown, createTokenMsg(t, app, ctx, testAccounts[0], tokenChownMsg))
   421  
   422  	ctx = mockApplyBlock(t, app, TokenChown, 4)
   423  }
   424  
   425  func TestHandleMsgTokenIssueFails(t *testing.T) {
   426  	var TokenIssue []*auth.StdTx
   427  	genAccs, testAccounts := CreateGenAccounts(1,
   428  		sdk.SysCoins{
   429  			sdk.NewDecCoinFromDec(common.NativeToken, sdk.NewDec(30000)),
   430  		},
   431  	)
   432  	app, keeper, _ := getMockDexAppEx(t, 0)
   433  	mock.SetGenesis(app.App, types.DecAccountArrToBaseAccountArr(genAccs))
   434  
   435  	//build context
   436  	ctx := mockApplyBlock(t, app, TokenIssue, 3)
   437  	cases := []struct {
   438  		info     string
   439  		msg      types.MsgTokenIssue
   440  		expected string
   441  		panic    bool
   442  	}{
   443  		{
   444  			"Error Get Decimal From Decimal String",
   445  			types.NewMsgTokenIssue("", common.NativeToken, common.NativeToken, "okcoin", "", testAccounts[0].baseAccount.Address, true),
   446  			"create a decimal from an input decimal string failed: create a decimal from an input decimal string failed: decimal string cannot be empty",
   447  			false,
   448  		},
   449  		{
   450  			"Error Invalid Coins",
   451  			types.NewMsgTokenIssue("", common.NativeToken, "a.b", "okcoin", "9999", testAccounts[0].baseAccount.Address, true),
   452  			"invalid coins: invalid coins: a.b",
   453  			false,
   454  		},
   455  		{
   456  			"Error Mint Coins Failed",
   457  			types.NewMsgTokenIssue("", common.NativeToken, common.NativeToken, "okcoin", "9999", testAccounts[0].baseAccount.Address, true),
   458  			"not have permission to mint should panic",
   459  			true,
   460  		},
   461  	}
   462  	for _, tc := range cases {
   463  
   464  		if tc.panic {
   465  			require.Panics(t, func() { handleMsgTokenIssue(ctx, keeper, tc.msg, nil) })
   466  		} else {
   467  			_, err := handleMsgTokenIssue(ctx, keeper, tc.msg, nil)
   468  			require.Equal(t, err.Error(), tc.expected)
   469  		}
   470  	}
   471  }
   472  
   473  func TestUpdateUserTokenRelationship(t *testing.T) {
   474  	intQuantity := int64(30000)
   475  	genAccs, testAccounts := CreateGenAccounts(2,
   476  		sdk.SysCoins{
   477  			sdk.NewDecCoinFromDec(common.NativeToken, sdk.NewDec(intQuantity)),
   478  		})
   479  
   480  	app, keeper, _ := getMockDexApp(t, 0)
   481  	mock.SetGenesis(app.App, types.DecAccountArrToBaseAccountArr(genAccs))
   482  
   483  	ctx := app.BaseApp.NewContext(true, abci.Header{})
   484  	ctx.SetTxBytes([]byte("90843555124EBF16EB13262400FB8CF639E6A772F437E37A0A141FE640A0B203"))
   485  
   486  	var tokenIssue []*auth.StdTx
   487  
   488  	totalSupplyStr := "500"
   489  	tokenIssueMsg := types.NewMsgTokenIssue("bnb", "", "bnb", "binance coin", totalSupplyStr, testAccounts[0].baseAccount.Address, true)
   490  	tokenIssue = append(tokenIssue, createTokenMsg(t, app, ctx, testAccounts[0], tokenIssueMsg))
   491  
   492  	ctx = mockApplyBlock(t, app, tokenIssue, 3)
   493  
   494  	tokens := keeper.GetUserTokensInfo(ctx, testAccounts[0].baseAccount.Address)
   495  	require.EqualValues(t, 1, len(tokens))
   496  
   497  	tokenName := getTokenSymbol(ctx, keeper, "bnb")
   498  	// ===============
   499  
   500  	var TokenChown []*auth.StdTx
   501  
   502  	//test if zzb is not exist
   503  	chownMsg := types.NewMsgTransferOwnership(testAccounts[0].baseAccount.Address, testAccounts[1].baseAccount.Address, tokenName)
   504  	TokenChown = append(TokenChown, createTokenMsg(t, app, ctx, testAccounts[0], chownMsg))
   505  
   506  	ctx = mockApplyBlock(t, app, TokenChown, 4)
   507  
   508  	tokens = keeper.GetUserTokensInfo(ctx, testAccounts[0].baseAccount.Address)
   509  	require.EqualValues(t, 1, len(tokens))
   510  
   511  	confirmMsg := types.NewMsgConfirmOwnership(testAccounts[1].baseAccount.Address, tokenName)
   512  	ctx = mockApplyBlock(t, app, []*auth.StdTx{createTokenMsg(t, app, ctx, testAccounts[1], confirmMsg)}, 5)
   513  
   514  	tokens = keeper.GetUserTokensInfo(ctx, testAccounts[0].baseAccount.Address)
   515  	require.EqualValues(t, 0, len(tokens))
   516  
   517  	tokens = keeper.GetUserTokensInfo(ctx, testAccounts[1].baseAccount.Address)
   518  	require.EqualValues(t, 1, len(tokens))
   519  }
   520  
   521  func TestCreateTokenIssue(t *testing.T) {
   522  	intQuantity := int64(3000)
   523  	genAccs, testAccounts := CreateGenAccounts(1,
   524  		sdk.SysCoins{
   525  			sdk.NewDecCoinFromDec(common.NativeToken, sdk.NewDec(intQuantity)),
   526  		})
   527  
   528  	app, keeper, _ := getMockDexApp(t, 0)
   529  	mock.SetGenesis(app.App, types.DecAccountArrToBaseAccountArr(genAccs))
   530  
   531  	ctx := app.BaseApp.NewContext(true, abci.Header{})
   532  	ctx.SetTxBytes([]byte("90843555124EBF16EB13262400FB8CF639E6A772F437E37A0A141FE640A0B203"))
   533  
   534  	var tokenIssue []*auth.StdTx
   535  
   536  	totalSupply := int64(500)
   537  	totalSupplyStr := "500"
   538  	tokenIssueMsg := types.NewMsgTokenIssue("bnb", "", "bnb", "binance coin", totalSupplyStr, testAccounts[0].baseAccount.Address, true)
   539  	tokenIssue = append(tokenIssue, createTokenMsg(t, app, ctx, testAccounts[0], tokenIssueMsg))
   540  
   541  	// not valid symbol
   542  	//tokenIssueMsg = types.NewMsgTokenIssue("bnba123451fadfasdf", "bnba123451fadfasdf", "bnba123451fadfasdf", totalSupply, testAccounts[0].baseAccount.Address, true)
   543  	//tokenIssue = append(tokenIssue, createTokenMsg(t, app, ctx, testAccounts[0], tokenIssueMsg))
   544  
   545  	// Total exceeds the upper limit
   546  	tokenIssueMsg = types.NewMsgTokenIssue("btc", "btc", "btc", "bitcoin", strconv.FormatInt(types.TotalSupplyUpperbound+1, 10), testAccounts[0].baseAccount.Address, true)
   547  	tokenIssue = append(tokenIssue, createTokenMsg(t, app, ctx, testAccounts[0], tokenIssueMsg))
   548  
   549  	// not enough okbs
   550  	tokenIssueMsg = types.NewMsgTokenIssue("xmr", "xmr", "xmr", "Monero", totalSupplyStr, testAccounts[0].baseAccount.Address, true)
   551  	tokenIssue = append(tokenIssue, createTokenMsg(t, app, ctx, testAccounts[0], tokenIssueMsg))
   552  
   553  	ctx = mockApplyBlock(t, app, tokenIssue, 3)
   554  
   555  	tokenName := getTokenSymbol(ctx, keeper, "bnb")
   556  	//feeIssue, err := sdk.NewDecFromStr(DefaultFeeIssue)
   557  	//require.EqualValues(t, nil, err)
   558  	feeIssue := keeper.GetParams(ctx).FeeIssue.Amount
   559  	coins := sdk.SysCoins{
   560  		sdk.NewDecCoinFromDec(tokenName, sdk.NewDec(totalSupply)),
   561  		sdk.NewDecCoinFromDec(common.NativeToken, sdk.NewDec(intQuantity).Sub(feeIssue)),
   562  	}
   563  	require.EqualValues(t, coins, app.AccountKeeper.GetAccount(ctx, testAccounts[0].addrKeys.Address).GetCoins())
   564  	tokenStoreKeyNum, lockStoreKeyNum := keeper.getNumKeys(ctx)
   565  	require.Equal(t, int64(3), tokenStoreKeyNum)
   566  	require.Equal(t, int64(0), lockStoreKeyNum)
   567  
   568  	tokenInfo := keeper.GetTokenInfo(ctx, tokenName)
   569  	require.EqualValues(t, sdk.MustNewDecFromStr("500"), tokenInfo.OriginalTotalSupply)
   570  }
   571  
   572  func TestCreateTokenBurn(t *testing.T) {
   573  	intQuantity := int64(2511)
   574  
   575  	genAccs, testAccounts := CreateGenAccounts(1,
   576  		sdk.SysCoins{
   577  			sdk.NewDecCoinFromDec(common.NativeToken, sdk.NewDec(intQuantity)),
   578  		})
   579  
   580  	_, testAccounts2 := CreateGenAccounts(1,
   581  		sdk.SysCoins{
   582  			sdk.NewDecCoinFromDec(common.NativeToken, sdk.NewDec(intQuantity)),
   583  		})
   584  
   585  	app, keeper, _ := getMockDexApp(t, 0)
   586  	mock.SetGenesis(app.App, types.DecAccountArrToBaseAccountArr(genAccs))
   587  
   588  	ctx := app.NewContext(true, abci.Header{})
   589  	var tokenMsgs []*auth.StdTx
   590  
   591  	tokenIssueMsg := types.NewMsgTokenIssue("btc", "btc", "btc", "bitcoin", "1000", testAccounts[0].baseAccount.Address, true)
   592  	tokenMsgs = append(tokenMsgs, createTokenMsg(t, app, ctx, testAccounts[0], tokenIssueMsg))
   593  	ctx = mockApplyBlock(t, app, tokenMsgs, 3)
   594  
   595  	tokenMsgs = tokenMsgs[:0]
   596  
   597  	burnNum := "100"
   598  	//mockToken(app.tokenKeeper, ctx, testAccounts[0].baseAccount.Address, intQuantity)
   599  
   600  	_, err := sdk.ParseDecCoin("-10000btc")
   601  	require.Error(t, err)
   602  
   603  	decCoin, err := sdk.ParseDecCoin("10000btc")
   604  	require.Nil(t, err)
   605  	// total exceeds the upper limit
   606  	tokenBurnMsg := types.NewMsgTokenBurn(decCoin, testAccounts[0].baseAccount.Address)
   607  	tokenMsgs = append(tokenMsgs, createTokenMsg(t, app, ctx, testAccounts[0], tokenBurnMsg))
   608  	//mockApplyBlock(t, app, tokenMsgs)
   609  
   610  	// not the token's owner
   611  	tokenBurnMsg = types.NewMsgTokenBurn(decCoin, testAccounts2[0].baseAccount.Address)
   612  	tokenMsgs = append(tokenMsgs, createTokenMsg(t, app, ctx, testAccounts[0], tokenBurnMsg))
   613  
   614  	tokenSymbol := getTokenSymbol(ctx, keeper, "btc")
   615  
   616  	decCoin, err = sdk.ParseDecCoin(burnNum + tokenSymbol)
   617  	require.Nil(t, err)
   618  	// normal case
   619  	tokenBurnMsg = types.NewMsgTokenBurn(decCoin, testAccounts[0].baseAccount.Address)
   620  	tokenMsgs = append(tokenMsgs, createTokenMsg(t, app, ctx, testAccounts[0], tokenBurnMsg))
   621  
   622  	decCoin, err = sdk.ParseDecCoin(burnNum + "btc")
   623  	require.Nil(t, err)
   624  	// not enough fees
   625  	tokenBurnMsg = types.NewMsgTokenBurn(decCoin, testAccounts[0].baseAccount.Address)
   626  	tokenMsgs = append(tokenMsgs, createTokenMsg(t, app, ctx, testAccounts[0], tokenBurnMsg))
   627  
   628  	ctx = mockApplyBlock(t, app, tokenMsgs, 4)
   629  
   630  	//fee, err := sdk.NewDecFromStr("0.0125")
   631  	fee, err := sdk.NewDecFromStr("0.0")
   632  	require.Nil(t, err)
   633  	validTxNum := sdk.NewDec(2)
   634  	coins := sdk.SysCoins{
   635  		sdk.NewDecCoinFromDec(tokenSymbol, sdk.NewDec(900)),
   636  		sdk.NewDecCoinFromDec(common.NativeToken, sdk.NewDec(1).Add(fee.Mul(validTxNum))),
   637  	}
   638  
   639  	require.EqualValues(t, coins, app.AccountKeeper.GetAccount(ctx, testAccounts[0].addrKeys.Address).GetCoins())
   640  }
   641  
   642  func TestCreateTokenMint(t *testing.T) {
   643  	intQuantity := int64(5011)
   644  
   645  	genAccs, testAccounts := CreateGenAccounts(1,
   646  		sdk.SysCoins{
   647  			sdk.NewDecCoinFromDec(common.NativeToken, sdk.NewDec(intQuantity)),
   648  		})
   649  
   650  	_, testAccounts2 := CreateGenAccounts(1,
   651  		sdk.SysCoins{
   652  			sdk.NewDecCoinFromDec(common.NativeToken, sdk.NewDec(intQuantity)),
   653  		})
   654  
   655  	app, keeper, _ := getMockDexApp(t, 0)
   656  	mock.SetGenesis(app.App, types.DecAccountArrToBaseAccountArr(genAccs))
   657  
   658  	ctx := app.NewContext(true, abci.Header{})
   659  	var tokenMsgs []*auth.StdTx
   660  
   661  	tokenIssueMsg := types.NewMsgTokenIssue("btc", "btc", "btc", "bitcoin", "1000", testAccounts[0].baseAccount.Address, true)
   662  	tokenMsgs = append(tokenMsgs, createTokenMsg(t, app, ctx, testAccounts[0], tokenIssueMsg))
   663  	ctx = mockApplyBlock(t, app, tokenMsgs, 3)
   664  	tokenMsgs = tokenMsgs[:0]
   665  
   666  	tokenIssueMsg = types.NewMsgTokenIssue("xmr", "xmr", "xmr", "monero", "1000", testAccounts[0].baseAccount.Address, false)
   667  	tokenMsgs = append(tokenMsgs, createTokenMsg(t, app, ctx, testAccounts[0], tokenIssueMsg))
   668  	ctx = mockApplyBlock(t, app, tokenMsgs, 4)
   669  
   670  	var mintNum int64 = 1000
   671  	// normal case
   672  	btcTokenSymbol := getTokenSymbol(ctx, keeper, "btc")
   673  	decCoin := sdk.NewDecCoinFromDec(btcTokenSymbol, sdk.NewDec(mintNum))
   674  	tokenMintMsg := types.NewMsgTokenMint(decCoin, testAccounts[0].baseAccount.Address)
   675  
   676  	tokenMsgs = append(tokenMsgs, createTokenMsg(t, app, ctx, testAccounts[0], tokenMintMsg))
   677  
   678  	// Total exceeds the upper limit
   679  	decCoin.Amount = sdk.NewDec(types.TotalSupplyUpperbound)
   680  	tokenMintMsg = types.NewMsgTokenMint(decCoin, testAccounts[0].baseAccount.Address)
   681  	tokenMsgs = append(tokenMsgs, createTokenMsg(t, app, ctx, testAccounts[0], tokenMintMsg))
   682  
   683  	// not the token's owner
   684  	decCoin.Amount = sdk.NewDec(mintNum)
   685  	tokenMintMsg = types.NewMsgTokenMint(decCoin, testAccounts2[0].baseAccount.Address)
   686  	tokenMsgs = append(tokenMsgs, createTokenMsg(t, app, ctx, testAccounts[0], tokenMintMsg))
   687  
   688  	// token not mintable
   689  	xmrTokenSymbol := getTokenSymbol(ctx, keeper, "xmr")
   690  	decCoin.Denom = xmrTokenSymbol
   691  	decCoin.Amount = sdk.NewDec(mintNum)
   692  	tokenMintMsg = types.NewMsgTokenMint(decCoin, testAccounts[0].baseAccount.Address)
   693  	tokenMsgs = append(tokenMsgs, createTokenMsg(t, app, ctx, testAccounts[0], tokenMintMsg))
   694  
   695  	// not enough fees
   696  	decCoin.Denom = btcTokenSymbol
   697  	decCoin.Amount = sdk.NewDec(mintNum)
   698  	tokenMintMsg = types.NewMsgTokenMint(decCoin, testAccounts[0].baseAccount.Address)
   699  	tokenMsgs = append(tokenMsgs, createTokenMsg(t, app, ctx, testAccounts[0], tokenMintMsg))
   700  
   701  	ctx = mockApplyBlock(t, app, tokenMsgs, 5)
   702  
   703  	//validTxNum := sdk.NewInt(2)
   704  	coins := sdk.MustParseCoins(btcTokenSymbol, "2000")
   705  	//coins = append(coins, sdk.MustParseCoins(common.NativeToken, "1.0375")...)
   706  	coins = append(coins, sdk.MustParseCoins(common.NativeToken, "1.0")...)
   707  	coins = append(coins, sdk.MustParseCoins(xmrTokenSymbol, "1000")...)
   708  
   709  	require.EqualValues(t, coins, app.AccountKeeper.GetAccount(ctx, testAccounts[0].addrKeys.Address).GetCoins())
   710  }
   711  
   712  func TestCreateMsgTokenSend(t *testing.T) {
   713  	intQuantity := int64(100000)
   714  
   715  	genAccs, testAccounts := CreateGenAccounts(2,
   716  		sdk.SysCoins{
   717  			sdk.NewDecCoinFromDec(common.NativeToken, sdk.NewDec(intQuantity)),
   718  		})
   719  
   720  	app, keeper, _ := getMockDexApp(t, 0)
   721  	mock.SetGenesis(app.App, types.DecAccountArrToBaseAccountArr(genAccs))
   722  
   723  	ctx := app.NewContext(true, abci.Header{})
   724  	var tokenMsgs []*auth.StdTx
   725  
   726  	tokenIssueMsg := types.NewMsgTokenIssue("btc", "btc", "btc", "bitcoin", "1000", testAccounts[0].baseAccount.Address, true)
   727  	tokenMsgs = append(tokenMsgs, createTokenMsg(t, app, ctx, testAccounts[0], tokenIssueMsg))
   728  	ctx = mockApplyBlock(t, app, tokenMsgs, 3)
   729  	tokenMsgs = tokenMsgs[:0]
   730  
   731  	tokenName := getTokenSymbol(ctx, keeper, "btc")
   732  	coins := sdk.SysCoins{
   733  		sdk.NewDecCoinFromDec(tokenName, sdk.NewDec(100)),
   734  	}
   735  	tokenSendMsg := types.NewMsgTokenSend(testAccounts[0].baseAccount.Address, testAccounts[1].baseAccount.Address, coins)
   736  	tokenMsgs = append(tokenMsgs, createTokenMsg(t, app, ctx, testAccounts[0], tokenSendMsg))
   737  
   738  	coins = sdk.SysCoins{
   739  		sdk.NewDecCoinFromDec("btc", sdk.NewDec(10000)),
   740  	}
   741  	// not enough coins
   742  	tokenSendMsg = types.NewMsgTokenSend(testAccounts[0].baseAccount.Address, testAccounts[1].baseAccount.Address, coins)
   743  	tokenMsgs = append(tokenMsgs, createTokenMsg(t, app, ctx, testAccounts[0], tokenSendMsg))
   744  
   745  	ctx = mockApplyBlock(t, app, tokenMsgs, 4)
   746  
   747  	accounts := app.AccountKeeper.GetAllAccounts(ctx)
   748  	for _, acc := range accounts {
   749  		if acc.GetAddress().Equals(testAccounts[0].baseAccount.Address) {
   750  			senderCoins := sdk.MustParseCoins(tokenName, "900")
   751  			senderCoins = append(senderCoins, sdk.MustParseCoins(common.NativeToken, "97500")...)
   752  			require.EqualValues(t, senderCoins, acc.GetCoins())
   753  		} else if acc.GetAddress().Equals(testAccounts[1].baseAccount.Address) {
   754  			receiverCoins := sdk.MustParseCoins(tokenName, "100")
   755  			receiverCoins = append(receiverCoins, sdk.MustParseCoins(common.NativeToken, "100000")...)
   756  			require.EqualValues(t, receiverCoins, acc.GetCoins())
   757  		}
   758  	}
   759  
   760  	// len(MsgTokenSend.Amount) > 1
   761  	tokenMsgs = tokenMsgs[:0]
   762  	coins = sdk.SysCoins{
   763  		sdk.NewDecCoinFromDec(tokenName, sdk.NewDec(100)),
   764  		sdk.NewDecCoinFromDec(common.NativeToken, sdk.NewDec(100)),
   765  	}
   766  	tokenSendMsg = types.NewMsgTokenSend(testAccounts[0].baseAccount.Address, testAccounts[1].baseAccount.Address, coins)
   767  	tokenMsgs = append(tokenMsgs, createTokenMsg(t, app, ctx, testAccounts[0], tokenSendMsg))
   768  
   769  	ctx = mockApplyBlock(t, app, tokenMsgs, 5)
   770  
   771  	accounts = app.AccountKeeper.GetAllAccounts(ctx)
   772  	for _, acc := range accounts {
   773  		if acc.GetAddress().Equals(testAccounts[0].baseAccount.Address) {
   774  			senderCoins := sdk.MustParseCoins(tokenName, "800")
   775  			senderCoins = append(senderCoins, sdk.MustParseCoins(common.NativeToken, "97400")...)
   776  			require.EqualValues(t, senderCoins.String(), acc.GetCoins().String())
   777  		} else if acc.GetAddress().Equals(testAccounts[1].baseAccount.Address) {
   778  			receiverCoins := sdk.MustParseCoins(tokenName, "200")
   779  			receiverCoins = append(receiverCoins, sdk.MustParseCoins(common.NativeToken, "100100")...)
   780  			require.EqualValues(t, receiverCoins, acc.GetCoins())
   781  		}
   782  	}
   783  }
   784  
   785  func TestCreateMsgMultiSend(t *testing.T) {
   786  	intQuantity := int64(100000)
   787  
   788  	genAccs, testAccounts := CreateGenAccounts(2,
   789  		sdk.SysCoins{
   790  			sdk.NewDecCoinFromDec(common.NativeToken, sdk.NewDec(intQuantity)),
   791  		})
   792  
   793  	app, keeper, _ := getMockDexApp(t, 0)
   794  	mock.SetGenesis(app.App, types.DecAccountArrToBaseAccountArr(genAccs))
   795  	// set anteHandler for mock app
   796  	app.PushAnteHandler(auth.NewAnteHandler(
   797  		app.AccountKeeper,
   798  		app.supplyKeeper,
   799  		auth.DefaultSigVerificationGasConsumer,
   800  	))
   801  
   802  	ctx := app.NewContext(true, abci.Header{})
   803  	var tokenMsgs []*auth.StdTx
   804  
   805  	tokenIssueMsg := types.NewMsgTokenIssue("btc", "btc", "btc", "bitcoin", "1000", testAccounts[0].baseAccount.Address, true)
   806  	tokenMsgs = append(tokenMsgs, createTokenMsg(t, app, ctx, testAccounts[0], tokenIssueMsg))
   807  	ctx = mockApplyBlock(t, app, tokenMsgs, 3)
   808  
   809  	tokenMsgs = tokenMsgs[:0]
   810  	btcSymbol := getTokenSymbol(ctx, keeper, "btc")
   811  	multiSendStr := `[{"to":"` + testAccounts[1].baseAccount.Address.String() + `","amount":"1` + common.NativeToken + `,2` + btcSymbol + `"}]`
   812  	transfers, err := types.StrToTransfers(multiSendStr)
   813  	require.NoError(t, err)
   814  	multiSend := types.NewMsgMultiSend(testAccounts[0].baseAccount.Address, transfers)
   815  	tokenMsgs = append(tokenMsgs, createTokenMsg(t, app, ctx, testAccounts[0], multiSend))
   816  	ctx = mockApplyBlock(t, app, tokenMsgs, 4)
   817  
   818  	// insufficient coins for multi-send
   819  	multiSendStr = `[{"to":"` + testAccounts[1].baseAccount.Address.String() + `","amount":"1` + common.NativeToken + `,2000` + btcSymbol + `"}]`
   820  	transfers, err = types.StrToTransfers(multiSendStr)
   821  	require.NoError(t, err)
   822  	multiSend = types.NewMsgMultiSend(testAccounts[0].baseAccount.Address, transfers)
   823  	tokenMsgs = append(tokenMsgs, createTokenMsg(t, app, ctx, testAccounts[0], multiSend))
   824  	ctx = mockApplyBlock(t, app, tokenMsgs, 5)
   825  
   826  	accounts := app.AccountKeeper.GetAllAccounts(ctx)
   827  	for _, acc := range accounts {
   828  		if acc.GetAddress().Equals(testAccounts[0].baseAccount.Address) {
   829  			senderCoins := sdk.MustParseCoins(btcSymbol, "998")
   830  			senderCoins = append(senderCoins, sdk.MustParseCoins(common.NativeToken, "97498.97000000")...)
   831  			require.EqualValues(t, senderCoins, acc.GetCoins())
   832  		} else if acc.GetAddress().Equals(testAccounts[1].baseAccount.Address) {
   833  			receiverCoins := sdk.MustParseCoins(btcSymbol, "2")
   834  			receiverCoins = append(receiverCoins, sdk.MustParseCoins(common.NativeToken, "100001")...)
   835  			require.EqualValues(t, receiverCoins, acc.GetCoins())
   836  		}
   837  	}
   838  }
   839  
   840  func TestCreateMsgTokenModify(t *testing.T) {
   841  	intQuantity := int64(100000)
   842  
   843  	genAccs, testAccounts := CreateGenAccounts(2,
   844  		sdk.SysCoins{
   845  			sdk.NewDecCoinFromDec(common.NativeToken, sdk.NewDec(intQuantity)),
   846  		})
   847  
   848  	app, keeper, _ := getMockDexApp(t, 0)
   849  	mock.SetGenesis(app.App, types.DecAccountArrToBaseAccountArr(genAccs))
   850  
   851  	ctx := app.NewContext(true, abci.Header{})
   852  	var tokenMsgs []*auth.StdTx
   853  
   854  	tokenIssueMsg := types.NewMsgTokenIssue("btc", "btc", "btc", "bitcoin", "1000", testAccounts[0].baseAccount.Address, true)
   855  	tokenMsgs = append(tokenMsgs, createTokenMsg(t, app, ctx, testAccounts[0], tokenIssueMsg))
   856  	ctx = mockApplyBlock(t, app, tokenMsgs, 3)
   857  
   858  	tokenMsgs = tokenMsgs[:0]
   859  	btcTokenSymbol := getTokenSymbol(ctx, keeper, "btc")
   860  
   861  	// normal case
   862  	tokenEditMsg := types.NewMsgTokenModify(btcTokenSymbol, "desc0", "whole name0", true, true, testAccounts[0].baseAccount.Address)
   863  	tokenMsgs = append(tokenMsgs, createTokenMsg(t, app, ctx, testAccounts[0], tokenEditMsg))
   864  	ctx = mockApplyBlock(t, app, tokenMsgs, 4)
   865  	token := keeper.GetTokenInfo(ctx, btcTokenSymbol)
   866  	require.EqualValues(t, "desc0", token.Description)
   867  	require.EqualValues(t, "whole name0", token.WholeName)
   868  
   869  	tokenMsgs = tokenMsgs[:0]
   870  	tokenEditMsg = types.NewMsgTokenModify(btcTokenSymbol, "desc1", "whole name1", false, true, testAccounts[0].baseAccount.Address)
   871  	tokenMsgs = append(tokenMsgs, createTokenMsg(t, app, ctx, testAccounts[0], tokenEditMsg))
   872  	ctx = mockApplyBlock(t, app, tokenMsgs, 5)
   873  	token = keeper.GetTokenInfo(ctx, btcTokenSymbol)
   874  	require.EqualValues(t, "desc0", token.Description)
   875  	require.EqualValues(t, "whole name1", token.WholeName)
   876  
   877  	tokenMsgs = tokenMsgs[:0]
   878  	tokenEditMsg = types.NewMsgTokenModify(btcTokenSymbol, "desc2", "whole name2", true, false, testAccounts[0].baseAccount.Address)
   879  	tokenMsgs = append(tokenMsgs, createTokenMsg(t, app, ctx, testAccounts[0], tokenEditMsg))
   880  	ctx = mockApplyBlock(t, app, tokenMsgs, 6)
   881  	token = keeper.GetTokenInfo(ctx, btcTokenSymbol)
   882  	require.EqualValues(t, "desc2", token.Description)
   883  	require.EqualValues(t, "whole name1", token.WholeName)
   884  
   885  	tokenMsgs = tokenMsgs[:0]
   886  	tokenEditMsg = types.NewMsgTokenModify(btcTokenSymbol, "desc3", "whole name2", false, false, testAccounts[0].baseAccount.Address)
   887  	tokenMsgs = append(tokenMsgs, createTokenMsg(t, app, ctx, testAccounts[0], tokenEditMsg))
   888  	ctx = mockApplyBlock(t, app, tokenMsgs, 7)
   889  	token = keeper.GetTokenInfo(ctx, btcTokenSymbol)
   890  	require.EqualValues(t, "desc2", token.Description)
   891  	require.EqualValues(t, "whole name1", token.WholeName)
   892  
   893  	// error case
   894  	tokenMsgs = tokenMsgs[:0]
   895  	tokenEditMsg = types.NewMsgTokenModify("btcTokenSymbol", "desc4", "whole name4", true, true, testAccounts[0].baseAccount.Address)
   896  	tokenMsgs = append(tokenMsgs, createTokenMsg(t, app, ctx, testAccounts[0], tokenEditMsg))
   897  	ctx = mockApplyBlock(t, app, tokenMsgs, 8)
   898  
   899  	tokenMsgs = tokenMsgs[:0]
   900  	tokenEditMsg = types.NewMsgTokenModify(btcTokenSymbol, "desc5", "whole name5", true, true, testAccounts[1].baseAccount.Address)
   901  	tokenMsgs = append(tokenMsgs, createTokenMsg(t, app, ctx, testAccounts[0], tokenEditMsg))
   902  	ctx = mockApplyBlock(t, app, tokenMsgs, 9)
   903  
   904  	tokenMsgs = tokenMsgs[:0]
   905  	tokenEditMsg = types.NewMsgTokenModify(btcTokenSymbol, "desc6", "whole nasiangrueinvowfoij;oeasifnroeinagoirengodd   me6", true, true, testAccounts[0].baseAccount.Address)
   906  	tokenMsgs = append(tokenMsgs, createTokenMsg(t, app, ctx, testAccounts[0], tokenEditMsg))
   907  	ctx = mockApplyBlock(t, app, tokenMsgs, 10)
   908  
   909  	tokenMsgs = tokenMsgs[:0]
   910  	tokenEditMsg = types.NewMsgTokenModify(btcTokenSymbol, `bnbbbbbbbbbbbnbbbbbbbbbbnbbbbbbbbbbbnbbbbbbbbb1234
   911  bnbbbbbbbbbbbnbbbbbbbbbbnbbbbbbbbbbbnbbbbbbbbb1234
   912  bnbbbbbbbbbbbnbbbbbbbbbbnbbbbbbbbbbbnbbbbbbbbb1234
   913  bnbbbbbbbbbbbnbbbbbbbbbbnbbbbbbbbbbbnbbbbbbbbb1234
   914  bnbbbbbbbbbbbnbbbbbbbbbbnbbbbbbbbbbbnbbbbbbbbb1234
   915  bnbbbbbbbbbbbnbbbbbbbbbbnbbbbbbbbbbbnbbbbbbbbb1234`, "whole name7", true, true, testAccounts[0].baseAccount.Address)
   916  	tokenMsgs = append(tokenMsgs, createTokenMsg(t, app, ctx, testAccounts[0], tokenEditMsg))
   917  	ctx = mockApplyBlock(t, app, tokenMsgs, 11)
   918  
   919  	token = keeper.GetTokenInfo(ctx, btcTokenSymbol)
   920  	require.EqualValues(t, "desc2", token.Description)
   921  	require.EqualValues(t, "whole name1", token.WholeName)
   922  }
   923  
   924  func getMockAppToHandleFee(t *testing.T, initBalance int64, numAcc int) (app *MockDexApp, testAccounts TestAccounts) {
   925  	intQuantity := int64(initBalance)
   926  	genAccs, testAccounts := CreateGenAccounts(numAcc,
   927  		sdk.SysCoins{
   928  			sdk.NewDecCoinFromDec(common.NativeToken, sdk.NewDec(intQuantity)),
   929  		})
   930  
   931  	app, _, _ = getMockDexApp(t, 0)
   932  	mock.SetGenesis(app.App, types.DecAccountArrToBaseAccountArr(genAccs))
   933  	app.PushAnteHandler(auth.NewAnteHandler(
   934  		app.AccountKeeper,
   935  		app.supplyKeeper,
   936  		auth.DefaultSigVerificationGasConsumer,
   937  	))
   938  
   939  	return app, testAccounts
   940  
   941  }
   942  
   943  func TestTxFailedFeeTable(t *testing.T) {
   944  
   945  	app, testAccounts := getMockAppToHandleFee(t, 10, 1)
   946  	ctx := app.BaseApp.NewContext(true, abci.Header{})
   947  
   948  	// to
   949  	toPriKey := secp256k1.GenPrivKey()
   950  	toPubKey := toPriKey.PubKey()
   951  	toAddr := sdk.AccAddress(toPubKey.Address())
   952  
   953  	// failed issue msg : not enough okbs .
   954  	failedIssueMsg := types.NewMsgTokenIssue("xmr", "xmr", "xmr", "Monero", "500", testAccounts[0].baseAccount.Address, true)
   955  	// failed mint msg : no such token
   956  	decCoin := sdk.NewDecCoinFromDec("nob", sdk.NewDec(200))
   957  	failedMintMsg := types.NewMsgTokenMint(decCoin, testAccounts[0].baseAccount.Address)
   958  	// failed burn msg : no such token
   959  	failedBurnMsg := types.NewMsgTokenBurn(decCoin, testAccounts[0].baseAccount.Address)
   960  	// failed edit msg : no such token
   961  	failedEditMsg := types.NewMsgTokenModify("nob", "desc0", "whole name0", true, true, testAccounts[0].baseAccount.Address)
   962  	// failed send msg: no such token
   963  	fialedSendMsg := types.NewMsgTokenSend(testAccounts[0].baseAccount.Address, toAddr, sdk.SysCoins{decCoin})
   964  
   965  	// failed MultiSend msg: no such token
   966  	multiSendStr := `[{"to":"` + toAddr.String() + `","amount":"1` + common.NativeToken + `,2` + "nob" + `"}]`
   967  	transfers, err := types.StrToTransfers(multiSendStr)
   968  	require.Nil(t, err)
   969  	failedMultiSendMsg := types.NewMsgMultiSend(testAccounts[0].baseAccount.Address, transfers)
   970  
   971  	// failed TransferOwnership msg: no such token
   972  	failedChownMsg := types.NewMsgTransferOwnership(testAccounts[0].baseAccount.Address, toAddr, "nob")
   973  
   974  	failTestSets := []struct {
   975  		name    string
   976  		balance string
   977  		msg     *auth.StdTx
   978  	}{
   979  		// 0.01fibo as fixed fee in each stdTx
   980  		{"fail to issue : 0.01", "9.990000000000000000", createTokenMsg(t, app, ctx, testAccounts[0], failedIssueMsg)},
   981  		{"fail to mint  : 0.01", "9.980000000000000000", createTokenMsg(t, app, ctx, testAccounts[0], failedMintMsg)},
   982  		{"fail to burn  : 0.01", "9.970000000000000000", createTokenMsg(t, app, ctx, testAccounts[0], failedBurnMsg)},
   983  		{"fail to modify: 0.01", "9.960000000000000000", createTokenMsg(t, app, ctx, testAccounts[0], failedEditMsg)},
   984  		{"fail to send  : 0.01", "9.950000000000000000", createTokenMsg(t, app, ctx, testAccounts[0], fialedSendMsg)},
   985  		{"fail to multi : 0.01", "9.940000000000000000", createTokenMsg(t, app, ctx, testAccounts[0], failedMultiSendMsg)},
   986  		{"fail to chown : 0.01", "9.930000000000000000", createTokenMsg(t, app, ctx, testAccounts[0], failedChownMsg)},
   987  	}
   988  	for i, tt := range failTestSets {
   989  		t.Run(tt.name, func(t *testing.T) {
   990  			ctx = mockApplyBlock(t, app, []*auth.StdTx{tt.msg}, int64(i+3))
   991  			require.Equal(t, tt.balance, app.AccountKeeper.GetAccount(ctx, testAccounts[0].addrKeys.Address).GetCoins().AmountOf(common.NativeToken).String())
   992  		})
   993  	}
   994  
   995  }
   996  
   997  func TestTxSuccessFeeTable(t *testing.T) {
   998  	app, testAccounts := getMockAppToHandleFee(t, 30000, 1)
   999  	ctx := app.BaseApp.NewContext(true, abci.Header{})
  1000  	// to
  1001  	toPriKey := secp256k1.GenPrivKey()
  1002  	toPubKey := toPriKey.PubKey()
  1003  	toAddr := sdk.AccAddress(toPubKey.Address())
  1004  
  1005  	// successful issue msg
  1006  	successfulIssueMsg := types.NewMsgTokenIssue("xxb", "xxb", "xxb", "xx coin", "500", testAccounts[0].baseAccount.Address, true)
  1007  
  1008  	symbolAfterIssue, ok := addTokenSuffix(ctx, app.tokenKeeper, "xxb")
  1009  	require.True(t, ok)
  1010  
  1011  	decCoin := sdk.NewDecCoinFromDec(symbolAfterIssue, sdk.NewDec(50))
  1012  	successfulMintMsg := types.NewMsgTokenMint(decCoin, testAccounts[0].baseAccount.Address)
  1013  
  1014  	successfulBurnMsg := types.NewMsgTokenBurn(decCoin, testAccounts[0].baseAccount.Address)
  1015  
  1016  	successfulSendMsg := types.NewMsgTokenSend(testAccounts[0].baseAccount.Address, toAddr, sdk.SysCoins{decCoin})
  1017  
  1018  	// multi send
  1019  	multiSendStr := `[{"to":"` + toAddr.String() + `","amount":" 10` + common.NativeToken + `,20` + symbolAfterIssue + `"}]`
  1020  	transfers, err := types.StrToTransfers(multiSendStr)
  1021  	require.Nil(t, err)
  1022  	successfulMultiSendMsg := types.NewMsgMultiSend(testAccounts[0].baseAccount.Address, transfers)
  1023  
  1024  	successfulEditMsg := types.NewMsgTokenModify(symbolAfterIssue, "edit msg", "xxb coin ", true, true, testAccounts[0].baseAccount.Address)
  1025  
  1026  	successfulChownMsg := types.NewMsgTransferOwnership(testAccounts[0].baseAccount.Address, toAddr, symbolAfterIssue)
  1027  
  1028  	successfulTestSets := []struct {
  1029  		description string
  1030  		balance     string
  1031  		msg         sdk.Msg
  1032  		account     *testAccount
  1033  	}{
  1034  		// 0.01fibo as fixed fee in each stdTx
  1035  		{"success to issue : 2500+0.01", "27499.990000000000000000", successfulIssueMsg, testAccounts[0]},
  1036  		{"success to mint  : 10+0.01", "27489.980000000000000000", successfulMintMsg, testAccounts[0]},
  1037  		{"success to burn  : 10+0.01", "27479.970000000000000000", successfulBurnMsg, testAccounts[0]},
  1038  		{"success to send  : 0.01", "27479.960000000000000000", successfulSendMsg, testAccounts[0]},
  1039  		{"success to multi : 10(amount of transfer) +0.01", "27469.950000000000000000", successfulMultiSendMsg, testAccounts[0]},
  1040  		{"success to modify: 0.01", "27469.940000000000000000", successfulEditMsg, testAccounts[0]},
  1041  		{"success to chown : 10+0.01", "27459.930000000000000000", successfulChownMsg, testAccounts[0]},
  1042  	}
  1043  	for i, tt := range successfulTestSets {
  1044  		t.Run(tt.description, func(t *testing.T) {
  1045  			stdTx := createTokenMsg(t, app, ctx, tt.account, tt.msg)
  1046  			ctx = mockApplyBlock(t, app, []*auth.StdTx{stdTx}, int64(i+3))
  1047  			require.Equal(t, tt.balance, app.AccountKeeper.GetAccount(ctx, testAccounts[0].addrKeys.Address).GetCoins().AmountOf(common.NativeToken).String())
  1048  		})
  1049  	}
  1050  }
  1051  
  1052  func TestBlockedAddrSend(t *testing.T) {
  1053  	app, testAccounts := getMockAppToHandleFee(t, 30000, 1)
  1054  	ctx := app.BaseApp.NewContext(true, abci.Header{})
  1055  	// blocked addr
  1056  	blockedAddr := supply.NewModuleAddress(auth.FeeCollectorName)
  1057  	// unblocked addr
  1058  	toPriKey := secp256k1.GenPrivKey()
  1059  	toPubKey := toPriKey.PubKey()
  1060  	validAddr := sdk.AccAddress(toPubKey.Address())
  1061  
  1062  	// build send msg
  1063  	decCoin := sdk.NewDecCoinFromDec(common.NativeToken, sdk.NewDec(50))
  1064  	successfulSendMsg := types.NewMsgTokenSend(testAccounts[0].baseAccount.Address, validAddr, sdk.SysCoins{decCoin})
  1065  	failedSendMsg := types.NewMsgTokenSend(testAccounts[0].baseAccount.Address, blockedAddr, sdk.SysCoins{decCoin})
  1066  
  1067  	// build multi-send msg
  1068  	multiSendStr := `[{"to":"` + validAddr.String() + `","amount":" 100` + common.NativeToken + `"}]`
  1069  	transfers, err := types.StrToTransfers(multiSendStr)
  1070  	require.NoError(t, err)
  1071  	successfulMultiSendMsg := types.NewMsgMultiSend(testAccounts[0].baseAccount.Address, transfers)
  1072  
  1073  	multiSendStr = `[{"to":"` + blockedAddr.String() + `","amount":" 100` + common.NativeToken + `"}]`
  1074  	transfers, err = types.StrToTransfers(multiSendStr)
  1075  	require.NoError(t, err)
  1076  	failedMultiSendMsg := types.NewMsgMultiSend(testAccounts[0].baseAccount.Address, transfers)
  1077  
  1078  	successfulTestSets := []struct {
  1079  		description string
  1080  		balance     string
  1081  		msg         sdk.Msg
  1082  		account     *testAccount
  1083  	}{
  1084  		// 0.01fibo as fixed fee in each stdTx
  1085  		{"success to send  : 50+0.01", "29949.990000000000000000", successfulSendMsg, testAccounts[0]},
  1086  		{"fail to send  : 0.01", "29949.980000000000000000", failedSendMsg, testAccounts[0]},
  1087  		{"success to multi-send  : 100+0.01", "29849.970000000000000000", successfulMultiSendMsg, testAccounts[0]},
  1088  		{"fail to multi-send  : 0.01", "29849.960000000000000000", failedMultiSendMsg, testAccounts[0]},
  1089  	}
  1090  	for i, tt := range successfulTestSets {
  1091  		t.Run(tt.description, func(t *testing.T) {
  1092  			stdTx := createTokenMsg(t, app, ctx, tt.account, tt.msg)
  1093  			ctx = mockApplyBlock(t, app, []*auth.StdTx{stdTx}, int64(i+3))
  1094  			require.Equal(t, tt.balance, app.AccountKeeper.GetAccount(ctx, testAccounts[0].addrKeys.Address).GetCoins().AmountOf(common.NativeToken).String())
  1095  		})
  1096  	}
  1097  
  1098  }
  1099  
  1100  func TestHandleTransferOwnership(t *testing.T) {
  1101  	common.InitConfig()
  1102  	app, keeper, testAccounts := getMockDexApp(t, 2)
  1103  	app.BeginBlock(abci.RequestBeginBlock{Header: abci.Header{Height: 2}})
  1104  	ctx := app.BaseApp.NewContext(false, abci.Header{}).WithBlockHeight(3)
  1105  	ctxPassedOwnershipConfirmWindow := app.BaseApp.NewContext(false, abci.Header{}).WithBlockTime(ctx.BlockTime().Add(types.DefaultOwnershipConfirmWindow * 2))
  1106  	handler := NewTokenHandler(keeper, version.ProtocolVersionV0)
  1107  
  1108  	param := types.DefaultParams()
  1109  	app.tokenKeeper.SetParams(ctx, param)
  1110  
  1111  	// issue token
  1112  	symbol := "xxb"
  1113  	msgNewIssue := types.NewMsgTokenIssue("xxb desc", symbol, symbol, symbol,
  1114  		"1000000", testAccounts[0], true)
  1115  	_, err := handler(ctx, msgNewIssue)
  1116  	require.Nil(t, err)
  1117  
  1118  	tokenName := getTokenSymbol(ctx, keeper, symbol)
  1119  
  1120  	// test case
  1121  	tests := []struct {
  1122  		ctx         sdk.Context
  1123  		msg         sdk.Msg
  1124  		expectedMsg string
  1125  	}{
  1126  		// case 1. sender is not the owner of token
  1127  		{
  1128  			ctx:         ctx,
  1129  			msg:         types.NewMsgTransferOwnership(testAccounts[1], testAccounts[0], tokenName),
  1130  			expectedMsg: fmt.Sprintf("input from address is not equal token owner: input from address is not equal token owner: %s", testAccounts[1]),
  1131  		},
  1132  		// case 2. transfer ownership to testAccounts[1] successfully
  1133  		{
  1134  			ctx:         ctx,
  1135  			msg:         types.NewMsgTransferOwnership(testAccounts[0], testAccounts[1], tokenName),
  1136  			expectedMsg: "",
  1137  		},
  1138  		// case 3. confirm ownership not exists
  1139  		{
  1140  			ctx:         ctx,
  1141  			msg:         types.NewMsgConfirmOwnership(testAccounts[1], "not-exist-token"),
  1142  			expectedMsg: fmt.Sprintf("get confirm ownership failed: get confirm ownership info failed"),
  1143  		},
  1144  		//// case 4. sender is not the owner of ConfirmOwnership
  1145  		{
  1146  			ctx:         ctx,
  1147  			msg:         types.NewMsgConfirmOwnership(testAccounts[0], tokenName),
  1148  			expectedMsg: fmt.Sprintf("input address is not equal confirm ownership address: input address (%s) is not equal confirm ownership address", testAccounts[0]),
  1149  		},
  1150  		// case 5. confirm ownership expired
  1151  		{
  1152  			ctx:         ctxPassedOwnershipConfirmWindow,
  1153  			msg:         types.NewMsgConfirmOwnership(testAccounts[1], tokenName),
  1154  			expectedMsg: fmt.Sprintf("confirm ownership not exist or blocktime after: confirm ownership not exist or blocktime after"),
  1155  		},
  1156  		// case 6. confirm ownership successfully
  1157  		{
  1158  			ctx:         ctx,
  1159  			msg:         types.NewMsgTransferOwnership(testAccounts[0], testAccounts[1], tokenName),
  1160  			expectedMsg: "",
  1161  		},
  1162  		{
  1163  			ctx:         ctx,
  1164  			msg:         types.NewMsgConfirmOwnership(testAccounts[1], tokenName),
  1165  			expectedMsg: "",
  1166  		},
  1167  
  1168  		// case 7. transfer ownership to testAccounts[0] successfully
  1169  		{
  1170  			ctx:         ctx,
  1171  			msg:         types.NewMsgTransferOwnership(testAccounts[1], testAccounts[0], tokenName),
  1172  			expectedMsg: "",
  1173  		},
  1174  		// case 8. confirm ownership exists but expired, and transfer to black hole successfully
  1175  		{
  1176  			ctx:         ctxPassedOwnershipConfirmWindow,
  1177  			msg:         types.NewMsgTransferOwnership(testAccounts[1], common.BlackHoleAddress(), tokenName),
  1178  			expectedMsg: "",
  1179  		},
  1180  	}
  1181  
  1182  	for _, testCase := range tests {
  1183  		_, err := handler(testCase.ctx, testCase.msg)
  1184  
  1185  		if err != nil {
  1186  			require.EqualValues(t, testCase.expectedMsg, err.Error())
  1187  		} else {
  1188  			require.EqualValues(t, testCase.expectedMsg, "")
  1189  		}
  1190  	}
  1191  
  1192  	token := keeper.GetTokenInfo(ctx, tokenName)
  1193  	require.True(t, token.Owner.Equals(common.BlackHoleAddress()))
  1194  
  1195  }
  1196  
  1197  func TestWalletTokenTransfer(t *testing.T) {
  1198  	app, keeper, addrs := getMockDexApp(t, 2)
  1199  	//tokenTransferMsg :=
  1200  	app.BeginBlock(abci.RequestBeginBlock{Header: abci.Header{Height: 2}})
  1201  	ctx := app.BaseApp.NewContext(false, abci.Header{}).WithBlockHeight(3)
  1202  	app.BaseApp.NewContext(false, abci.Header{}).WithBlockTime(ctx.BlockTime().Add(types.DefaultOwnershipConfirmWindow * 2))
  1203  
  1204  	tests := []struct {
  1205  		info     string
  1206  		ctx      sdk.Context
  1207  		msg      sdk.Msg
  1208  		expected func()
  1209  		pass     bool
  1210  	}{
  1211  		{
  1212  			"succ with transfer and balance equal",
  1213  			ctx,
  1214  			&bank.MsgSendAdapter{
  1215  				FromAddress: addrs[0].String(),
  1216  				ToAddress:   addrs[1].String(),
  1217  				Amount:      sdk.CoinAdapters{sdk.NewCoinAdapter(sdk.DefaultBondDenom, sdk.NewIntFromBigInt(big.NewInt(1000000000000000000)))},
  1218  			},
  1219  			func() {
  1220  				require.Equal(t, app.AccountKeeper.GetAccount(ctx, addrs[0]).GetCoins().AmountOf(common.NativeToken).String(), "99999.000000000000000000")
  1221  				require.Equal(t, app.AccountKeeper.GetAccount(ctx, addrs[1]).GetCoins().AmountOf(common.NativeToken).String(), "100001.000000000000000000")
  1222  			},
  1223  			true,
  1224  		},
  1225  		{
  1226  			"failure insufficient funds",
  1227  			ctx,
  1228  			&bank.MsgSendAdapter{
  1229  				FromAddress: addrs[0].String(),
  1230  				ToAddress:   addrs[1].String(),
  1231  				Amount:      sdk.CoinAdapters{sdk.NewCoinAdapter(sdk.DefaultBondDenom, sdk.NewIntFromBigInt(new(big.Int).Mul(big.NewInt(1000000000000000000), big.NewInt(100000))))},
  1232  			},
  1233  			func() {
  1234  			},
  1235  			false,
  1236  		},
  1237  	}
  1238  	handler := NewTokenHandler(keeper, version.ProtocolVersionV0)
  1239  	for _, tc := range tests {
  1240  		_, err := handler(ctx, tc.msg)
  1241  		tc.expected()
  1242  		if tc.pass {
  1243  			require.NoError(t, err)
  1244  		} else {
  1245  			require.Error(t, err)
  1246  		}
  1247  	}
  1248  }