diff --git a/x/auth/vesting/types/vesting_account.go b/x/auth/vesting/types/vesting_account.go index 0f537f616..ed2158b60 100644 --- a/x/auth/vesting/types/vesting_account.go +++ b/x/auth/vesting/types/vesting_account.go @@ -2,12 +2,14 @@ package types import ( "errors" + "fmt" "time" yaml "gopkg.in/yaml.v2" cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" vestexported "github.com/cosmos/cosmos-sdk/x/auth/vesting/exported" ) @@ -423,6 +425,20 @@ func (pva PeriodicVestingAccount) Validate() error { return errors.New("original vesting coins does not match the sum of all coins in vesting periods") } + for i, period := range pva.VestingPeriods { + if !period.Amount.IsValid() { + return sdkerrors.ErrInvalidCoins.Wrap(period.Amount.String()) + } + + if !period.Amount.IsAllPositive() { + return sdkerrors.ErrInvalidCoins.Wrap(period.Amount.String()) + } + + if period.Length < 1 { + return fmt.Errorf("invalid period length of %d in period %d, length must be greater than 0", period.Length, i) + } + } + return pva.BaseVestingAccount.Validate() } diff --git a/x/auth/vesting/types/vesting_account_test.go b/x/auth/vesting/types/vesting_account_test.go index 80afdbe88..bd0b6ec8b 100644 --- a/x/auth/vesting/types/vesting_account_test.go +++ b/x/auth/vesting/types/vesting_account_test.go @@ -660,6 +660,7 @@ func TestTrackUndelegationPermLockedVestingAcc(t *testing.T) { } func TestGenesisAccountValidate(t *testing.T) { + t.Parallel() pubkey := secp256k1.GenPrivKey().PubKey() addr := sdk.AccAddress(pubkey.Address()) baseAcc := authtypes.NewBaseAccount(addr, pubkey, 0, 0) @@ -697,7 +698,15 @@ func TestGenesisAccountValidate(t *testing.T) { }, { "valid periodic vesting account", - types.NewPeriodicVestingAccount(baseAcc, initialVesting, 0, types.Periods{types.Period{Length: int64(100), Amount: sdk.Coins{sdk.NewInt64Coin(sdk.DefaultBondDenom, 50)}}}, nil), + types.NewPeriodicVestingAccount( + baseAcc, + initialVesting, + 0, + types.Periods{ + types.Period{Length: int64(100), Amount: sdk.Coins{sdk.NewInt64Coin(sdk.DefaultBondDenom, 50)}}, + }, + nil, + ), false, }, { @@ -714,6 +723,37 @@ func TestGenesisAccountValidate(t *testing.T) { 0, types.Periods{types.Period{Length: int64(100), Amount: sdk.Coins{sdk.NewInt64Coin(sdk.DefaultBondDenom, 25)}}}), true, }, + { + "Empty coin amount should fail", + types.NewPeriodicVestingAccountRaw( + baseVestingWithCoins, + 0, types.Periods{types.Period{Length: int64(100), Amount: sdk.Coins{}}}), + true, + }, + { + "Less than 1 coin period should fail", + types.NewPeriodicVestingAccountRaw( + baseVestingWithCoins, + 0, types.Periods{types.Period{Length: int64(0), Amount: sdk.Coins{sdk.NewInt64Coin(sdk.DefaultBondDenom, 25)}}}), + true, + }, + { + "Negative coin amount should fail", + types.NewPeriodicVestingAccountRaw( + baseVestingWithCoins, + 0, types.Periods{types.Period{Length: int64(100), Amount: sdk.Coins{sdk.Coin{ + Denom: sdk.DefaultBondDenom, + Amount: sdk.NewInt(-123), + }}}}), + true, + }, + { + "Less than 1 coin period should fail", + types.NewPeriodicVestingAccountRaw( + baseVestingWithCoins, + 0, types.Periods{types.Period{Length: int64(-1), Amount: sdk.Coins{sdk.NewInt64Coin(sdk.DefaultBondDenom, 25)}}}), + true, + }, { "valid permanent locked vesting account", types.NewPermanentLockedAccount(baseAcc, initialVesting, nil),