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 }