github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/x/farm/handler_test.go (about) 1 //go:build ignore 2 // +build ignore 3 4 package farm 5 6 import ( 7 "errors" 8 "fmt" 9 "math" 10 "math/rand" 11 "testing" 12 13 "github.com/fibonacci-chain/fbc/x/common" 14 15 sdk "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types" 16 abci "github.com/fibonacci-chain/fbc/libs/tendermint/abci/types" 17 swap "github.com/fibonacci-chain/fbc/x/ammswap" 18 swaptypes "github.com/fibonacci-chain/fbc/x/ammswap/types" 19 "github.com/fibonacci-chain/fbc/x/farm/keeper" 20 "github.com/fibonacci-chain/fbc/x/farm/types" 21 "github.com/fibonacci-chain/fbc/x/token" 22 "github.com/stretchr/testify/require" 23 ) 24 25 type testContext struct { 26 ctx sdk.Context 27 k Keeper 28 mockKeeper keeper.MockFarmKeeper 29 swapTokenPairs []swaptypes.SwapTokenPair 30 tokenOwner sdk.AccAddress 31 nonPairTokenName []string 32 nonExistTokenName []string 33 addrList []sdk.AccAddress // 1000 fibo per address 34 handler sdk.Handler 35 } 36 37 type getMsgFunc func(tCtx *testContext, preData interface{}) sdk.Msg 38 39 type preExecFunc func(t *testing.T, tCtx *testContext) interface{} 40 41 type verificationFunc func(t *testing.T, tCtx *testContext, err sdk.Error, testCase testCaseItem, preCoins, afterCoins sdk.SysCoins, preData interface{}) 42 43 var verification verificationFunc = func(t *testing.T, context *testContext, err sdk.Error, testCase testCaseItem, preCoins, afterCoins sdk.SysCoins, preData interface{}) { 44 if testCase.expectedErr == nil { 45 require.Nil(t, err) 46 } else { 47 require.Equal(t, testCase.expectedErr.Error(), err.Error()) 48 } 49 } 50 51 type testCaseItem struct { 52 caseName string // the name of the case 53 preExec preExecFunc // function "preExec" executes the code before executing the specific handler to be tested 54 getMsg getMsgFunc // function "getMsg" returns a sdk.Msg for testing, this msg will be tested by executing the function "handler" 55 verification verificationFunc // function "verification" Verifies that the test results are the same as expected 56 expectedErr sdk.Error // expectedCode represents the expected code in the test result 57 } 58 59 func testCaseTest(t *testing.T, testCaseList []testCaseItem) { 60 for _, testCase := range testCaseList { 61 tCtx := initEnvironment(t) 62 preData := testCase.preExec(t, tCtx) 63 msg := testCase.getMsg(tCtx, preData) 64 addrList := msg.GetSigners() 65 addr := addrList[0] 66 preCoins := tCtx.k.TokenKeeper().GetCoins(tCtx.ctx, addr) 67 _, err := tCtx.handler(tCtx.ctx, msg) 68 afterCoins := tCtx.k.TokenKeeper().GetCoins(tCtx.ctx, addr) 69 testCase.verification(t, tCtx, err, testCase, preCoins, afterCoins, preData) 70 } 71 } 72 73 func testCaseCombinationTest(t *testing.T, testCaseList []testCaseItem) { 74 tCtx := initEnvironment(t) 75 for _, testCase := range testCaseList { 76 preData := testCase.preExec(t, tCtx) 77 msg := testCase.getMsg(tCtx, preData) 78 addrList := msg.GetSigners() 79 addr := addrList[0] 80 preCoins := tCtx.k.TokenKeeper().GetCoins(tCtx.ctx, addr) 81 _, err := tCtx.handler(tCtx.ctx, msg) 82 afterCoins := tCtx.k.TokenKeeper().GetCoins(tCtx.ctx, addr) 83 testCase.verification(t, tCtx, err, testCase, preCoins, afterCoins, preData) 84 } 85 } 86 87 func initEnvironment(t *testing.T) *testContext { 88 // init 89 ctx, mk := keeper.GetKeeper(t) 90 k := mk.Keeper 91 92 var blockHeight int64 = 10 93 ctx.SetBlockHeight(blockHeight) 94 BeginBlocker(ctx, abci.RequestBeginBlock{Header: abci.Header{Height: blockHeight}}, k) 95 96 testBaseTokenName := swaptypes.TestBasePooledToken 97 testQuoteTokenName := swaptypes.TestBasePooledToken2 98 testQuoteTokenName2 := swaptypes.TestBasePooledToken3 99 nonExistTokenName := "fff" 100 101 token.NewTestToken(t, ctx, mk.TokenKeeper, mk.BankKeeper, testBaseTokenName, keeper.Addrs) 102 token.NewTestToken(t, ctx, mk.TokenKeeper, mk.BankKeeper, testQuoteTokenName, keeper.Addrs) 103 token.NewTestToken(t, ctx, mk.TokenKeeper, mk.BankKeeper, testQuoteTokenName2, keeper.Addrs) 104 105 var initPoolTokenAmount int64 = 100 106 testBaseToken := sdk.NewDecCoinFromDec(testBaseTokenName, sdk.NewDec(initPoolTokenAmount)) 107 testQuoteToken := sdk.NewDecCoinFromDec(testQuoteTokenName, sdk.NewDec(initPoolTokenAmount)) 108 testAddr := keeper.Addrs[0] 109 testSwapTokenPair := swap.NewTestSwapTokenPairWithInitLiquidity(t, ctx, mk.SwapKeeper, testBaseToken, testQuoteToken, keeper.Addrs) 110 111 //acc := mk.AccKeeper.GetAccount(ctx, Addrs[0]) 112 //fmt.Println(acc) 113 114 handler := NewHandler(k) 115 116 return &testContext{ 117 ctx: ctx, 118 k: k, 119 mockKeeper: mk, 120 swapTokenPairs: []swap.SwapTokenPair{testSwapTokenPair}, 121 tokenOwner: testAddr, 122 nonPairTokenName: []string{testQuoteTokenName2}, 123 nonExistTokenName: []string{nonExistTokenName}, 124 addrList: keeper.Addrs[1:], 125 handler: handler, 126 } 127 } 128 129 var normalGetCreatePoolMsg getMsgFunc = func(tCtx *testContext, preData interface{}) sdk.Msg { 130 testSwapTokenPair := tCtx.swapTokenPairs[0] 131 testYieldTokenName := testSwapTokenPair.BasePooledCoin.Denom 132 owner := tCtx.tokenOwner 133 poolName := "abc" 134 minLockAmount := sdk.NewDecCoinFromDec(testSwapTokenPair.PoolTokenName, sdk.ZeroDec()) 135 createPoolMsg := types.NewMsgCreatePool(owner, poolName, minLockAmount, testYieldTokenName) 136 return createPoolMsg 137 } 138 139 var normalGetDestroyPoolMsg getMsgFunc = func(tCtx *testContext, preData interface{}) sdk.Msg { 140 createPoolMsg := preData.(types.MsgCreatePool) 141 addr := createPoolMsg.Owner 142 poolName := createPoolMsg.PoolName 143 destroyPoolMsg := types.NewMsgDestroyPool(addr, poolName) 144 return destroyPoolMsg 145 } 146 147 var normalGetProvideMsg getMsgFunc = func(tCtx *testContext, preData interface{}) sdk.Msg { 148 createPoolMsg := preData.(types.MsgCreatePool) 149 poolName := createPoolMsg.PoolName 150 address := createPoolMsg.Owner 151 amount := sdk.NewDecCoinFromDec(createPoolMsg.YieldedSymbol, sdk.NewDec(10)) 152 amountYieldedPerBlock := sdk.NewDec(1) 153 startBlockHeight := tCtx.ctx.BlockHeight() + 1 154 provideMsg := types.NewMsgProvide(poolName, address, amount, amountYieldedPerBlock, startBlockHeight) 155 return provideMsg 156 } 157 158 var normalGetLockMsg getMsgFunc = func(tCtx *testContext, preData interface{}) sdk.Msg { 159 createPoolMsg := preData.(types.MsgCreatePool) 160 poolName := createPoolMsg.PoolName 161 address := createPoolMsg.Owner 162 amount := sdk.NewDecCoinFromDec(createPoolMsg.MinLockAmount.Denom, sdk.NewDec(1)) 163 lockMsg := types.NewMsgLock(poolName, address, amount) 164 return lockMsg 165 } 166 167 var normalGetUnlockMsg getMsgFunc = func(tCtx *testContext, preData interface{}) sdk.Msg { 168 createPoolMsg := preData.(types.MsgCreatePool) 169 poolName := createPoolMsg.PoolName 170 address := createPoolMsg.Owner 171 amount := sdk.NewDecCoinFromDec(createPoolMsg.MinLockAmount.Denom, sdk.NewDec(1)) 172 unlockMsg := types.NewMsgUnlock(poolName, address, amount) 173 return unlockMsg 174 } 175 176 var normalGetClaimMsg getMsgFunc = func(tCtx *testContext, preData interface{}) sdk.Msg { 177 createPoolMsg := preData.(types.MsgCreatePool) 178 claimMsg := types.NewMsgClaim(createPoolMsg.PoolName, createPoolMsg.Owner) 179 return claimMsg 180 } 181 182 func createPool(t *testing.T, tCtx *testContext) types.MsgCreatePool { 183 createPoolMsg := normalGetCreatePoolMsg(tCtx, nil).(types.MsgCreatePool) 184 _, err := tCtx.handler(tCtx.ctx, createPoolMsg) 185 require.Nil(t, err) 186 187 k := tCtx.k 188 found := k.HasFarmPool(tCtx.ctx, createPoolMsg.PoolName) 189 require.True(t, found) 190 return createPoolMsg 191 } 192 193 func destroyPool(t *testing.T, tCtx *testContext, createPoolMsg types.MsgCreatePool) { 194 k := tCtx.k 195 found := k.HasFarmPool(tCtx.ctx, createPoolMsg.PoolName) 196 require.True(t, found) 197 destroyPoolMsg := normalGetDestroyPoolMsg(tCtx, createPoolMsg) 198 _, err := tCtx.handler(tCtx.ctx, destroyPoolMsg) 199 require.Nil(t, err) 200 found = k.HasFarmPool(tCtx.ctx, createPoolMsg.PoolName) 201 require.False(t, found) 202 } 203 204 func provide(t *testing.T, tCtx *testContext, createPoolMsg types.MsgCreatePool) types.MsgProvide { 205 provideMsg := normalGetProvideMsg(tCtx, createPoolMsg) 206 _, err := tCtx.handler(tCtx.ctx, provideMsg) 207 require.Nil(t, err) 208 return provideMsg.(types.MsgProvide) 209 } 210 211 func lock(t *testing.T, tCtx *testContext, createPoolMsg types.MsgCreatePool) types.MsgLock { 212 lockMsg := normalGetLockMsg(tCtx, createPoolMsg) 213 _, err := tCtx.handler(tCtx.ctx, lockMsg) 214 require.Nil(t, err) 215 return lockMsg.(types.MsgLock) 216 } 217 218 func unlock(t *testing.T, tCtx *testContext, createPoolMsg types.MsgCreatePool) { 219 unlockMsg := normalGetUnlockMsg(tCtx, createPoolMsg) 220 _, err := tCtx.handler(tCtx.ctx, unlockMsg) 221 require.Nil(t, err) 222 } 223 224 func claim(t *testing.T, tCtx *testContext, createPoolMsg types.MsgCreatePool) { 225 claimMsg := normalGetClaimMsg(tCtx, createPoolMsg) 226 _, err := tCtx.handler(tCtx.ctx, claimMsg) 227 require.Nil(t, err) 228 } 229 230 func TestHandlerMsgCreatePool(t *testing.T) { 231 preExec := func(t *testing.T, tCtx *testContext) interface{} { 232 return nil 233 } 234 235 tests := []testCaseItem{ 236 { 237 caseName: "success", 238 preExec: preExec, 239 getMsg: normalGetCreatePoolMsg, 240 verification: verification, 241 expectedErr: nil, 242 }, 243 { 244 caseName: "success. create again after destroying", 245 preExec: func(t *testing.T, tCtx *testContext) interface{} { 246 createPoolMsg := createPool(t, tCtx) 247 248 provide(t, tCtx, createPoolMsg) 249 250 lock(t, tCtx, createPoolMsg) 251 252 tCtx.ctx.SetBlockHeight(tCtx.ctx.BlockHeight() + 1000) 253 254 claim(t, tCtx, createPoolMsg) 255 256 unlock(t, tCtx, createPoolMsg) 257 258 destroyPool(t, tCtx, createPoolMsg) 259 260 return nil 261 }, 262 getMsg: normalGetCreatePoolMsg, 263 verification: verification, 264 expectedErr: nil, 265 }, 266 { 267 caseName: "failed. farm pool already exists", 268 preExec: func(t *testing.T, tCtx *testContext) interface{} { 269 return createPool(t, tCtx) 270 }, 271 getMsg: func(tCtx *testContext, preData interface{}) sdk.Msg { 272 createPoolMsg := preData.(types.MsgCreatePool) 273 return createPoolMsg 274 }, 275 verification: verification, 276 expectedErr: types.ErrPoolAlreadyExist("abc"), 277 }, 278 { 279 caseName: "failed. lock token does not exists", 280 preExec: preExec, 281 getMsg: func(tCtx *testContext, preData interface{}) sdk.Msg { 282 createPoolMsg := normalGetCreatePoolMsg(tCtx, preData).(types.MsgCreatePool) 283 createPoolMsg.MinLockAmount = sdk.NewDecCoinFromDec(tCtx.nonExistTokenName[0], sdk.ZeroDec()) 284 return createPoolMsg 285 }, 286 verification: verification, 287 expectedErr: types.ErrTokenNotExist("fff"), 288 }, 289 { 290 caseName: "failed. yield token does not exists", 291 preExec: preExec, 292 getMsg: func(tCtx *testContext, preData interface{}) sdk.Msg { 293 createPoolMsg := normalGetCreatePoolMsg(tCtx, nil).(types.MsgCreatePool) 294 createPoolMsg.YieldedSymbol = tCtx.nonExistTokenName[0] 295 return createPoolMsg 296 }, 297 verification: verification, 298 expectedErr: types.ErrTokenNotExist("fff"), 299 }, 300 { 301 caseName: "failed. insufficient fee coins", 302 preExec: func(t *testing.T, context *testContext) interface{} { 303 params := context.k.GetParams(context.ctx) 304 params.CreatePoolFee = sdk.NewDecCoinFromDec(context.nonExistTokenName[0], sdk.NewDec(1)) 305 context.k.SetParams(context.ctx, params) 306 return nil 307 }, 308 getMsg: normalGetCreatePoolMsg, 309 verification: verification, 310 expectedErr: errors.New( 311 "insufficient coins: insufficient funds: insufficient account funds; 89900.000000000000000000aab,101.000000000000000000ammswap_aab_ccb,89900.000000000000000000ccb,100000.000000000000000000ddb,1000.000000000000000000fibo < 1.000000000000000000fff", 312 ), 313 }, 314 { 315 caseName: "failed. insufficient coins", 316 preExec: func(t *testing.T, context *testContext) interface{} { 317 params := context.k.GetParams(context.ctx) 318 params.CreatePoolDeposit = sdk.NewDecCoinFromDec(context.nonExistTokenName[0], sdk.NewDec(1)) 319 context.k.SetParams(context.ctx, params) 320 return nil 321 }, 322 getMsg: normalGetCreatePoolMsg, 323 verification: verification, 324 expectedErr: errors.New( 325 "insufficient coins: insufficient funds: insufficient account funds; 89900.000000000000000000aab,101.000000000000000000ammswap_aab_ccb,89900.000000000000000000ccb,100000.000000000000000000ddb,1000.000000000000000000fibo < 1.000000000000000000fff", 326 ), 327 }, 328 } 329 testCaseTest(t, tests) 330 } 331 332 func TestHandlerMsgDestroyPool(t *testing.T) { 333 common.InitConfig() 334 preExec := func(t *testing.T, tCtx *testContext) interface{} { 335 // create pool 336 createPoolMsg := createPool(t, tCtx) 337 return createPoolMsg 338 } 339 tests := []testCaseItem{ 340 { 341 caseName: "success", 342 preExec: preExec, 343 getMsg: normalGetDestroyPoolMsg, 344 verification: verification, 345 expectedErr: nil, 346 }, 347 { 348 caseName: "failed. Farm pool does not exist", 349 preExec: func(t *testing.T, tCtx *testContext) interface{} { 350 createPoolMsg := normalGetCreatePoolMsg(tCtx, nil) 351 return createPoolMsg 352 }, 353 getMsg: normalGetDestroyPoolMsg, 354 verification: verification, 355 expectedErr: types.ErrNoFarmPoolFound("abc"), 356 }, 357 { 358 caseName: "failed. the address isn't the owner of pool", 359 preExec: preExec, 360 getMsg: func(tCtx *testContext, preData interface{}) sdk.Msg { 361 destroyPoolMsg := normalGetDestroyPoolMsg(tCtx, preData).(types.MsgDestroyPool) 362 destroyPoolMsg.Owner = tCtx.addrList[0] 363 return destroyPoolMsg 364 }, 365 verification: verification, 366 expectedErr: types.ErrInvalidPoolOwner("ex15ky9du8a2wlstz6fpx3p4mqpjyrm5cgp83ahy9", "abc"), 367 }, 368 { 369 caseName: "failed. insufficient fee coins", 370 preExec: func(t *testing.T, tCtx *testContext) interface{} { 371 // create pool 372 createPoolMsg := createPool(t, tCtx) 373 374 // modify params 375 pools, found := tCtx.k.GetFarmPool(tCtx.ctx, createPoolMsg.PoolName) 376 require.True(t, found) 377 pools.DepositAmount = sdk.NewDecCoinFromDec(tCtx.nonExistTokenName[0], sdk.NewDec(1)) 378 tCtx.k.SetFarmPool(tCtx.ctx, pools) 379 return createPoolMsg 380 }, 381 getMsg: normalGetDestroyPoolMsg, 382 verification: verification, 383 expectedErr: errors.New("insufficient coins: insufficient funds: insufficient account funds; 10.000000000000000000fibo < 1.000000000000000000fff"), 384 }, 385 { 386 caseName: "failed. the pool is not finished and can not be destroyed", 387 preExec: func(t *testing.T, tCtx *testContext) interface{} { 388 // create pool 389 createPoolMsg := createPool(t, tCtx) 390 391 // provide 392 provide(t, tCtx, createPoolMsg) 393 394 return createPoolMsg 395 }, 396 getMsg: normalGetDestroyPoolMsg, 397 verification: verification, 398 expectedErr: types.ErrPoolNotFinished("abc"), 399 }, 400 { 401 caseName: "success. destroy after providing", 402 preExec: func(t *testing.T, tCtx *testContext) interface{} { 403 // create pool 404 createPoolMsg := createPool(t, tCtx) 405 406 // provide 407 provide(t, tCtx, createPoolMsg) 408 409 tCtx.ctx.SetBlockHeight(tCtx.ctx.BlockHeight() + 1000) 410 411 return createPoolMsg 412 }, 413 getMsg: normalGetDestroyPoolMsg, 414 verification: verification, 415 expectedErr: nil, 416 }, 417 { 418 caseName: "success. destroy after claiming", 419 preExec: func(t *testing.T, tCtx *testContext) interface{} { 420 // create pool 421 createPoolMsg := createPool(t, tCtx) 422 423 // provide 424 provide(t, tCtx, createPoolMsg) 425 426 lock(t, tCtx, createPoolMsg) 427 428 tCtx.ctx.SetBlockHeight(tCtx.ctx.BlockHeight() + 1000) 429 430 claim(t, tCtx, createPoolMsg) 431 432 unlock(t, tCtx, createPoolMsg) 433 434 return createPoolMsg 435 }, 436 getMsg: normalGetDestroyPoolMsg, 437 verification: verification, 438 expectedErr: nil, 439 }, 440 { 441 caseName: "failed. insufficient rewards coins", 442 preExec: func(t *testing.T, tCtx *testContext) interface{} { 443 // create pool 444 createPoolMsg := createPool(t, tCtx) 445 446 // provide 447 provide(t, tCtx, createPoolMsg) 448 449 tCtx.ctx.SetBlockHeight(tCtx.ctx.BlockHeight() + 1000) 450 451 pool, found := tCtx.k.GetFarmPool(tCtx.ctx, createPoolMsg.PoolName) 452 require.True(t, found) 453 updatedPool, _ := tCtx.k.CalculateAmountYieldedBetween(tCtx.ctx, pool) 454 455 err := tCtx.k.SupplyKeeper().SendCoinsFromModuleToAccount(tCtx.ctx, YieldFarmingAccount, createPoolMsg.Owner, updatedPool.TotalAccumulatedRewards) 456 require.Nil(t, err) 457 458 return createPoolMsg 459 }, 460 getMsg: normalGetDestroyPoolMsg, 461 verification: verification, 462 expectedErr: errors.New("insufficient coins: insufficient funds: insufficient account funds; < 10.000000000000000000aab"), 463 }, 464 { 465 caseName: "failed. the pool is not finished and can not be destroyed", 466 preExec: func(t *testing.T, tCtx *testContext) interface{} { 467 // create pool 468 createPoolMsg := createPool(t, tCtx) 469 470 // provide 471 provide(t, tCtx, createPoolMsg) 472 473 // lock 474 lock(t, tCtx, createPoolMsg) 475 476 tCtx.ctx.SetBlockHeight(tCtx.ctx.BlockHeight() + 1000) 477 478 return createPoolMsg 479 }, 480 getMsg: normalGetDestroyPoolMsg, 481 verification: verification, 482 expectedErr: types.ErrPoolNotFinished("abc"), 483 }, 484 } 485 testCaseTest(t, tests) 486 } 487 488 func TestHandlerMsgProvide(t *testing.T) { 489 var preExec preExecFunc = func(t *testing.T, tCtx *testContext) interface{} { 490 // create pool 491 createPoolMsg := createPool(t, tCtx) 492 return createPoolMsg 493 } 494 tests := []testCaseItem{ 495 { 496 caseName: "success", 497 preExec: preExec, 498 getMsg: normalGetProvideMsg, 499 verification: verification, 500 expectedErr: nil, 501 }, 502 { 503 caseName: "failed. The start height to yield is less than current height", 504 preExec: preExec, 505 getMsg: func(tCtx *testContext, preData interface{}) sdk.Msg { 506 provideMsg := normalGetProvideMsg(tCtx, preData).(types.MsgProvide) 507 provideMsg.StartHeightToYield = 0 508 return provideMsg 509 }, 510 verification: verification, 511 expectedErr: types.ErrInvalidStartHeight(), 512 }, 513 { 514 caseName: "failed. Farm pool does not exist", 515 preExec: func(t *testing.T, tCtx *testContext) interface{} { 516 createPoolMsg := normalGetCreatePoolMsg(tCtx, nil) 517 return createPoolMsg 518 }, 519 getMsg: normalGetProvideMsg, 520 verification: verification, 521 expectedErr: types.ErrNoFarmPoolFound("abc"), 522 }, 523 { 524 caseName: "failed. The coin name should be %s, not %s", 525 preExec: preExec, 526 getMsg: func(tCtx *testContext, preData interface{}) sdk.Msg { 527 provideMsg := normalGetProvideMsg(tCtx, preData).(types.MsgProvide) 528 provideMsg.Amount = sdk.NewDecCoinFromDec(tCtx.nonExistTokenName[0], provideMsg.Amount.Amount) 529 return provideMsg 530 }, 531 verification: verification, 532 expectedErr: types.ErrInvalidDenom("aab", "fff"), 533 }, 534 { 535 caseName: "failed. The remaining amount is %s, so it's not enable to provide token repeatedly util amount become zero", 536 preExec: func(t *testing.T, tCtx *testContext) interface{} { 537 // create pool 538 createPoolMsg := createPool(t, tCtx) 539 540 // provide 541 provide(t, tCtx, createPoolMsg) 542 return createPoolMsg 543 }, 544 getMsg: normalGetProvideMsg, 545 verification: verification, 546 expectedErr: types.ErrRemainingAmountNotZero("10.000000000000000000aab"), 547 }, 548 { 549 caseName: "insufficient amount", 550 preExec: preExec, 551 getMsg: func(tCtx *testContext, preData interface{}) sdk.Msg { 552 provideMsg := normalGetProvideMsg(tCtx, preData).(types.MsgProvide) 553 provideMsg.Amount = sdk.NewDecCoinFromDec(provideMsg.Amount.Denom, sdk.NewDec(1000000000)) 554 return provideMsg 555 }, 556 verification: verification, 557 expectedErr: errors.New(fmt.Sprintf("failed. send coins from account to module failed insufficient funds: insufficient account funds; "+ 558 "89900.000000000000000000aab,101.000000000000000000ammswap_aab_ccb,89900.000000000000000000ccb,"+ 559 "100000.000000000000000000ddb,990.000000000000000000%s < 1000000000.000000000000000000aab", sdk.DefaultBondDenom)), 560 }, 561 } 562 563 testCaseTest(t, tests) 564 } 565 566 func TestHandlerMsgLock(t *testing.T) { 567 var preExec preExecFunc = func(t *testing.T, tCtx *testContext) interface{} { 568 // create pool 569 createPoolMsg := createPool(t, tCtx) 570 571 // provide 572 provide(t, tCtx, createPoolMsg) 573 574 return createPoolMsg 575 } 576 tests := []testCaseItem{ 577 { 578 caseName: "success", 579 preExec: preExec, 580 getMsg: normalGetLockMsg, 581 verification: verification, 582 expectedErr: nil, 583 }, 584 { 585 caseName: "failed. Farm pool does not exist", 586 preExec: func(t *testing.T, tCtx *testContext) interface{} { 587 createPoolMsg := normalGetCreatePoolMsg(tCtx, nil) 588 return createPoolMsg 589 }, 590 getMsg: normalGetLockMsg, 591 verification: verification, 592 expectedErr: types.ErrNoFarmPoolFound("abc"), 593 }, 594 { 595 caseName: "failed. The coin name should be %s, not %s", 596 preExec: preExec, 597 getMsg: func(tCtx *testContext, preData interface{}) sdk.Msg { 598 lockMsg := normalGetLockMsg(tCtx, preData).(types.MsgLock) 599 lockMsg.Amount.Denom = tCtx.nonExistTokenName[0] 600 return lockMsg 601 }, 602 verification: verification, 603 expectedErr: types.ErrInvalidDenom("ammswap_aab_ccb", "fff"), 604 }, 605 { 606 caseName: "failed. lock amount %s must be greater than the pool`s min lock amount %s", 607 preExec: func(t *testing.T, tCtx *testContext) interface{} { 608 // create pool 609 createPoolMsg := normalGetCreatePoolMsg(tCtx, nil).(types.MsgCreatePool) 610 createPoolMsg.MinLockAmount.Amount = sdk.NewDec(math.MaxInt64) 611 _, err := tCtx.handler(tCtx.ctx, createPoolMsg) 612 require.Nil(t, err) 613 614 // provide 615 provide(t, tCtx, createPoolMsg) 616 617 return createPoolMsg 618 }, 619 getMsg: normalGetLockMsg, 620 verification: verification, 621 expectedErr: types.ErrLockAmountBelowMinimum(sdk.MustNewDecFromStr("9223372036854775807.000000000000000000"), sdk.MustNewDecFromStr("1.000000000000000000")), 622 }, 623 { 624 caseName: "success. has lockInfo", 625 preExec: func(t *testing.T, tCtx *testContext) interface{} { 626 // create pool 627 createPoolMsg := createPool(t, tCtx) 628 629 // provide 630 provide(t, tCtx, createPoolMsg) 631 632 // lock 633 lock(t, tCtx, createPoolMsg) 634 635 tCtx.ctx.SetBlockHeight(tCtx.ctx.BlockHeight() + 2) 636 637 return createPoolMsg 638 }, 639 getMsg: normalGetLockMsg, 640 verification: func(t *testing.T, tCtx *testContext, err sdk.Error, testCase testCaseItem, preCoins, afterCoins sdk.SysCoins, preData interface{}) { 641 verification(t, tCtx, err, testCase, preCoins, afterCoins, preData) 642 createPoolMsg := preData.(types.MsgCreatePool) 643 644 // claimed rewards 645 rewards := tCtx.mockKeeper.ObserverKeeper.ObserverData.ClaimedCoins.AmountOf(createPoolMsg.YieldedSymbol) 646 require.Equal(t, sdk.NewDec(1), rewards) 647 }, 648 expectedErr: nil, 649 }, 650 { 651 caseName: "failed. withdraw failed", 652 preExec: func(t *testing.T, tCtx *testContext) interface{} { 653 // create pool 654 createPoolMsg := createPool(t, tCtx) 655 656 // provide 657 provideMsg := provide(t, tCtx, createPoolMsg) 658 659 // lock 660 lock(t, tCtx, createPoolMsg) 661 662 tCtx.ctx.SetBlockHeight(tCtx.ctx.BlockHeight() + 1000) 663 664 err := tCtx.k.SupplyKeeper().SendCoinsFromModuleToAccount(tCtx.ctx, types.YieldFarmingAccount, provideMsg.Address, sdk.NewCoins(provideMsg.Amount)) 665 require.Nil(t, err) 666 return createPoolMsg 667 }, 668 getMsg: normalGetLockMsg, 669 verification: verification, 670 expectedErr: errors.New("insufficient funds: insufficient account funds; < 10.000000000000000000aab"), 671 }, 672 { 673 caseName: "failed. insufficient coins", 674 preExec: preExec, 675 getMsg: func(tCtx *testContext, preData interface{}) sdk.Msg { 676 lockMsg := normalGetLockMsg(tCtx, preData).(types.MsgLock) 677 lockMsg.Amount.Amount = sdk.NewDec(1000000) 678 return lockMsg 679 }, 680 verification: verification, 681 expectedErr: errors.New(fmt.Sprintf("failed. send coins from account to module failed insufficient funds: insufficient account funds; "+ 682 "89890.000000000000000000aab,101.000000000000000000ammswap_aab_ccb,89900.000000000000000000ccb,"+ 683 "100000.000000000000000000ddb,990.000000000000000000%s < 1000000.000000000000000000ammswap_aab_ccb", sdk.DefaultBondDenom)), 684 }, 685 } 686 687 testCaseTest(t, tests) 688 } 689 690 func TestHandlerMsgUnlock(t *testing.T) { 691 common.InitConfig() 692 var preExec preExecFunc = func(t *testing.T, tCtx *testContext) interface{} { 693 // create pool 694 createPoolMsg := createPool(t, tCtx) 695 696 // provide 697 provide(t, tCtx, createPoolMsg) 698 699 // lock 700 lock(t, tCtx, createPoolMsg) 701 702 return createPoolMsg 703 } 704 tests := []testCaseItem{ 705 { 706 caseName: "success", 707 preExec: preExec, 708 getMsg: normalGetUnlockMsg, 709 verification: verification, 710 expectedErr: nil, 711 }, 712 { 713 caseName: "failed. the addr doesn't have any lock infos", 714 preExec: func(t *testing.T, tCtx *testContext) interface{} { 715 // create pool 716 createPoolMsg := createPool(t, tCtx) 717 718 // provide 719 provide(t, tCtx, createPoolMsg) 720 return createPoolMsg 721 }, 722 getMsg: normalGetUnlockMsg, 723 verification: verification, 724 expectedErr: types.ErrNoLockInfoFound("ex15ky9du8a2wlstz6fpx3p4mqpjyrm5cgq68fzeh", "abc"), 725 }, 726 { 727 caseName: "failed. The coin name should be %s, not %s", 728 preExec: preExec, 729 getMsg: func(tCtx *testContext, preData interface{}) sdk.Msg { 730 unlockMsg := normalGetUnlockMsg(tCtx, preData).(types.MsgUnlock) 731 unlockMsg.Amount.Denom = tCtx.nonExistTokenName[0] 732 return unlockMsg 733 }, 734 verification: verification, 735 expectedErr: types.ErrInvalidDenom("ammswap_aab_ccb", "fff"), 736 }, 737 { 738 caseName: "failed. The actual amount %s is less than %s", 739 preExec: preExec, 740 getMsg: func(tCtx *testContext, preData interface{}) sdk.Msg { 741 unlockMsg := normalGetUnlockMsg(tCtx, preData).(types.MsgUnlock) 742 unlockMsg.Amount.Amount = unlockMsg.Amount.Amount.Add(sdk.NewDec(1)) 743 return unlockMsg 744 }, 745 verification: verification, 746 expectedErr: types.ErrInsufficientAmount("1.000000000000000000ammswap_aab_ccb", "2.000000000000000000ammswap_aab_ccb"), 747 }, 748 { 749 caseName: "failed. remain lock amount %s is less than pool`s min lock amount %s", 750 preExec: func(t *testing.T, tCtx *testContext) interface{} { 751 // create pool 752 createPoolMsg := normalGetCreatePoolMsg(tCtx, nil).(types.MsgCreatePool) 753 createPoolMsg.MinLockAmount.Amount = sdk.NewDec(2) 754 _, err := tCtx.handler(tCtx.ctx, createPoolMsg) 755 require.Nil(t, err) 756 757 // provide 758 provide(t, tCtx, createPoolMsg) 759 760 // lock 761 lockMsg := normalGetLockMsg(tCtx, createPoolMsg).(types.MsgLock) 762 lockMsg.Amount.Amount = sdk.NewDec(2) 763 _, err = tCtx.handler(tCtx.ctx, lockMsg) 764 require.Nil(t, err) 765 766 return createPoolMsg 767 }, 768 getMsg: normalGetUnlockMsg, 769 verification: verification, 770 expectedErr: types.ErrLockAmountBelowMinimum(sdk.MustNewDecFromStr("2.000000000000000000"), sdk.MustNewDecFromStr("1.000000000000000000")), 771 }, 772 { 773 caseName: "failed. Farm pool %s does not exist", 774 preExec: func(t *testing.T, tCtx *testContext) interface{} { 775 preData := preExec(t, tCtx).(types.MsgCreatePool) 776 tCtx.k.DeleteFarmPool(tCtx.ctx, preData.PoolName) 777 return preData 778 }, 779 getMsg: normalGetUnlockMsg, 780 verification: verification, 781 expectedErr: types.ErrNoFarmPoolFound("abc"), 782 }, 783 { 784 caseName: "failed. withdraw failed", 785 preExec: func(t *testing.T, tCtx *testContext) interface{} { 786 // create pool 787 createPoolMsg := createPool(t, tCtx) 788 789 // provide 790 provideMsg := provide(t, tCtx, createPoolMsg) 791 792 // lock 793 lock(t, tCtx, createPoolMsg) 794 795 tCtx.ctx.SetBlockHeight(tCtx.ctx.BlockHeight() + 1000) 796 797 err := tCtx.k.SupplyKeeper().SendCoinsFromModuleToAccount(tCtx.ctx, types.YieldFarmingAccount, provideMsg.Address, sdk.NewCoins(provideMsg.Amount)) 798 require.Nil(t, err) 799 return createPoolMsg 800 }, 801 getMsg: normalGetUnlockMsg, 802 verification: verification, 803 expectedErr: errors.New("insufficient funds: insufficient account funds; < 10.000000000000000000aab"), 804 }, 805 { 806 caseName: "failed. insufficient coins from module account", 807 preExec: func(t *testing.T, tCtx *testContext) interface{} { 808 // create pool 809 createPoolMsg := createPool(t, tCtx) 810 811 // provide 812 provide(t, tCtx, createPoolMsg) 813 814 // lock 815 lockMsg := lock(t, tCtx, createPoolMsg) 816 817 tCtx.ctx.SetBlockHeight(tCtx.ctx.BlockHeight() + 1000) 818 819 err := tCtx.k.SupplyKeeper().SendCoinsFromModuleToAccount(tCtx.ctx, ModuleName, lockMsg.Address, sdk.NewCoins(lockMsg.Amount)) 820 require.Nil(t, err) 821 return createPoolMsg 822 }, 823 getMsg: normalGetUnlockMsg, 824 verification: verification, 825 expectedErr: errors.New(fmt.Sprintf("failed. send coins from module to account failed insufficient funds: insufficient account funds; "+"10.000000000000000000%s < 1.000000000000000000ammswap_aab_ccb", sdk.DefaultBondDenom)), 826 }, 827 { 828 caseName: "success. lock and unlock without provide before", 829 preExec: func(t *testing.T, tCtx *testContext) interface{} { 830 // create pool 831 createPoolMsg := createPool(t, tCtx) 832 833 // lock 834 lock(t, tCtx, createPoolMsg) 835 836 tCtx.ctx.SetBlockHeight(tCtx.ctx.BlockHeight() + 1000) 837 return createPoolMsg 838 }, 839 getMsg: normalGetUnlockMsg, 840 verification: verification, 841 expectedErr: nil, 842 }, 843 { 844 caseName: "success with rewards", 845 preExec: func(t *testing.T, tCtx *testContext) interface{} { 846 // create pool 847 createPoolMsg := createPool(t, tCtx) 848 849 // provide 850 provide(t, tCtx, createPoolMsg) 851 852 // lock 853 lock(t, tCtx, createPoolMsg) 854 855 tCtx.ctx.SetBlockHeight(tCtx.ctx.BlockHeight() + 2) 856 857 return createPoolMsg 858 }, 859 getMsg: normalGetUnlockMsg, 860 verification: func(t *testing.T, tCtx *testContext, err sdk.Error, testCase testCaseItem, preCoins, afterCoins sdk.SysCoins, preData interface{}) { 861 verification(t, tCtx, err, testCase, preCoins, afterCoins, preData) 862 createPoolMsg := preData.(types.MsgCreatePool) 863 diffCoins := afterCoins.Sub(preCoins) 864 actualDec := diffCoins.AmountOf(createPoolMsg.YieldedSymbol) 865 require.Equal(t, sdk.NewDec(1), actualDec) 866 867 // claimed rewards 868 rewards := tCtx.mockKeeper.ObserverKeeper.ObserverData.ClaimedCoins.AmountOf(createPoolMsg.YieldedSymbol) 869 require.Equal(t, sdk.NewDec(1), rewards) 870 }, 871 expectedErr: nil, 872 }, 873 } 874 875 testCaseTest(t, tests) 876 } 877 878 func TestHandlerMsgClaim(t *testing.T) { 879 var preExec preExecFunc = func(t *testing.T, tCtx *testContext) interface{} { 880 // create pool 881 createPoolMsg := createPool(t, tCtx) 882 883 // provide 884 provide(t, tCtx, createPoolMsg) 885 886 // lock 887 lock(t, tCtx, createPoolMsg) 888 889 return createPoolMsg 890 } 891 tests := []testCaseItem{ 892 { 893 caseName: "success. claim after providing at the same block height", 894 preExec: preExec, 895 getMsg: normalGetClaimMsg, 896 verification: verification, 897 expectedErr: nil, 898 }, 899 { 900 caseName: "success. claim after providing at the lower block height", 901 preExec: func(t *testing.T, tCtx *testContext) interface{} { 902 // create pool 903 createPoolMsg := createPool(t, tCtx) 904 905 // provide 906 provide(t, tCtx, createPoolMsg) 907 908 // lock 909 lock(t, tCtx, createPoolMsg) 910 911 tCtx.ctx.SetBlockHeight(tCtx.ctx.BlockHeight() + 2) 912 913 return createPoolMsg 914 }, 915 getMsg: normalGetClaimMsg, 916 verification: func(t *testing.T, tCtx *testContext, err sdk.Error, testCase testCaseItem, preCoins, afterCoins sdk.SysCoins, preData interface{}) { 917 verification(t, tCtx, err, testCase, preCoins, afterCoins, preData) 918 createPoolMsg := preData.(types.MsgCreatePool) 919 diffCoins := afterCoins.Sub(preCoins) 920 actualDec := diffCoins.AmountOf(createPoolMsg.YieldedSymbol) 921 require.Equal(t, sdk.NewDec(1), actualDec) 922 923 // claimed rewards 924 rewards := tCtx.mockKeeper.ObserverKeeper.ObserverData.ClaimedCoins.AmountOf(createPoolMsg.YieldedSymbol) 925 require.Equal(t, sdk.NewDec(1), rewards) 926 }, 927 expectedErr: nil, 928 }, 929 { 930 caseName: "failed. Farm pool %s does not exist", 931 preExec: func(t *testing.T, tCtx *testContext) interface{} { 932 createPoolMsg := normalGetCreatePoolMsg(tCtx, nil) 933 return createPoolMsg 934 }, 935 getMsg: normalGetClaimMsg, 936 verification: verification, 937 expectedErr: types.ErrNoFarmPoolFound("abc"), 938 }, 939 { 940 caseName: "failed. withdraw failed", 941 preExec: func(t *testing.T, tCtx *testContext) interface{} { 942 // create pool 943 createPoolMsg := createPool(t, tCtx) 944 945 // provide 946 provideMsg := provide(t, tCtx, createPoolMsg) 947 948 // lock 949 lock(t, tCtx, createPoolMsg) 950 951 tCtx.ctx.SetBlockHeight(tCtx.ctx.BlockHeight() + 1000) 952 953 err := tCtx.k.SupplyKeeper().SendCoinsFromModuleToAccount(tCtx.ctx, types.YieldFarmingAccount, provideMsg.Address, sdk.NewCoins(provideMsg.Amount)) 954 require.Nil(t, err) 955 return createPoolMsg 956 }, 957 getMsg: normalGetClaimMsg, 958 verification: verification, 959 expectedErr: errors.New("insufficient funds: insufficient account funds; < 10.000000000000000000aab"), 960 }, 961 } 962 963 testCaseTest(t, tests) 964 } 965 966 func TestNewHandler(t *testing.T) { 967 // init 968 tCtx := initEnvironment(t) 969 msg := swaptypes.NewMsgCreateExchange(tCtx.swapTokenPairs[0].BasePooledCoin.Denom, tCtx.swapTokenPairs[0].QuotePooledCoin.Denom, tCtx.tokenOwner) 970 _, err := tCtx.handler(tCtx.ctx, msg) 971 require.Error(t, err) 972 } 973 974 func TestHandlerMultiLockAtOneBlockHeight(t *testing.T) { 975 tCtx := initEnvironment(t) 976 977 // create pool 978 createPoolMsg := createPool(t, tCtx) 979 980 tCtx.ctx.SetBlockHeight(tCtx.ctx.BlockHeight() + 10) 981 // provide 982 provide(t, tCtx, createPoolMsg) 983 984 tCtx.ctx.SetBlockHeight(tCtx.ctx.BlockHeight() + 4) 985 // lock 986 lock(t, tCtx, createPoolMsg) 987 988 createPoolMsg.Owner = tCtx.addrList[0] 989 lock(t, tCtx, createPoolMsg) 990 991 createPoolMsg.Owner = tCtx.addrList[1] 992 lock(t, tCtx, createPoolMsg) 993 994 createPoolMsg.Owner = tCtx.addrList[2] 995 lock(t, tCtx, createPoolMsg) 996 997 createPoolMsg.Owner = tCtx.addrList[3] 998 lock(t, tCtx, createPoolMsg) 999 1000 tCtx.ctx.SetBlockHeight(tCtx.ctx.BlockHeight() + 4) 1001 1002 createPoolMsg.Owner = tCtx.addrList[4] 1003 lock(t, tCtx, createPoolMsg) 1004 1005 createPoolMsg.Owner = tCtx.addrList[5] 1006 lock(t, tCtx, createPoolMsg) 1007 1008 tCtx.ctx.SetBlockHeight(tCtx.ctx.BlockHeight() + 4) 1009 1010 createPoolMsg.Owner = tCtx.addrList[6] 1011 lock(t, tCtx, createPoolMsg) 1012 1013 createPoolMsg.Owner = tCtx.addrList[7] 1014 lock(t, tCtx, createPoolMsg) 1015 1016 createPoolMsg.Owner = tCtx.addrList[1] 1017 lock(t, tCtx, createPoolMsg) 1018 1019 createPoolMsg.Owner = tCtx.addrList[1] 1020 lock(t, tCtx, createPoolMsg) 1021 1022 createPoolMsg.Owner = tCtx.addrList[1] 1023 lock(t, tCtx, createPoolMsg) 1024 1025 createPoolMsg.Owner = tCtx.addrList[1] 1026 lock(t, tCtx, createPoolMsg) 1027 1028 //curPeriodRewards := tCtx.k.GetPoolCurrentRewards(tCtx.ctx, createPoolMsg.PoolName) 1029 //var period uint64 1030 //for period = 0;period < curPeriodRewards.Period;period++ { 1031 // historyPeriodRewards := tCtx.k.GetPoolHistoricalRewards(tCtx.ctx, createPoolMsg.PoolName, period) 1032 // fmt.Println("period:", period) 1033 // fmt.Println(string(types.ModuleCdc.MustMarshalJSON(historyPeriodRewards))) 1034 //} 1035 tCtx.k.IterateAllLockInfos(tCtx.ctx, func(lockInfo types.LockInfo) (stop bool) { 1036 return false 1037 }) 1038 1039 } 1040 1041 func TestHandlerMultiLockAtOneBlockHeight2(t *testing.T) { 1042 tCtx := initEnvironment(t) 1043 1044 // create pool 1045 createPoolMsg := createPool(t, tCtx) 1046 1047 tCtx.ctx.SetBlockHeight(tCtx.ctx.BlockHeight() + 10) 1048 // provide 1049 provide(t, tCtx, createPoolMsg) 1050 1051 tCtx.ctx.SetBlockHeight(tCtx.ctx.BlockHeight() + 4) 1052 // lock 1053 lock(t, tCtx, createPoolMsg) 1054 1055 createPoolMsg.Owner = tCtx.addrList[0] 1056 lock(t, tCtx, createPoolMsg) 1057 1058 createPoolMsg.Owner = tCtx.addrList[0] 1059 lock(t, tCtx, createPoolMsg) 1060 1061 createPoolMsg.Owner = tCtx.addrList[0] 1062 lock(t, tCtx, createPoolMsg) 1063 1064 createPoolMsg.Owner = tCtx.addrList[0] 1065 lock(t, tCtx, createPoolMsg) 1066 1067 tCtx.ctx.SetBlockHeight(tCtx.ctx.BlockHeight() + 4) 1068 1069 createPoolMsg.Owner = tCtx.addrList[0] 1070 lock(t, tCtx, createPoolMsg) 1071 1072 createPoolMsg.Owner = tCtx.addrList[0] 1073 lock(t, tCtx, createPoolMsg) 1074 1075 tCtx.ctx.SetBlockHeight(tCtx.ctx.BlockHeight() + 4) 1076 1077 createPoolMsg.Owner = tCtx.addrList[0] 1078 lock(t, tCtx, createPoolMsg) 1079 1080 createPoolMsg.Owner = tCtx.addrList[0] 1081 lock(t, tCtx, createPoolMsg) 1082 1083 createPoolMsg.Owner = tCtx.addrList[0] 1084 lock(t, tCtx, createPoolMsg) 1085 1086 createPoolMsg.Owner = tCtx.addrList[0] 1087 lock(t, tCtx, createPoolMsg) 1088 1089 createPoolMsg.Owner = tCtx.addrList[0] 1090 lock(t, tCtx, createPoolMsg) 1091 1092 createPoolMsg.Owner = tCtx.addrList[0] 1093 lock(t, tCtx, createPoolMsg) 1094 1095 //curPeriodRewards := tCtx.k.GetPoolCurrentRewards(tCtx.ctx, createPoolMsg.PoolName) 1096 //var period uint64 1097 //for period = 0;period < curPeriodRewards.Period;period++ { 1098 // historyPeriodRewards := tCtx.k.GetPoolHistoricalRewards(tCtx.ctx, createPoolMsg.PoolName, period) 1099 // fmt.Println("period:", period) 1100 // fmt.Println(string(types.ModuleCdc.MustMarshalJSON(historyPeriodRewards))) 1101 //} 1102 tCtx.k.IterateAllLockInfos(tCtx.ctx, func(lockInfo types.LockInfo) (stop bool) { 1103 return false 1104 }) 1105 1106 } 1107 1108 func TestHandlerMultiLockAndUnlock(t *testing.T) { 1109 tCtx := initEnvironment(t) 1110 1111 // create pool 1112 createPoolMsg := createPool(t, tCtx) 1113 1114 tCtx.ctx.SetBlockHeight(tCtx.ctx.BlockHeight() + 10) 1115 // provide 1116 provide(t, tCtx, createPoolMsg) 1117 1118 tCtx.ctx.SetBlockHeight(tCtx.ctx.BlockHeight() + 4) 1119 // lock 1120 lock(t, tCtx, createPoolMsg) 1121 1122 createPoolMsg.Owner = tCtx.addrList[1] 1123 lock(t, tCtx, createPoolMsg) 1124 1125 createPoolMsg.Owner = tCtx.addrList[2] 1126 lock(t, tCtx, createPoolMsg) 1127 1128 createPoolMsg.Owner = tCtx.addrList[3] 1129 lock(t, tCtx, createPoolMsg) 1130 1131 createPoolMsg.Owner = tCtx.addrList[4] 1132 lock(t, tCtx, createPoolMsg) 1133 1134 tCtx.ctx.SetBlockHeight(tCtx.ctx.BlockHeight() + 4) 1135 1136 createPoolMsg.Owner = tCtx.tokenOwner 1137 unlock(t, tCtx, createPoolMsg) 1138 1139 createPoolMsg.Owner = tCtx.addrList[1] 1140 unlock(t, tCtx, createPoolMsg) 1141 1142 createPoolMsg.Owner = tCtx.addrList[2] 1143 unlock(t, tCtx, createPoolMsg) 1144 1145 createPoolMsg.Owner = tCtx.addrList[3] 1146 unlock(t, tCtx, createPoolMsg) 1147 1148 createPoolMsg.Owner = tCtx.addrList[4] 1149 unlock(t, tCtx, createPoolMsg) 1150 1151 //curPeriodRewards := tCtx.k.GetPoolCurrentRewards(tCtx.ctx, createPoolMsg.PoolName) 1152 numHistoricalRewards := 0 1153 tCtx.k.IteratePoolHistoricalRewards(tCtx.ctx, createPoolMsg.PoolName, 1154 func(store sdk.KVStore, key []byte, value []byte) (stop bool) { 1155 var rewards types.PoolHistoricalRewards 1156 types.ModuleCdc.MustUnmarshalBinaryLengthPrefixed(value, &rewards) 1157 numHistoricalRewards++ 1158 return false 1159 }) 1160 require.Equal(t, 1, numHistoricalRewards) 1161 numLockInfo := 0 1162 tCtx.k.IterateAllLockInfos(tCtx.ctx, func(lockInfo types.LockInfo) (stop bool) { 1163 numLockInfo++ 1164 return false 1165 }) 1166 require.Equal(t, 0, numLockInfo) 1167 } 1168 1169 func TestHandlerRandom(t *testing.T) { 1170 tCtx := initEnvironment(t) 1171 1172 // create pool 1173 createPoolMsg := createPool(t, tCtx) 1174 for i := 0; i < 10000; i++ { 1175 var msg sdk.Msg 1176 judge := rand.Intn(5) 1177 switch judge { 1178 case 0: 1179 msg = normalGetProvideMsg(tCtx, createPoolMsg) 1180 case 1: 1181 msg = normalGetCreatePoolMsg(tCtx, createPoolMsg) 1182 case 2: 1183 msg = normalGetLockMsg(tCtx, createPoolMsg) 1184 case 3: 1185 msg = normalGetUnlockMsg(tCtx, createPoolMsg) 1186 case 4: 1187 msg = normalGetClaimMsg(tCtx, createPoolMsg) 1188 case 5: 1189 msg = normalGetDestroyPoolMsg(tCtx, createPoolMsg) 1190 } 1191 ctx, writeCache := tCtx.ctx.CacheContext() 1192 _, err := tCtx.handler(ctx, msg) 1193 if err != nil { 1194 //fmt.Println(err.Error()) 1195 } else { 1196 writeCache() 1197 } 1198 tCtx.ctx.SetBlockHeight(tCtx.ctx.BlockHeight() + int64(rand.Intn(2))) 1199 } 1200 } 1201 1202 func TestHandlerCheckCombination(t *testing.T) { 1203 var preExec preExecFunc = func(t *testing.T, tCtx *testContext) interface{} { 1204 return normalGetCreatePoolMsg(tCtx, nil) 1205 } 1206 tests := []testCaseItem{ 1207 { 1208 caseName: "success. create pool", 1209 preExec: preExec, 1210 getMsg: normalGetCreatePoolMsg, 1211 verification: verification, 1212 expectedErr: nil, 1213 }, 1214 { 1215 caseName: "success. provide", 1216 preExec: func(t *testing.T, tCtx *testContext) interface{} { 1217 tCtx.ctx.SetBlockHeight(tCtx.ctx.BlockHeight() + 1) 1218 return normalGetCreatePoolMsg(tCtx, nil) 1219 }, 1220 getMsg: normalGetProvideMsg, 1221 verification: verification, 1222 expectedErr: nil, 1223 }, 1224 { 1225 caseName: "success. lock address 1", 1226 preExec: func(t *testing.T, tCtx *testContext) interface{} { 1227 tCtx.ctx.SetBlockHeight(tCtx.ctx.BlockHeight() + 1) 1228 return normalGetCreatePoolMsg(tCtx, nil) 1229 }, 1230 getMsg: normalGetLockMsg, 1231 verification: verification, 1232 expectedErr: nil, 1233 }, 1234 { 1235 caseName: "success. lock address 2", 1236 preExec: func(t *testing.T, tCtx *testContext) interface{} { 1237 tCtx.ctx.SetBlockHeight(tCtx.ctx.BlockHeight() + 1) 1238 createPoolMsg := normalGetCreatePoolMsg(tCtx, nil).(types.MsgCreatePool) 1239 createPoolMsg.Owner = tCtx.addrList[0] 1240 return createPoolMsg 1241 }, 1242 getMsg: normalGetLockMsg, 1243 verification: verification, 1244 expectedErr: nil, 1245 }, 1246 { 1247 caseName: "success. claim address 1", 1248 preExec: preExec, 1249 getMsg: normalGetClaimMsg, 1250 verification: verification, 1251 expectedErr: nil, 1252 }, 1253 { 1254 caseName: "success. unlock address 1", 1255 preExec: func(t *testing.T, tCtx *testContext) interface{} { 1256 tCtx.ctx.SetBlockHeight(tCtx.ctx.BlockHeight() + 1) 1257 return normalGetCreatePoolMsg(tCtx, nil) 1258 }, 1259 getMsg: normalGetUnlockMsg, 1260 verification: func(t *testing.T, tCtx *testContext, err sdk.Error, testCase testCaseItem, preCoins, afterCoins sdk.SysCoins, preData interface{}) { 1261 verification(t, tCtx, err, testCase, preCoins, afterCoins, preData) 1262 createPoolMsg := preData.(types.MsgCreatePool) 1263 1264 // check current rewards 1265 curPeriodRewards := tCtx.k.GetPoolCurrentRewards(tCtx.ctx, createPoolMsg.PoolName) 1266 var expectedCurrentPeriod uint64 = 6 1267 require.Equal(t, expectedCurrentPeriod, curPeriodRewards.Period) 1268 require.Equal(t, tCtx.ctx.BlockHeight(), curPeriodRewards.StartBlockHeight) 1269 1270 // check the number of historicalRewards 1271 numHistoricalRewards := 0 1272 tCtx.k.IteratePoolHistoricalRewards(tCtx.ctx, createPoolMsg.PoolName, 1273 func(store sdk.KVStore, key []byte, value []byte) (stop bool) { 1274 var rewards types.PoolHistoricalRewards 1275 types.ModuleCdc.MustUnmarshalBinaryLengthPrefixed(value, &rewards) 1276 numHistoricalRewards++ 1277 return false 1278 }) 1279 require.Equal(t, 2, numHistoricalRewards) 1280 1281 // check the number of lockInfo 1282 numLockInfo := 0 1283 tCtx.k.IterateAllLockInfos(tCtx.ctx, func(lockInfo types.LockInfo) (stop bool) { 1284 numLockInfo++ 1285 return false 1286 }) 1287 require.Equal(t, int(1), numLockInfo) 1288 1289 // check historical rewards of period 3 1290 expectedRatio := sdk.NewDecCoinsFromDec(createPoolMsg.YieldedSymbol, sdk.NewDec(1)) 1291 rewards := tCtx.k.GetPoolHistoricalRewards(tCtx.ctx, createPoolMsg.PoolName, 3) 1292 require.Equal(t, uint16(1), rewards.ReferenceCount) 1293 require.Equal(t, expectedRatio.String(), rewards.CumulativeRewardRatio.String()) 1294 1295 // check historical rewards of period 5 1296 expectedRatio = sdk.NewDecCoinsFromDec(createPoolMsg.YieldedSymbol, sdk.NewDecWithPrec(15, 1)) 1297 rewards = tCtx.k.GetPoolHistoricalRewards(tCtx.ctx, createPoolMsg.PoolName, 5) 1298 require.Equal(t, uint16(1), rewards.ReferenceCount) 1299 require.Equal(t, expectedRatio.String(), rewards.CumulativeRewardRatio.String()) 1300 1301 // check farm pool 1302 pool, found := tCtx.k.GetFarmPool(tCtx.ctx, createPoolMsg.PoolName) 1303 params := tCtx.k.GetParams(tCtx.ctx) 1304 require.True(t, found) 1305 require.Equal(t, params.CreatePoolDeposit.String(), pool.DepositAmount.String()) 1306 expectedLockedValue := sdk.NewDecCoinFromDec(createPoolMsg.MinLockAmount.Denom, sdk.NewDec(1)) 1307 require.Equal(t, expectedLockedValue.String(), pool.TotalValueLocked.String()) 1308 require.Equal(t, 1, len(pool.YieldedTokenInfos)) 1309 expectedRemainingAmount := sdk.NewDecCoinFromDec(createPoolMsg.YieldedSymbol, sdk.NewDec(8)) 1310 require.Equal(t, expectedRemainingAmount.String(), pool.YieldedTokenInfos[0].RemainingAmount.String()) 1311 expectedTotalAccumulatedRewards := sdk.NewDecCoinsFromDec(createPoolMsg.YieldedSymbol, sdk.NewDecWithPrec(5, 1)) 1312 require.Equal(t, expectedTotalAccumulatedRewards.String(), pool.TotalAccumulatedRewards.String()) 1313 1314 }, 1315 expectedErr: nil, 1316 }, 1317 } 1318 1319 testCaseCombinationTest(t, tests) 1320 1321 }