diff --git a/x/incentive/keeper/payout.go b/x/incentive/keeper/payout.go index 50794520..94624274 100644 --- a/x/incentive/keeper/payout.go +++ b/x/incentive/keeper/payout.go @@ -1,6 +1,8 @@ package keeper import ( + "fmt" + sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/x/auth" @@ -34,6 +36,7 @@ func (k Keeper) PayoutClaim(ctx sdk.Context, addr sdk.AccAddress, collateralType types.EventTypeClaim, sdk.NewAttribute(types.AttributeKeyClaimedBy, addr.String()), sdk.NewAttribute(types.AttributeKeyClaimAmount, claim.Reward.String()), + sdk.NewAttribute(types.AttributeKeyClaimPeriod, fmt.Sprintf("%d", claim.ClaimPeriodID)), ), ) return nil @@ -141,16 +144,22 @@ func (k Keeper) addCoinsToVestingSchedule(ctx sdk.Context, addr sdk.AccAddress, // Add the new vesting coins to OriginalVesting vacc.OriginalVesting = vacc.OriginalVesting.Add(amt...) // update vesting periods + // EndTime = 100 + // BlockTime = 110 + // length == 6 if vacc.EndTime < ctx.BlockTime().Unix() { // edge case one - the vesting account's end time is in the past (ie, all previous vesting periods have completed) // append a new period to the vesting account, update the end time, update the account in the store and return - newPeriodLength := (ctx.BlockTime().Unix() - vacc.EndTime) + length + newPeriodLength := (ctx.BlockTime().Unix() - vacc.EndTime) + length // 110 - 100 + 6 = 16 newPeriod := types.NewPeriod(amt, newPeriodLength) vacc.VestingPeriods = append(vacc.VestingPeriods, newPeriod) vacc.EndTime = ctx.BlockTime().Unix() + length k.accountKeeper.SetAccount(ctx, vacc) return } + // StartTime = 110 + // BlockTime = 100 + // length = 6 if vacc.StartTime > ctx.BlockTime().Unix() { // edge case two - the vesting account's start time is in the future (all periods have not started) // update the start time to now and adjust the period lengths in place - a new period will be inserted in the next code block @@ -158,7 +167,7 @@ func (k Keeper) addCoinsToVestingSchedule(ctx sdk.Context, addr sdk.AccAddress, for i, period := range vacc.VestingPeriods { updatedPeriod := period if i == 0 { - updatedPeriod = types.NewPeriod(period.Amount, (vacc.StartTime-ctx.BlockTime().Unix())+period.Length) + updatedPeriod = types.NewPeriod(period.Amount, (vacc.StartTime-ctx.BlockTime().Unix())+period.Length) // 110 - 100 + 6 = 16 } updatedPeriods = append(updatedPeriods, updatedPeriod) } @@ -167,11 +176,12 @@ func (k Keeper) addCoinsToVestingSchedule(ctx sdk.Context, addr sdk.AccAddress, } // logic for inserting a new vesting period into the existing vesting schedule - totalPeriodLength := types.GetTotalVestingPeriodLength(vacc.VestingPeriods) + remainingLength := vacc.EndTime - ctx.BlockTime().Unix() + elapsedTime := ctx.BlockTime().Unix() - vacc.StartTime proposedEndTime := ctx.BlockTime().Unix() + length - if totalPeriodLength < length { - // in the case that the proposed length is longer than the sum of all previous period lengths, create a new period with length equal to the difference between the proposed length and the previous total length - newPeriodLength := length - totalPeriodLength + if remainingLength < length { + // in the case that the proposed length is longer than the remaining length of all vesting periods, create a new period with length equal to the difference between the proposed length and the previous total length + newPeriodLength := length - remainingLength newPeriod := types.NewPeriod(amt, newPeriodLength) vacc.VestingPeriods = append(vacc.VestingPeriods, newPeriod) // update the end time so that the sum of all period lengths equals endTime - startTime @@ -184,6 +194,19 @@ func (k Keeper) addCoinsToVestingSchedule(ctx sdk.Context, addr sdk.AccAddress, // Expected result: // {[l: 1, a: 1], [l:2, a: 1], [l:2, a:x], [l:6, a:3], [l:5, a:3]} + // StartTime = 100 + // Periods = [5,5,5,5] + // EndTime = 120 + // BlockTime = 101 + // length = 2 + + // for period in Periods: + // iteration 1: + // lengthCounter = 5 + // if 5 < 101 - 100 + 2 - no + // if 5 = 3 - no + // else + // newperiod = 2 - 0 newPeriods := vesting.Periods{} lengthCounter := int64(0) appendRemaining := false @@ -193,14 +216,14 @@ func (k Keeper) addCoinsToVestingSchedule(ctx sdk.Context, addr sdk.AccAddress, continue } lengthCounter += period.Length - if lengthCounter < length { + if lengthCounter < elapsedTime+length { // 1 newPeriods = append(newPeriods, period) - } else if lengthCounter == length { + } else if lengthCounter == elapsedTime+length { newPeriod := types.NewPeriod(period.Amount.Add(amt...), period.Length) newPeriods = append(newPeriods, newPeriod) appendRemaining = true } else { - newPeriod := types.NewPeriod(amt, length-types.GetTotalVestingPeriodLength(newPeriods)) + newPeriod := types.NewPeriod(amt, elapsedTime+length-types.GetTotalVestingPeriodLength(newPeriods)) previousPeriod := types.NewPeriod(period.Amount, period.Length-newPeriod.Length) newPeriods = append(newPeriods, newPeriod, previousPeriod) appendRemaining = true diff --git a/x/incentive/keeper/payout_test.go b/x/incentive/keeper/payout_test.go index cfdfa652..14e039df 100644 --- a/x/incentive/keeper/payout_test.go +++ b/x/incentive/keeper/payout_test.go @@ -2,6 +2,7 @@ package keeper_test import ( "errors" + "strings" "time" sdk "github.com/cosmos/cosmos-sdk/types" @@ -35,7 +36,7 @@ func (suite *KeeperTestSuite) setupChain() { ) supplyKeeper := tApp.GetSupplyKeeper() macc := supplyKeeper.GetModuleAccount(ctx, kavadist.ModuleName) - err := supplyKeeper.MintCoins(ctx, macc.GetName(), cs(c("ukava", 500))) + err := supplyKeeper.MintCoins(ctx, macc.GetName(), cs(c("ukava", 600))) suite.Require().NoError(err) // sets addrs[0] to be a periodic vesting account @@ -99,157 +100,290 @@ func (suite *KeeperTestSuite) setupExpiredClaims() { suite.addrs = addrs } -func (suite *KeeperTestSuite) TestSendCoinsToPeriodicVestingAccount() { - suite.setupChain() - - type args struct { - coins sdk.Coins - length int64 +func createPeriodicVestingAccount(origVesting sdk.Coins, periods vesting.Periods, startTime, endTime int64) (*vesting.PeriodicVestingAccount, error) { + _, addr := app.GeneratePrivKeyAddressPairs(1) + bacc := auth.NewBaseAccountWithAddress(addr[0]) + bacc.Coins = origVesting + bva, err := vesting.NewBaseVestingAccount(&bacc, origVesting, endTime) + if err != nil { + return &vesting.PeriodicVestingAccount{}, err } + pva := vesting.NewPeriodicVestingAccountRaw(bva, startTime, periods) + err = pva.Validate() + if err != nil { + return &vesting.PeriodicVestingAccount{}, err + } + return pva, nil +} +func (suite *KeeperTestSuite) TestSendCoinsToPeriodicVestingAccount() { + type accountArgs struct { + periods vesting.Periods + origVestingCoins sdk.Coins + startTime int64 + endTime int64 + } + type args struct { + accArgs accountArgs + period vesting.Period + ctxTime time.Time + mintModAccountCoins bool + expectedPeriods vesting.Periods + expectedStartTime int64 + expectedEndTime int64 + } type errArgs struct { expectErr bool - errType error + contains string } - - type vestingAccountTest struct { - name string - blockTime time.Time - args args - errArgs errArgs - expectedPeriods vesting.Periods - expectedOriginalVesting sdk.Coins - expectedCoins sdk.Coins - expectedStartTime int64 - expectedEndTime int64 + type testCase struct { + name string + args args + errArgs errArgs } + type testCases []testCase - type vestingAccountTests []vestingAccountTest - - testCases := vestingAccountTests{ - vestingAccountTest{ - name: "insert period into an existing vesting schedule", - blockTime: time.Unix(100, 0), - args: args{coins: cs(c("ukava", 100)), length: 5}, - errArgs: errArgs{expectErr: false, errType: nil}, - expectedPeriods: vesting.Periods{ - vesting.Period{Length: int64(1), Amount: cs(c("ukava", 100))}, - vesting.Period{Length: int64(2), Amount: cs(c("ukava", 100))}, - vesting.Period{Length: int64(2), Amount: cs(c("ukava", 100))}, - vesting.Period{Length: int64(6), Amount: cs(c("ukava", 100))}, - vesting.Period{Length: int64(5), Amount: cs(c("ukava", 100))}, + tests := testCases{ + { + name: "insert period at beginning schedule", + args: args{ + accArgs: accountArgs{ + periods: vesting.Periods{ + vesting.Period{Length: 5, Amount: cs(c("ukava", 5))}, + vesting.Period{Length: 5, Amount: cs(c("ukava", 5))}, + vesting.Period{Length: 5, Amount: cs(c("ukava", 5))}, + vesting.Period{Length: 5, Amount: cs(c("ukava", 5))}}, + origVestingCoins: cs(c("ukava", 20)), + startTime: 100, + endTime: 120, + }, + period: vesting.Period{Length: 2, Amount: cs(c("ukava", 6))}, + ctxTime: time.Unix(101, 0), + mintModAccountCoins: true, + expectedPeriods: vesting.Periods{ + vesting.Period{Length: 3, Amount: cs(c("ukava", 6))}, + vesting.Period{Length: 2, Amount: cs(c("ukava", 5))}, + vesting.Period{Length: 5, Amount: cs(c("ukava", 5))}, + vesting.Period{Length: 5, Amount: cs(c("ukava", 5))}, + vesting.Period{Length: 5, Amount: cs(c("ukava", 5))}}, + expectedStartTime: 100, + expectedEndTime: 120, }, - expectedOriginalVesting: cs(c("ukava", 500)), - expectedCoins: cs(c("ukava", 500)), - expectedStartTime: int64(100), - expectedEndTime: int64(116), - }, - vestingAccountTest{ - name: "append period to the end of an existing vesting schedule", - blockTime: time.Unix(100, 0), - args: args{coins: cs(c("ukava", 100)), length: 17}, - errArgs: errArgs{expectErr: false, errType: nil}, - expectedPeriods: vesting.Periods{ - vesting.Period{Length: int64(1), Amount: cs(c("ukava", 100))}, - vesting.Period{Length: int64(2), Amount: cs(c("ukava", 100))}, - vesting.Period{Length: int64(2), Amount: cs(c("ukava", 100))}, - vesting.Period{Length: int64(6), Amount: cs(c("ukava", 100))}, - vesting.Period{Length: int64(5), Amount: cs(c("ukava", 100))}, - vesting.Period{Length: int64(1), Amount: cs(c("ukava", 100))}, + errArgs: errArgs{ + expectErr: false, + contains: "", }, - expectedOriginalVesting: cs(c("ukava", 600)), - expectedCoins: cs(c("ukava", 600)), - expectedStartTime: int64(100), - expectedEndTime: int64(117), }, - vestingAccountTest{ - name: "append period to the end of a completed vesting schedule", - blockTime: time.Unix(120, 0), - args: args{coins: cs(c("ukava", 100)), length: 5}, - errArgs: errArgs{expectErr: false, errType: nil}, - expectedPeriods: vesting.Periods{ - vesting.Period{Length: int64(1), Amount: cs(c("ukava", 100))}, - vesting.Period{Length: int64(2), Amount: cs(c("ukava", 100))}, - vesting.Period{Length: int64(2), Amount: cs(c("ukava", 100))}, - vesting.Period{Length: int64(6), Amount: cs(c("ukava", 100))}, - vesting.Period{Length: int64(5), Amount: cs(c("ukava", 100))}, - vesting.Period{Length: int64(1), Amount: cs(c("ukava", 100))}, - vesting.Period{Length: int64(8), Amount: cs(c("ukava", 100))}, + { + name: "insert period at beginning with new start time", + args: args{ + accArgs: accountArgs{ + periods: vesting.Periods{ + vesting.Period{Length: 5, Amount: cs(c("ukava", 5))}, + vesting.Period{Length: 5, Amount: cs(c("ukava", 5))}, + vesting.Period{Length: 5, Amount: cs(c("ukava", 5))}, + vesting.Period{Length: 5, Amount: cs(c("ukava", 5))}}, + origVestingCoins: cs(c("ukava", 20)), + startTime: 100, + endTime: 120, + }, + period: vesting.Period{Length: 7, Amount: cs(c("ukava", 6))}, + ctxTime: time.Unix(80, 0), + mintModAccountCoins: true, + expectedPeriods: vesting.Periods{ + vesting.Period{Length: 7, Amount: cs(c("ukava", 6))}, + vesting.Period{Length: 18, Amount: cs(c("ukava", 5))}, + vesting.Period{Length: 5, Amount: cs(c("ukava", 5))}, + vesting.Period{Length: 5, Amount: cs(c("ukava", 5))}, + vesting.Period{Length: 5, Amount: cs(c("ukava", 5))}}, + expectedStartTime: 80, + expectedEndTime: 120, }, - expectedOriginalVesting: cs(c("ukava", 700)), - expectedCoins: cs(c("ukava", 700)), - expectedStartTime: int64(100), - expectedEndTime: int64(125), - }, - vestingAccountTest{ - name: "prepend period to to an upcoming vesting schedule", - blockTime: time.Unix(90, 0), - args: args{coins: cs(c("ukava", 100)), length: 5}, - errArgs: errArgs{expectErr: false, errType: nil}, - expectedPeriods: vesting.Periods{ - vesting.Period{Length: int64(5), Amount: cs(c("ukava", 100))}, - vesting.Period{Length: int64(6), Amount: cs(c("ukava", 100))}, - vesting.Period{Length: int64(2), Amount: cs(c("ukava", 100))}, - vesting.Period{Length: int64(2), Amount: cs(c("ukava", 100))}, - vesting.Period{Length: int64(6), Amount: cs(c("ukava", 100))}, - vesting.Period{Length: int64(5), Amount: cs(c("ukava", 100))}, - vesting.Period{Length: int64(1), Amount: cs(c("ukava", 100))}, - vesting.Period{Length: int64(8), Amount: cs(c("ukava", 100))}, + errArgs: errArgs{ + expectErr: false, + contains: "", }, - expectedOriginalVesting: cs(c("ukava", 800)), - expectedCoins: cs(c("ukava", 800)), - expectedStartTime: int64(90), - expectedEndTime: int64(125), }, - vestingAccountTest{ - name: "add period that coincides with an existing end time", - blockTime: time.Unix(90, 0), - args: args{coins: cs(c("ukava", 100)), length: 11}, - errArgs: errArgs{expectErr: false, errType: nil}, - expectedPeriods: vesting.Periods{ - vesting.Period{Length: int64(5), Amount: cs(c("ukava", 100))}, - vesting.Period{Length: int64(6), Amount: cs(c("ukava", 200))}, - vesting.Period{Length: int64(2), Amount: cs(c("ukava", 100))}, - vesting.Period{Length: int64(2), Amount: cs(c("ukava", 100))}, - vesting.Period{Length: int64(6), Amount: cs(c("ukava", 100))}, - vesting.Period{Length: int64(5), Amount: cs(c("ukava", 100))}, - vesting.Period{Length: int64(1), Amount: cs(c("ukava", 100))}, - vesting.Period{Length: int64(8), Amount: cs(c("ukava", 100))}, + { + name: "insert period in middle of schedule", + args: args{ + accArgs: accountArgs{ + periods: vesting.Periods{ + vesting.Period{Length: 5, Amount: cs(c("ukava", 5))}, + vesting.Period{Length: 5, Amount: cs(c("ukava", 5))}, + vesting.Period{Length: 5, Amount: cs(c("ukava", 5))}, + vesting.Period{Length: 5, Amount: cs(c("ukava", 5))}}, + origVestingCoins: cs(c("ukava", 20)), + startTime: 100, + endTime: 120, + }, + period: vesting.Period{Length: 7, Amount: cs(c("ukava", 6))}, + ctxTime: time.Unix(101, 0), + mintModAccountCoins: true, + expectedPeriods: vesting.Periods{ + vesting.Period{Length: 5, Amount: cs(c("ukava", 5))}, + vesting.Period{Length: 3, Amount: cs(c("ukava", 6))}, + vesting.Period{Length: 2, Amount: cs(c("ukava", 5))}, + vesting.Period{Length: 5, Amount: cs(c("ukava", 5))}, + vesting.Period{Length: 5, Amount: cs(c("ukava", 5))}}, + expectedStartTime: 100, + expectedEndTime: 120, + }, + errArgs: errArgs{ + expectErr: false, + contains: "", }, - expectedOriginalVesting: cs(c("ukava", 900)), - expectedCoins: cs(c("ukava", 900)), - expectedStartTime: int64(90), - expectedEndTime: int64(125), }, - vestingAccountTest{ - name: "insufficient module account balance", - blockTime: time.Unix(90, 0), - args: args{coins: cs(c("ukava", 1000)), length: 11}, - errArgs: errArgs{expectErr: true, errType: types.ErrInsufficientModAccountBalance}, - expectedPeriods: vesting.Periods{}, - expectedOriginalVesting: sdk.Coins{}, - expectedCoins: sdk.Coins{}, - expectedStartTime: int64(0), - expectedEndTime: int64(0), + { + name: "append to end of schedule", + args: args{ + accArgs: accountArgs{ + periods: vesting.Periods{ + vesting.Period{Length: 5, Amount: cs(c("ukava", 5))}, + vesting.Period{Length: 5, Amount: cs(c("ukava", 5))}, + vesting.Period{Length: 5, Amount: cs(c("ukava", 5))}, + vesting.Period{Length: 5, Amount: cs(c("ukava", 5))}}, + origVestingCoins: cs(c("ukava", 20)), + startTime: 100, + endTime: 120, + }, + period: vesting.Period{Length: 7, Amount: cs(c("ukava", 6))}, + ctxTime: time.Unix(125, 0), + mintModAccountCoins: true, + expectedPeriods: vesting.Periods{ + vesting.Period{Length: 5, Amount: cs(c("ukava", 5))}, + vesting.Period{Length: 5, Amount: cs(c("ukava", 5))}, + vesting.Period{Length: 5, Amount: cs(c("ukava", 5))}, + vesting.Period{Length: 5, Amount: cs(c("ukava", 5))}, + vesting.Period{Length: 12, Amount: cs(c("ukava", 6))}}, + expectedStartTime: 100, + expectedEndTime: 132, + }, + errArgs: errArgs{ + expectErr: false, + contains: "", + }, + }, + { + name: "add coins to existing period", + args: args{ + accArgs: accountArgs{ + periods: vesting.Periods{ + vesting.Period{Length: 5, Amount: cs(c("ukava", 5))}, + vesting.Period{Length: 5, Amount: cs(c("ukava", 5))}, + vesting.Period{Length: 5, Amount: cs(c("ukava", 5))}, + vesting.Period{Length: 5, Amount: cs(c("ukava", 5))}}, + origVestingCoins: cs(c("ukava", 20)), + startTime: 100, + endTime: 120, + }, + period: vesting.Period{Length: 5, Amount: cs(c("ukava", 6))}, + ctxTime: time.Unix(110, 0), + mintModAccountCoins: true, + expectedPeriods: vesting.Periods{ + vesting.Period{Length: 5, Amount: cs(c("ukava", 5))}, + vesting.Period{Length: 5, Amount: cs(c("ukava", 5))}, + vesting.Period{Length: 5, Amount: cs(c("ukava", 11))}, + vesting.Period{Length: 5, Amount: cs(c("ukava", 5))}}, + expectedStartTime: 100, + expectedEndTime: 120, + }, + errArgs: errArgs{ + expectErr: false, + contains: "", + }, + }, + { + name: "insufficient mod account balance", + args: args{ + accArgs: accountArgs{ + periods: vesting.Periods{ + vesting.Period{Length: 5, Amount: cs(c("ukava", 5))}, + vesting.Period{Length: 5, Amount: cs(c("ukava", 5))}, + vesting.Period{Length: 5, Amount: cs(c("ukava", 5))}, + vesting.Period{Length: 5, Amount: cs(c("ukava", 5))}}, + origVestingCoins: cs(c("ukava", 20)), + startTime: 100, + endTime: 120, + }, + period: vesting.Period{Length: 7, Amount: cs(c("ukava", 6))}, + ctxTime: time.Unix(125, 0), + mintModAccountCoins: false, + expectedPeriods: vesting.Periods{ + vesting.Period{Length: 5, Amount: cs(c("ukava", 5))}, + vesting.Period{Length: 5, Amount: cs(c("ukava", 5))}, + vesting.Period{Length: 5, Amount: cs(c("ukava", 5))}, + vesting.Period{Length: 5, Amount: cs(c("ukava", 5))}, + vesting.Period{Length: 12, Amount: cs(c("ukava", 6))}}, + expectedStartTime: 100, + expectedEndTime: 132, + }, + errArgs: errArgs{ + expectErr: true, + contains: "insufficient funds", + }, + }, + { + name: "add large period mid schedule", + args: args{ + accArgs: accountArgs{ + periods: vesting.Periods{ + vesting.Period{Length: 5, Amount: cs(c("ukava", 5))}, + vesting.Period{Length: 5, Amount: cs(c("ukava", 5))}, + vesting.Period{Length: 5, Amount: cs(c("ukava", 5))}, + vesting.Period{Length: 5, Amount: cs(c("ukava", 5))}}, + origVestingCoins: cs(c("ukava", 20)), + startTime: 100, + endTime: 120, + }, + period: vesting.Period{Length: 50, Amount: cs(c("ukava", 6))}, + ctxTime: time.Unix(110, 0), + mintModAccountCoins: true, + expectedPeriods: vesting.Periods{ + vesting.Period{Length: 5, Amount: cs(c("ukava", 5))}, + vesting.Period{Length: 5, Amount: cs(c("ukava", 5))}, + vesting.Period{Length: 5, Amount: cs(c("ukava", 5))}, + vesting.Period{Length: 5, Amount: cs(c("ukava", 5))}, + vesting.Period{Length: 40, Amount: cs(c("ukava", 6))}}, + expectedStartTime: 100, + expectedEndTime: 160, + }, + errArgs: errArgs{ + expectErr: false, + contains: "", + }, }, } - - for _, tc := range testCases { + for _, tc := range tests { suite.Run(tc.name, func() { - suite.ctx = suite.ctx.WithBlockTime(tc.blockTime) - err := suite.keeper.SendTimeLockedCoinsToAccount(suite.ctx, kavadist.ModuleName, suite.addrs[0], tc.args.coins, tc.args.length) + // create the periodic vesting account + pva, err := createPeriodicVestingAccount(tc.args.accArgs.origVestingCoins, tc.args.accArgs.periods, tc.args.accArgs.startTime, tc.args.accArgs.endTime) + suite.Require().NoError(err) + + // setup store state with account and kavadist module account + suite.ctx = suite.ctx.WithBlockTime(tc.args.ctxTime) + ak := suite.app.GetAccountKeeper() + ak.SetAccount(suite.ctx, pva) + // mint module account coins if required + if tc.args.mintModAccountCoins { + sk := suite.app.GetSupplyKeeper() + err = sk.MintCoins(suite.ctx, kavadist.ModuleName, tc.args.period.Amount) + suite.Require().NoError(err) + } + + err = suite.keeper.SendTimeLockedCoinsToPeriodicVestingAccount(suite.ctx, kavadist.ModuleName, pva.Address, tc.args.period.Amount, tc.args.period.Length) if tc.errArgs.expectErr { - suite.Require().True(errors.Is(err, tc.errArgs.errType)) + suite.Require().Error(err) + suite.Require().True(strings.Contains(err.Error(), tc.errArgs.contains)) } else { suite.Require().NoError(err) - acc := suite.getAccount(suite.addrs[0]) + + acc := suite.getAccount(pva.Address) vacc, ok := acc.(*vesting.PeriodicVestingAccount) - suite.True(ok) - suite.Equal(tc.expectedPeriods, vacc.VestingPeriods) - suite.Equal(tc.expectedOriginalVesting, vacc.OriginalVesting) - suite.Equal(tc.expectedCoins, vacc.Coins) - suite.Equal(tc.expectedStartTime, vacc.StartTime) - suite.Equal(tc.expectedEndTime, vacc.EndTime) + suite.Require().True(ok) + suite.Require().Equal(tc.args.expectedPeriods, vacc.VestingPeriods) + suite.Require().Equal(tc.args.expectedStartTime, vacc.StartTime) + suite.Require().Equal(tc.args.expectedEndTime, vacc.EndTime) } }) } @@ -300,7 +434,7 @@ func (suite *KeeperTestSuite) TestPayoutClaim() { suite.keeper.SetClaim(suite.ctx, c3) // existing claim with corresponding claim period successfully claimed by existing periodic vesting account - err := suite.keeper.PayoutClaim(suite.ctx, suite.addrs[0], "bnb", 1) + err := suite.keeper.PayoutClaim(suite.ctx.WithBlockTime(time.Unix(3700, 0)), suite.addrs[0], "bnb", 1) suite.Require().NoError(err) acc := suite.getAccount(suite.addrs[0]) // account is a periodic vesting account