github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/x/farm/keeper/calc_test.go (about) 1 //go:build ignore 2 // +build ignore 3 4 package keeper 5 6 import ( 7 "testing" 8 9 sdk "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types" 10 "github.com/fibonacci-chain/fbc/x/farm/types" 11 "github.com/stretchr/testify/require" 12 ) 13 14 func TestCalculateAmountYieldedBetween(t *testing.T) { 15 ctx, keeper := GetKeeper(t) 16 poolName := "poolName" 17 type testCase struct { 18 curRewards types.PoolCurrentRewards 19 endBlockHeight int64 20 yieldedInfos types.YieldedTokenInfos 21 expectedFunc func(testCase, func() (types.FarmPool, sdk.SysCoins)) 22 } 23 24 expectSuccess := func(test testCase, testFunc func() (types.FarmPool, sdk.SysCoins)) { 25 pool, yieldedTokens := testFunc() 26 oldRemaining := test.yieldedInfos[0].RemainingAmount 27 newRemaining := pool.YieldedTokenInfos[0].RemainingAmount 28 require.Equal(t, yieldedTokens, sdk.SysCoins{oldRemaining.Sub(newRemaining)}) 29 } 30 31 expectNotYield := func(test testCase, testFunc func() (types.FarmPool, sdk.SysCoins)) { 32 pool, yieldedTokens := testFunc() 33 require.True(t, yieldedTokens.IsZero()) 34 require.Equal(t, test.yieldedInfos, pool.YieldedTokenInfos) 35 } 36 37 tests := []testCase{ 38 { 39 curRewards: types.NewPoolCurrentRewards(100, 1, sdk.SysCoins{}), 40 endBlockHeight: 120, 41 yieldedInfos: types.YieldedTokenInfos{ 42 types.NewYieldedTokenInfo( 43 sdk.NewDecCoin("xxb", sdk.ZeroInt()), 44 0, 45 sdk.NewDec(0), 46 ), 47 }, 48 expectedFunc: expectNotYield, 49 }, 50 { 51 curRewards: types.NewPoolCurrentRewards(60, 1, sdk.SysCoins{}), 52 endBlockHeight: 100, 53 yieldedInfos: types.YieldedTokenInfos{ 54 types.NewYieldedTokenInfo( 55 sdk.NewDecCoin("xxb", sdk.NewInt(1000)), 56 100, 57 sdk.NewDec(10), 58 ), 59 }, 60 expectedFunc: expectNotYield, 61 }, 62 { 63 curRewards: types.NewPoolCurrentRewards(120, 1, sdk.SysCoins{}), 64 endBlockHeight: 100, 65 yieldedInfos: types.YieldedTokenInfos{ 66 types.NewYieldedTokenInfo( 67 sdk.NewDecCoin("xxb", sdk.NewInt(1000)), 68 70, 69 sdk.NewDec(10), 70 ), 71 }, 72 expectedFunc: expectNotYield, 73 }, 74 { 75 curRewards: types.NewPoolCurrentRewards(60, 1, sdk.SysCoins{}), 76 endBlockHeight: 100, 77 yieldedInfos: types.YieldedTokenInfos{ 78 types.NewYieldedTokenInfo( 79 sdk.NewDecCoin("xxb", sdk.NewInt(1000)), 80 70, 81 sdk.NewDec(10), 82 ), 83 }, 84 expectedFunc: expectSuccess, 85 }, 86 { 87 curRewards: types.NewPoolCurrentRewards(70, 1, sdk.SysCoins{}), 88 endBlockHeight: 100, 89 yieldedInfos: types.YieldedTokenInfos{ 90 types.NewYieldedTokenInfo( 91 sdk.NewDecCoin("xxb", sdk.NewInt(100)), 92 60, 93 sdk.NewDec(10), 94 ), 95 }, 96 expectedFunc: expectSuccess, 97 }, 98 } 99 100 for _, test := range tests { 101 ctx.SetBlockHeight(test.endBlockHeight) 102 keeper.SetPoolCurrentRewards(ctx, poolName, test.curRewards) 103 pool := types.FarmPool{ 104 Name: poolName, 105 YieldedTokenInfos: types.YieldedTokenInfos{test.yieldedInfos[0]}, 106 } 107 wrappedTestFunc := func() (types.FarmPool, sdk.SysCoins) { 108 return keeper.CalculateAmountYieldedBetween(ctx, pool) 109 } 110 test.expectedFunc(test, wrappedTestFunc) 111 } 112 } 113 114 func TestIncrementReferenceCount(t *testing.T) { 115 ctx, keeper := GetKeeper(t) 116 poolName := "poolName" 117 118 expectSuccess := func(testFunc func()) { 119 testFunc() 120 } 121 122 expectPanic := func(testFunc func()) { 123 require.Panics(t, testFunc) 124 } 125 126 tests := []struct { 127 period uint64 128 referenceCount uint16 129 expectedFunc func(func()) 130 }{ 131 {0, 0, expectSuccess}, 132 {1, 1, expectSuccess}, 133 {2, 2, expectSuccess}, 134 {0, 3, expectPanic}, 135 } 136 137 for _, test := range tests { 138 his := types.NewPoolHistoricalRewards(sdk.SysCoins{}, test.referenceCount) 139 keeper.SetPoolHistoricalRewards(ctx, poolName, test.period, his) 140 wrappedTestFunc := func() { 141 keeper.incrementReferenceCount(ctx, poolName, test.period) 142 newHis := keeper.GetPoolHistoricalRewards(ctx, poolName, test.period) 143 require.Equal(t, test.referenceCount+1, newHis.ReferenceCount) 144 } 145 test.expectedFunc(wrappedTestFunc) 146 } 147 } 148 149 func TestDecrementReferenceCount(t *testing.T) { 150 ctx, keeper := GetKeeper(t) 151 poolName := "poolName" 152 153 type testCase struct { 154 period uint64 155 referenceCount uint16 156 expectedFunc func(testCase, func()) 157 } 158 159 expectDeleted := func(test testCase, testFunc func()) { 160 testFunc() 161 require.Panics(t, func() { 162 keeper.GetPoolHistoricalRewards(ctx, poolName, test.period) 163 }) 164 } 165 166 expectSuccess := func(test testCase, testFunc func()) { 167 testFunc() 168 newHis := keeper.GetPoolHistoricalRewards(ctx, poolName, test.period) 169 require.Equal(t, test.referenceCount-1, newHis.ReferenceCount) 170 } 171 172 expectPanic := func(test testCase, testFunc func()) { 173 require.Panics(t, testFunc) 174 } 175 176 tests := []testCase{ 177 {0, 0, expectPanic}, 178 {1, 1, expectDeleted}, 179 {2, 2, expectSuccess}, 180 {0, 3, expectSuccess}, 181 } 182 183 for _, test := range tests { 184 his := types.NewPoolHistoricalRewards(sdk.SysCoins{}, test.referenceCount) 185 keeper.SetPoolHistoricalRewards(ctx, poolName, test.period, his) 186 wrappedTestFunc := func() { 187 keeper.decrementReferenceCount(ctx, poolName, test.period) 188 } 189 test.expectedFunc(test, wrappedTestFunc) 190 } 191 } 192 193 func TestCalculateLockRewardsBetween(t *testing.T) { 194 ctx, keeper := GetKeeper(t) 195 poolName := "poolName" 196 197 type testCase struct { 198 startPeriod uint64 199 startRatio sdk.SysCoins 200 endPeriod uint64 201 endRatio sdk.SysCoins 202 amount sdk.SysCoin 203 expectedFunc func(testCase, func() sdk.SysCoins) 204 } 205 206 expectSuccess := func(test testCase, testFunc func() sdk.SysCoins) { 207 rewards := testFunc() 208 require.Equal(t, rewards, test.endRatio.Sub(test.startRatio).MulDecTruncate(test.amount.Amount)) 209 } 210 211 expectPanic := func(test testCase, testFunc func() sdk.SysCoins) { 212 require.Panics(t, func() { 213 testFunc() 214 }) 215 } 216 217 tests := []testCase{ 218 { 219 startPeriod: 0, 220 startRatio: sdk.SysCoins{ 221 sdk.NewDecCoin("wwb", sdk.NewInt(10)), 222 sdk.NewDecCoin("fibo", sdk.NewInt(10)), 223 }, 224 endPeriod: 1, 225 endRatio: sdk.SysCoins{ 226 sdk.NewDecCoin("wwb", sdk.NewInt(10)), 227 sdk.NewDecCoin("fibo", sdk.NewInt(100)), 228 }, 229 amount: sdk.NewDecCoin("xxb", sdk.NewInt(10)), 230 expectedFunc: expectSuccess, 231 }, 232 { 233 startPeriod: 0, 234 startRatio: sdk.SysCoins{ 235 sdk.NewDecCoin("wwb", sdk.NewInt(10)), 236 sdk.NewDecCoin("fibo", sdk.NewInt(10)), 237 }, 238 endPeriod: 1, 239 endRatio: sdk.SysCoins{ 240 sdk.NewDecCoin("wwb", sdk.NewInt(10)), 241 sdk.NewDecCoin("fibo", sdk.NewInt(7)), 242 }, 243 amount: sdk.NewDecCoin("xxb", sdk.NewInt(10)), 244 expectedFunc: expectPanic, 245 }, 246 { 247 startPeriod: 0, 248 startRatio: sdk.SysCoins{ 249 sdk.NewDecCoin("wwb", sdk.NewInt(10)), 250 sdk.NewDecCoin("fibo", sdk.NewInt(10)), 251 }, 252 endPeriod: 1, 253 endRatio: sdk.SysCoins{ 254 sdk.NewDecCoin("wwb", sdk.NewInt(10)), 255 sdk.NewDecCoin("fibo", sdk.NewInt(100)), 256 }, 257 amount: sdk.SysCoin{"xxb", sdk.NewDec(-1)}, 258 expectedFunc: expectPanic, 259 }, 260 { 261 startPeriod: 1, 262 startRatio: sdk.SysCoins{ 263 sdk.NewDecCoin("wwb", sdk.NewInt(10)), 264 sdk.NewDecCoin("fibo", sdk.NewInt(10)), 265 }, 266 endPeriod: 0, 267 endRatio: sdk.SysCoins{ 268 sdk.NewDecCoin("wwb", sdk.NewInt(10)), 269 sdk.NewDecCoin("fibo", sdk.NewInt(100)), 270 }, 271 amount: sdk.NewDecCoin("xxb", sdk.NewInt(10)), 272 expectedFunc: expectPanic, 273 }, 274 } 275 276 for _, test := range tests { 277 startHis := types.NewPoolHistoricalRewards(test.startRatio, 1) 278 keeper.SetPoolHistoricalRewards(ctx, poolName, test.startPeriod, startHis) 279 endHis := types.NewPoolHistoricalRewards(test.endRatio, 1) 280 keeper.SetPoolHistoricalRewards(ctx, poolName, test.endPeriod, endHis) 281 282 wrappedTestFunc := func() sdk.SysCoins { 283 return keeper.calculateLockRewardsBetween(ctx, poolName, test.startPeriod, test.endPeriod, test.amount) 284 } 285 test.expectedFunc(test, wrappedTestFunc) 286 } 287 } 288 289 func TestIncrementPoolPeriod(t *testing.T) { 290 ctx, keeper := GetKeeper(t) 291 poolName := "poolName" 292 293 type testCase struct { 294 curRewards types.PoolCurrentRewards 295 preHisRewards types.PoolHistoricalRewards 296 valueLocked sdk.SysCoin 297 yieldedTokens sdk.SysCoins 298 expectedFunc func(testCase, func() uint64) 299 } 300 301 expectSuccess := func(test testCase, testFunc func() uint64) { 302 period := testFunc() 303 // previous historical rewards is deleted 304 require.Panics(t, func() { 305 keeper.GetPoolHistoricalRewards(ctx, poolName, test.curRewards.Period-1) 306 }) 307 // return the current period ended just now 308 require.Equal(t, test.curRewards.Period, period) 309 310 var currentRatio sdk.SysCoins 311 if test.valueLocked.IsZero() { 312 currentRatio = sdk.SysCoins{} 313 } else { 314 currentRatio = test.curRewards.Rewards.Add2(test.yieldedTokens).QuoDecTruncate(test.valueLocked.Amount) 315 } 316 317 // create new current period rewards 318 newHis := keeper.GetPoolHistoricalRewards(ctx, poolName, test.curRewards.Period) 319 require.Equal(t, test.preHisRewards.CumulativeRewardRatio.Add2(currentRatio), 320 newHis.CumulativeRewardRatio, 321 ) 322 323 newCurr := keeper.GetPoolCurrentRewards(ctx, poolName) 324 require.Equal( 325 t, 326 test.curRewards.Period+1, 327 newCurr.Period, 328 ) 329 } 330 331 tests := []testCase{ 332 { 333 curRewards: types.NewPoolCurrentRewards(100, 1, sdk.SysCoins{}), 334 preHisRewards: types.NewPoolHistoricalRewards( 335 sdk.SysCoins{sdk.NewDecCoinFromDec("xxb", sdk.NewDec(10))}, 1, 336 ), 337 valueLocked: sdk.NewDecCoinFromDec("wwb", sdk.NewDec(100)), 338 yieldedTokens: sdk.SysCoins{sdk.NewDecCoin("yyb", sdk.NewInt(100))}, 339 expectedFunc: expectSuccess, 340 }, 341 { 342 curRewards: types.NewPoolCurrentRewards(100, 1, sdk.SysCoins{}), 343 preHisRewards: types.NewPoolHistoricalRewards( 344 sdk.SysCoins{sdk.NewDecCoinFromDec("xxb", sdk.NewDec(10))}, 1, 345 ), 346 valueLocked: sdk.NewDecCoinFromDec("wwb", sdk.NewDec(0)), 347 yieldedTokens: sdk.SysCoins{sdk.NewDecCoin("yyb", sdk.NewInt(100))}, 348 expectedFunc: expectSuccess, 349 }, 350 } 351 352 for _, test := range tests { 353 keeper.SetPoolHistoricalRewards(ctx, poolName, test.curRewards.Period-1, test.preHisRewards) 354 keeper.SetPoolCurrentRewards(ctx, poolName, test.curRewards) 355 356 wrappedTestFunc := func() uint64 { 357 return keeper.IncrementPoolPeriod(ctx, poolName, test.valueLocked, test.yieldedTokens) 358 } 359 test.expectedFunc(test, wrappedTestFunc) 360 } 361 } 362 363 func TestUpdateLockInfo(t *testing.T) { 364 ctx, keeper := GetKeeper(t) 365 poolName := "poolName" 366 367 type testCase struct { 368 lockInfo types.LockInfo 369 changeAmount sdk.Dec 370 isSetLockInfo bool 371 expectedFunc func(testCase, func()) 372 } 373 374 expectPanic := func(test testCase, testFunc func()) { 375 require.Panics(t, func() { 376 testFunc() 377 }) 378 } 379 380 expectDelete := func(test testCase, testFunc func()) { 381 testFunc() 382 found := keeper.HasLockInfo(ctx, test.lockInfo.Owner, poolName) 383 require.False(t, found) 384 found = keeper.HasAddressInFarmPool(ctx, poolName, test.lockInfo.Owner) 385 require.False(t, found) 386 } 387 388 expectUpdate := func(test testCase, testFunc func()) { 389 testFunc() 390 lockInfo, found := keeper.GetLockInfo(ctx, test.lockInfo.Owner, poolName) 391 require.True(t, found) 392 require.Equal(t, lockInfo.Amount.Amount, test.lockInfo.Amount.Amount.Add(test.changeAmount)) 393 } 394 395 tests := []testCase{ 396 { 397 lockInfo: types.NewLockInfo( 398 Addrs[0], poolName, sdk.NewDecCoinFromDec("xxb", sdk.NewDec(10)), 399 100, 1, 400 ), 401 changeAmount: sdk.NewDec(0), 402 isSetLockInfo: false, 403 expectedFunc: expectPanic, 404 }, 405 { 406 lockInfo: types.NewLockInfo( 407 Addrs[0], poolName, sdk.NewDecCoinFromDec("xxb", sdk.NewDec(10)), 408 100, 1, 409 ), 410 changeAmount: sdk.NewDec(-10), 411 isSetLockInfo: true, 412 expectedFunc: expectDelete, 413 }, 414 { 415 lockInfo: types.NewLockInfo( 416 Addrs[0], poolName, sdk.NewDecCoinFromDec("xxb", sdk.NewDec(10)), 417 100, 1, 418 ), 419 changeAmount: sdk.NewDec(5), 420 isSetLockInfo: true, 421 expectedFunc: expectUpdate, 422 }, 423 } 424 425 for _, test := range tests { 426 keeper.SetPoolHistoricalRewards( 427 ctx, poolName, 1, 428 types.NewPoolHistoricalRewards(sdk.SysCoins{}, 1), 429 ) 430 keeper.SetPoolCurrentRewards( 431 ctx, poolName, types.NewPoolCurrentRewards(ctx.BlockHeight(), 2, sdk.SysCoins{}), 432 ) 433 if test.isSetLockInfo { 434 keeper.SetLockInfo(ctx, test.lockInfo) 435 } 436 wrappedTestFunc := func() { 437 keeper.UpdateLockInfo(ctx, test.lockInfo.Owner, poolName, test.changeAmount) 438 } 439 test.expectedFunc(test, wrappedTestFunc) 440 } 441 } 442 443 func TestWithdrawRewards(t *testing.T) { 444 ctx, keeper := GetKeeper(t) 445 poolName := "poolName" 446 447 type testCase struct { 448 lockInfo types.LockInfo 449 totalLocked sdk.SysCoin 450 yieldedAmount sdk.SysCoins 451 isSetLockInfo bool 452 isSetModuleAcc bool 453 expectedFunc func(testCase, func() (sdk.SysCoins, sdk.Error)) 454 } 455 456 expectError := func(test testCase, testFunc func() (sdk.SysCoins, sdk.Error)) { 457 rewards, err := testFunc() 458 require.Equal(t, sdk.SysCoins(nil), rewards) 459 require.NotNil(t, err) 460 } 461 462 expectSuccess := func(test testCase, testFunc func() (sdk.SysCoins, sdk.Error)) { 463 rewards, err := testFunc() 464 require.Equal( 465 t, 466 test.yieldedAmount.QuoDecTruncate(test.totalLocked.Amount).MulDecTruncate(test.lockInfo.Amount.Amount), 467 rewards, 468 ) 469 require.Nil(t, err) 470 require.Panics(t, func() { 471 keeper.GetPoolHistoricalRewards(ctx, poolName, test.lockInfo.ReferencePeriod) 472 }) 473 } 474 475 expectNoRewards := func(test testCase, testFunc func() (sdk.SysCoins, sdk.Error)) { 476 rewards, err := testFunc() 477 require.Equal(t, sdk.SysCoins(nil), rewards) 478 require.Nil(t, err) 479 require.Panics(t, func() { 480 keeper.GetPoolHistoricalRewards(ctx, poolName, test.lockInfo.ReferencePeriod) 481 }) 482 } 483 484 tests := []testCase{ 485 { 486 lockInfo: types.NewLockInfo( 487 Addrs[0], poolName, sdk.NewDecCoinFromDec("xxb", sdk.NewDec(10)), 488 100, 1, 489 ), 490 totalLocked: sdk.NewDecCoinFromDec("xxb", sdk.NewDec(100)), 491 yieldedAmount: sdk.NewDecCoinsFromDec("wwb", sdk.NewDec(100)), 492 isSetLockInfo: false, 493 isSetModuleAcc: false, 494 expectedFunc: expectError, 495 }, 496 { 497 lockInfo: types.NewLockInfo( 498 Addrs[0], poolName, sdk.NewDecCoinFromDec("xxb", sdk.NewDec(10)), 499 100, 1, 500 ), 501 totalLocked: sdk.NewDecCoinFromDec("xxb", sdk.NewDec(100)), 502 yieldedAmount: sdk.NewDecCoinsFromDec("wwb", sdk.NewDec(100)), 503 isSetLockInfo: true, 504 isSetModuleAcc: false, 505 expectedFunc: expectError, 506 }, 507 { 508 lockInfo: types.NewLockInfo( 509 Addrs[0], poolName, sdk.NewDecCoinFromDec("xxb", sdk.NewDec(10)), 510 100, 1, 511 ), 512 totalLocked: sdk.NewDecCoinFromDec("xxb", sdk.NewDec(100)), 513 yieldedAmount: sdk.NewDecCoinsFromDec("wwb", sdk.NewDec(100)), 514 isSetLockInfo: true, 515 isSetModuleAcc: true, 516 expectedFunc: expectSuccess, 517 }, 518 { 519 lockInfo: types.NewLockInfo( 520 Addrs[0], poolName, sdk.NewDecCoinFromDec("xxb", sdk.NewDec(10)), 521 120, 1, 522 ), 523 totalLocked: sdk.NewDecCoinFromDec("xxb", sdk.NewDec(100)), 524 yieldedAmount: sdk.NewDecCoinsFromDec("wwb", sdk.NewDec(100)), 525 isSetLockInfo: true, 526 isSetModuleAcc: true, 527 expectedFunc: expectNoRewards, 528 }, 529 } 530 531 for _, test := range tests { 532 ctx.SetBlockHeight(120) 533 keeper.SetPoolHistoricalRewards( 534 ctx, poolName, 1, 535 types.NewPoolHistoricalRewards(sdk.SysCoins{}, 2), 536 ) 537 keeper.SetPoolCurrentRewards( 538 ctx, poolName, types.NewPoolCurrentRewards(ctx.BlockHeight(), 2, sdk.SysCoins{}), 539 ) 540 if test.isSetLockInfo { 541 keeper.SetLockInfo(ctx, test.lockInfo) 542 } 543 if test.isSetModuleAcc { 544 yieldModuleAcc := keeper.supplyKeeper.GetModuleAccount(ctx, types.YieldFarmingAccount) 545 err := yieldModuleAcc.SetCoins( 546 test.yieldedAmount.MulDecTruncate(test.totalLocked.Amount).MulDecTruncate(test.lockInfo.Amount.Amount), 547 ) 548 require.Nil(t, err) 549 keeper.supplyKeeper.SetModuleAccount(ctx, yieldModuleAcc) 550 } 551 wrappedTestFunc := func() (sdk.SysCoins, sdk.Error) { 552 return keeper.WithdrawRewards(ctx, poolName, test.totalLocked, test.yieldedAmount, test.lockInfo.Owner) 553 } 554 test.expectedFunc(test, wrappedTestFunc) 555 } 556 }