mirror of
https://github.com/0glabs/0g-chain.git
synced 2024-12-26 00: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
|
package keeper
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
||||||
"github.com/cosmos/cosmos-sdk/x/auth"
|
"github.com/cosmos/cosmos-sdk/x/auth"
|
||||||
@ -34,6 +36,7 @@ func (k Keeper) PayoutClaim(ctx sdk.Context, addr sdk.AccAddress, collateralType
|
|||||||
types.EventTypeClaim,
|
types.EventTypeClaim,
|
||||||
sdk.NewAttribute(types.AttributeKeyClaimedBy, addr.String()),
|
sdk.NewAttribute(types.AttributeKeyClaimedBy, addr.String()),
|
||||||
sdk.NewAttribute(types.AttributeKeyClaimAmount, claim.Reward.String()),
|
sdk.NewAttribute(types.AttributeKeyClaimAmount, claim.Reward.String()),
|
||||||
|
sdk.NewAttribute(types.AttributeKeyClaimPeriod, fmt.Sprintf("%d", claim.ClaimPeriodID)),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
return nil
|
return nil
|
||||||
@ -141,16 +144,22 @@ func (k Keeper) addCoinsToVestingSchedule(ctx sdk.Context, addr sdk.AccAddress,
|
|||||||
// Add the new vesting coins to OriginalVesting
|
// Add the new vesting coins to OriginalVesting
|
||||||
vacc.OriginalVesting = vacc.OriginalVesting.Add(amt...)
|
vacc.OriginalVesting = vacc.OriginalVesting.Add(amt...)
|
||||||
// update vesting periods
|
// update vesting periods
|
||||||
|
// EndTime = 100
|
||||||
|
// BlockTime = 110
|
||||||
|
// length == 6
|
||||||
if vacc.EndTime < ctx.BlockTime().Unix() {
|
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)
|
// 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
|
// 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)
|
newPeriod := types.NewPeriod(amt, newPeriodLength)
|
||||||
vacc.VestingPeriods = append(vacc.VestingPeriods, newPeriod)
|
vacc.VestingPeriods = append(vacc.VestingPeriods, newPeriod)
|
||||||
vacc.EndTime = ctx.BlockTime().Unix() + length
|
vacc.EndTime = ctx.BlockTime().Unix() + length
|
||||||
k.accountKeeper.SetAccount(ctx, vacc)
|
k.accountKeeper.SetAccount(ctx, vacc)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
// StartTime = 110
|
||||||
|
// BlockTime = 100
|
||||||
|
// length = 6
|
||||||
if vacc.StartTime > ctx.BlockTime().Unix() {
|
if vacc.StartTime > ctx.BlockTime().Unix() {
|
||||||
// edge case two - the vesting account's start time is in the future (all periods have not started)
|
// 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
|
// 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 {
|
for i, period := range vacc.VestingPeriods {
|
||||||
updatedPeriod := period
|
updatedPeriod := period
|
||||||
if i == 0 {
|
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)
|
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
|
// 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
|
proposedEndTime := ctx.BlockTime().Unix() + length
|
||||||
if totalPeriodLength < length {
|
if remainingLength < 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
|
// 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 - totalPeriodLength
|
newPeriodLength := length - remainingLength
|
||||||
newPeriod := types.NewPeriod(amt, newPeriodLength)
|
newPeriod := types.NewPeriod(amt, newPeriodLength)
|
||||||
vacc.VestingPeriods = append(vacc.VestingPeriods, newPeriod)
|
vacc.VestingPeriods = append(vacc.VestingPeriods, newPeriod)
|
||||||
// update the end time so that the sum of all period lengths equals endTime - startTime
|
// 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:
|
// Expected result:
|
||||||
// {[l: 1, a: 1], [l:2, a: 1], [l:2, a:x], [l:6, a:3], [l:5, a:3]}
|
// {[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{}
|
newPeriods := vesting.Periods{}
|
||||||
lengthCounter := int64(0)
|
lengthCounter := int64(0)
|
||||||
appendRemaining := false
|
appendRemaining := false
|
||||||
@ -193,14 +216,14 @@ func (k Keeper) addCoinsToVestingSchedule(ctx sdk.Context, addr sdk.AccAddress,
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
lengthCounter += period.Length
|
lengthCounter += period.Length
|
||||||
if lengthCounter < length {
|
if lengthCounter < elapsedTime+length { // 1
|
||||||
newPeriods = append(newPeriods, period)
|
newPeriods = append(newPeriods, period)
|
||||||
} else if lengthCounter == length {
|
} else if lengthCounter == elapsedTime+length {
|
||||||
newPeriod := types.NewPeriod(period.Amount.Add(amt...), period.Length)
|
newPeriod := types.NewPeriod(period.Amount.Add(amt...), period.Length)
|
||||||
newPeriods = append(newPeriods, newPeriod)
|
newPeriods = append(newPeriods, newPeriod)
|
||||||
appendRemaining = true
|
appendRemaining = true
|
||||||
} else {
|
} 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)
|
previousPeriod := types.NewPeriod(period.Amount, period.Length-newPeriod.Length)
|
||||||
newPeriods = append(newPeriods, newPeriod, previousPeriod)
|
newPeriods = append(newPeriods, newPeriod, previousPeriod)
|
||||||
appendRemaining = true
|
appendRemaining = true
|
||||||
|
@ -2,6 +2,7 @@ package keeper_test
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
@ -35,7 +36,7 @@ func (suite *KeeperTestSuite) setupChain() {
|
|||||||
)
|
)
|
||||||
supplyKeeper := tApp.GetSupplyKeeper()
|
supplyKeeper := tApp.GetSupplyKeeper()
|
||||||
macc := supplyKeeper.GetModuleAccount(ctx, kavadist.ModuleName)
|
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)
|
suite.Require().NoError(err)
|
||||||
|
|
||||||
// sets addrs[0] to be a periodic vesting account
|
// sets addrs[0] to be a periodic vesting account
|
||||||
@ -99,157 +100,290 @@ func (suite *KeeperTestSuite) setupExpiredClaims() {
|
|||||||
suite.addrs = addrs
|
suite.addrs = addrs
|
||||||
}
|
}
|
||||||
|
|
||||||
func (suite *KeeperTestSuite) TestSendCoinsToPeriodicVestingAccount() {
|
func createPeriodicVestingAccount(origVesting sdk.Coins, periods vesting.Periods, startTime, endTime int64) (*vesting.PeriodicVestingAccount, error) {
|
||||||
suite.setupChain()
|
_, addr := app.GeneratePrivKeyAddressPairs(1)
|
||||||
|
bacc := auth.NewBaseAccountWithAddress(addr[0])
|
||||||
type args struct {
|
bacc.Coins = origVesting
|
||||||
coins sdk.Coins
|
bva, err := vesting.NewBaseVestingAccount(&bacc, origVesting, endTime)
|
||||||
length int64
|
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 {
|
type errArgs struct {
|
||||||
expectErr bool
|
expectErr bool
|
||||||
errType error
|
contains string
|
||||||
}
|
}
|
||||||
|
type testCase struct {
|
||||||
type vestingAccountTest struct {
|
name string
|
||||||
name string
|
args args
|
||||||
blockTime time.Time
|
errArgs errArgs
|
||||||
args args
|
|
||||||
errArgs errArgs
|
|
||||||
expectedPeriods vesting.Periods
|
|
||||||
expectedOriginalVesting sdk.Coins
|
|
||||||
expectedCoins sdk.Coins
|
|
||||||
expectedStartTime int64
|
|
||||||
expectedEndTime int64
|
|
||||||
}
|
}
|
||||||
|
type testCases []testCase
|
||||||
|
|
||||||
type vestingAccountTests []vestingAccountTest
|
tests := testCases{
|
||||||
|
{
|
||||||
testCases := vestingAccountTests{
|
name: "insert period at beginning schedule",
|
||||||
vestingAccountTest{
|
args: args{
|
||||||
name: "insert period into an existing vesting schedule",
|
accArgs: accountArgs{
|
||||||
blockTime: time.Unix(100, 0),
|
periods: vesting.Periods{
|
||||||
args: args{coins: cs(c("ukava", 100)), length: 5},
|
vesting.Period{Length: 5, Amount: cs(c("ukava", 5))},
|
||||||
errArgs: errArgs{expectErr: false, errType: nil},
|
vesting.Period{Length: 5, Amount: cs(c("ukava", 5))},
|
||||||
expectedPeriods: vesting.Periods{
|
vesting.Period{Length: 5, Amount: cs(c("ukava", 5))},
|
||||||
vesting.Period{Length: int64(1), Amount: cs(c("ukava", 100))},
|
vesting.Period{Length: 5, Amount: cs(c("ukava", 5))}},
|
||||||
vesting.Period{Length: int64(2), Amount: cs(c("ukava", 100))},
|
origVestingCoins: cs(c("ukava", 20)),
|
||||||
vesting.Period{Length: int64(2), Amount: cs(c("ukava", 100))},
|
startTime: 100,
|
||||||
vesting.Period{Length: int64(6), Amount: cs(c("ukava", 100))},
|
endTime: 120,
|
||||||
vesting.Period{Length: int64(5), Amount: cs(c("ukava", 100))},
|
},
|
||||||
|
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)),
|
errArgs: errArgs{
|
||||||
expectedCoins: cs(c("ukava", 500)),
|
expectErr: false,
|
||||||
expectedStartTime: int64(100),
|
contains: "",
|
||||||
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))},
|
|
||||||
},
|
},
|
||||||
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",
|
name: "insert period at beginning with new start time",
|
||||||
blockTime: time.Unix(120, 0),
|
args: args{
|
||||||
args: args{coins: cs(c("ukava", 100)), length: 5},
|
accArgs: accountArgs{
|
||||||
errArgs: errArgs{expectErr: false, errType: nil},
|
periods: vesting.Periods{
|
||||||
expectedPeriods: vesting.Periods{
|
vesting.Period{Length: 5, Amount: cs(c("ukava", 5))},
|
||||||
vesting.Period{Length: int64(1), Amount: cs(c("ukava", 100))},
|
vesting.Period{Length: 5, Amount: cs(c("ukava", 5))},
|
||||||
vesting.Period{Length: int64(2), Amount: cs(c("ukava", 100))},
|
vesting.Period{Length: 5, Amount: cs(c("ukava", 5))},
|
||||||
vesting.Period{Length: int64(2), Amount: cs(c("ukava", 100))},
|
vesting.Period{Length: 5, Amount: cs(c("ukava", 5))}},
|
||||||
vesting.Period{Length: int64(6), Amount: cs(c("ukava", 100))},
|
origVestingCoins: cs(c("ukava", 20)),
|
||||||
vesting.Period{Length: int64(5), Amount: cs(c("ukava", 100))},
|
startTime: 100,
|
||||||
vesting.Period{Length: int64(1), Amount: cs(c("ukava", 100))},
|
endTime: 120,
|
||||||
vesting.Period{Length: int64(8), Amount: cs(c("ukava", 100))},
|
},
|
||||||
|
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)),
|
errArgs: errArgs{
|
||||||
expectedCoins: cs(c("ukava", 700)),
|
expectErr: false,
|
||||||
expectedStartTime: int64(100),
|
contains: "",
|
||||||
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))},
|
|
||||||
},
|
},
|
||||||
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",
|
name: "insert period in middle of schedule",
|
||||||
blockTime: time.Unix(90, 0),
|
args: args{
|
||||||
args: args{coins: cs(c("ukava", 100)), length: 11},
|
accArgs: accountArgs{
|
||||||
errArgs: errArgs{expectErr: false, errType: nil},
|
periods: vesting.Periods{
|
||||||
expectedPeriods: vesting.Periods{
|
vesting.Period{Length: 5, Amount: cs(c("ukava", 5))},
|
||||||
vesting.Period{Length: int64(5), Amount: cs(c("ukava", 100))},
|
vesting.Period{Length: 5, Amount: cs(c("ukava", 5))},
|
||||||
vesting.Period{Length: int64(6), Amount: cs(c("ukava", 200))},
|
vesting.Period{Length: 5, Amount: cs(c("ukava", 5))},
|
||||||
vesting.Period{Length: int64(2), Amount: cs(c("ukava", 100))},
|
vesting.Period{Length: 5, Amount: cs(c("ukava", 5))}},
|
||||||
vesting.Period{Length: int64(2), Amount: cs(c("ukava", 100))},
|
origVestingCoins: cs(c("ukava", 20)),
|
||||||
vesting.Period{Length: int64(6), Amount: cs(c("ukava", 100))},
|
startTime: 100,
|
||||||
vesting.Period{Length: int64(5), Amount: cs(c("ukava", 100))},
|
endTime: 120,
|
||||||
vesting.Period{Length: int64(1), Amount: cs(c("ukava", 100))},
|
},
|
||||||
vesting.Period{Length: int64(8), Amount: cs(c("ukava", 100))},
|
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",
|
name: "append to end of schedule",
|
||||||
blockTime: time.Unix(90, 0),
|
args: args{
|
||||||
args: args{coins: cs(c("ukava", 1000)), length: 11},
|
accArgs: accountArgs{
|
||||||
errArgs: errArgs{expectErr: true, errType: types.ErrInsufficientModAccountBalance},
|
periods: vesting.Periods{
|
||||||
expectedPeriods: vesting.Periods{},
|
vesting.Period{Length: 5, Amount: cs(c("ukava", 5))},
|
||||||
expectedOriginalVesting: sdk.Coins{},
|
vesting.Period{Length: 5, Amount: cs(c("ukava", 5))},
|
||||||
expectedCoins: sdk.Coins{},
|
vesting.Period{Length: 5, Amount: cs(c("ukava", 5))},
|
||||||
expectedStartTime: int64(0),
|
vesting.Period{Length: 5, Amount: cs(c("ukava", 5))}},
|
||||||
expectedEndTime: int64(0),
|
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 tests {
|
||||||
for _, tc := range testCases {
|
|
||||||
suite.Run(tc.name, func() {
|
suite.Run(tc.name, func() {
|
||||||
suite.ctx = suite.ctx.WithBlockTime(tc.blockTime)
|
// create the periodic vesting account
|
||||||
err := suite.keeper.SendTimeLockedCoinsToAccount(suite.ctx, kavadist.ModuleName, suite.addrs[0], tc.args.coins, tc.args.length)
|
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 {
|
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 {
|
} else {
|
||||||
suite.Require().NoError(err)
|
suite.Require().NoError(err)
|
||||||
acc := suite.getAccount(suite.addrs[0])
|
|
||||||
|
acc := suite.getAccount(pva.Address)
|
||||||
vacc, ok := acc.(*vesting.PeriodicVestingAccount)
|
vacc, ok := acc.(*vesting.PeriodicVestingAccount)
|
||||||
suite.True(ok)
|
suite.Require().True(ok)
|
||||||
suite.Equal(tc.expectedPeriods, vacc.VestingPeriods)
|
suite.Require().Equal(tc.args.expectedPeriods, vacc.VestingPeriods)
|
||||||
suite.Equal(tc.expectedOriginalVesting, vacc.OriginalVesting)
|
suite.Require().Equal(tc.args.expectedStartTime, vacc.StartTime)
|
||||||
suite.Equal(tc.expectedCoins, vacc.Coins)
|
suite.Require().Equal(tc.args.expectedEndTime, vacc.EndTime)
|
||||||
suite.Equal(tc.expectedStartTime, vacc.StartTime)
|
|
||||||
suite.Equal(tc.expectedEndTime, vacc.EndTime)
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -300,7 +434,7 @@ func (suite *KeeperTestSuite) TestPayoutClaim() {
|
|||||||
suite.keeper.SetClaim(suite.ctx, c3)
|
suite.keeper.SetClaim(suite.ctx, c3)
|
||||||
|
|
||||||
// existing claim with corresponding claim period successfully claimed by existing periodic vesting account
|
// 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)
|
suite.Require().NoError(err)
|
||||||
acc := suite.getAccount(suite.addrs[0])
|
acc := suite.getAccount(suite.addrs[0])
|
||||||
// account is a periodic vesting account
|
// account is a periodic vesting account
|
||||||
|
Loading…
Reference in New Issue
Block a user