mirror of
https://github.com/0glabs/0g-chain.git
synced 2024-12-23 23:05:18 +00:00
Update reward vesting length calculation (#624)
* use remaining length when sending coins to vesting account * query claims that have corresponding claim periods * cleanup comments * remove debugging statements * fix bug with inserting period in middle of vesting schedule * apply review suggestion
This commit is contained in:
parent
fca16da84a
commit
c0006ca8eb
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user