2020-09-21 21:08:43 +00:00
|
|
|
package keeper_test
|
|
|
|
|
|
|
|
import (
|
|
|
|
"time"
|
|
|
|
|
|
|
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
|
|
|
"github.com/cosmos/cosmos-sdk/x/auth"
|
|
|
|
"github.com/cosmos/cosmos-sdk/x/auth/vesting"
|
|
|
|
abci "github.com/tendermint/tendermint/abci/types"
|
|
|
|
"github.com/tendermint/tendermint/crypto"
|
2020-10-05 21:44:17 +00:00
|
|
|
|
|
|
|
"github.com/kava-labs/kava/app"
|
2020-12-21 17:18:55 +00:00
|
|
|
"github.com/kava-labs/kava/x/hard/types"
|
2020-09-21 21:08:43 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
func (suite *KeeperTestSuite) TestSendTimeLockedCoinsToAccount() {
|
|
|
|
type accountArgs struct {
|
|
|
|
addr sdk.AccAddress
|
|
|
|
vestingAccountBefore bool
|
|
|
|
vestingAccountAfter bool
|
|
|
|
coins sdk.Coins
|
|
|
|
periods vesting.Periods
|
|
|
|
origVestingCoins sdk.Coins
|
|
|
|
startTime int64
|
|
|
|
endTime int64
|
|
|
|
}
|
|
|
|
type args struct {
|
|
|
|
accArgs accountArgs
|
|
|
|
period vesting.Period
|
|
|
|
blockTime time.Time
|
|
|
|
expectedAccountBalance sdk.Coins
|
|
|
|
expectedModAccountBalance sdk.Coins
|
|
|
|
expectedPeriods vesting.Periods
|
|
|
|
expectedStartTime int64
|
|
|
|
expectedEndTime int64
|
|
|
|
}
|
|
|
|
type errArgs struct {
|
|
|
|
expectPass bool
|
|
|
|
contains string
|
|
|
|
}
|
|
|
|
type testCase struct {
|
|
|
|
name string
|
|
|
|
args args
|
|
|
|
errArgs errArgs
|
|
|
|
}
|
|
|
|
testCases := []testCase{
|
|
|
|
{
|
|
|
|
name: "send liquid coins to base account",
|
|
|
|
args: args{
|
|
|
|
accArgs: accountArgs{
|
|
|
|
addr: sdk.AccAddress(crypto.AddressHash([]byte("test"))),
|
|
|
|
vestingAccountBefore: false,
|
|
|
|
vestingAccountAfter: false,
|
|
|
|
coins: sdk.NewCoins(sdk.NewCoin("bnb", sdk.NewInt(1000)), sdk.NewCoin("btcb", sdk.NewInt(1000))),
|
|
|
|
},
|
|
|
|
period: vesting.Period{Length: 0, Amount: sdk.NewCoins(sdk.NewCoin("hard", sdk.NewInt(100)))},
|
|
|
|
blockTime: time.Date(2020, 11, 1, 14, 0, 0, 0, time.UTC),
|
|
|
|
expectedAccountBalance: sdk.NewCoins(sdk.NewCoin("bnb", sdk.NewInt(1000)), sdk.NewCoin("btcb", sdk.NewInt(1000)), sdk.NewCoin("hard", sdk.NewInt(100))),
|
|
|
|
expectedModAccountBalance: sdk.NewCoins(sdk.NewCoin("hard", sdk.NewInt(900))),
|
|
|
|
expectedPeriods: vesting.Periods{},
|
|
|
|
expectedStartTime: 0,
|
|
|
|
expectedEndTime: 0,
|
|
|
|
},
|
|
|
|
errArgs: errArgs{
|
|
|
|
expectPass: true,
|
|
|
|
contains: "",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "send liquid coins to vesting account",
|
|
|
|
args: args{
|
|
|
|
accArgs: accountArgs{
|
|
|
|
addr: sdk.AccAddress(crypto.AddressHash([]byte("test"))),
|
|
|
|
vestingAccountBefore: true,
|
|
|
|
vestingAccountAfter: true,
|
|
|
|
coins: sdk.NewCoins(sdk.NewCoin("bnb", sdk.NewInt(1000)), sdk.NewCoin("btcb", sdk.NewInt(1000))),
|
|
|
|
periods: vesting.Periods{
|
|
|
|
vesting.Period{Amount: sdk.NewCoins(sdk.NewCoin("bnb", sdk.NewInt(100))), Length: 100},
|
|
|
|
},
|
|
|
|
origVestingCoins: sdk.NewCoins(sdk.NewCoin("bnb", sdk.NewInt(100))),
|
|
|
|
startTime: time.Date(2020, 11, 1, 14, 0, 0, 0, time.UTC).Unix(),
|
|
|
|
endTime: time.Date(2020, 11, 1, 14, 0, 0, 0, time.UTC).Unix() + 100,
|
|
|
|
},
|
|
|
|
period: vesting.Period{Length: 0, Amount: sdk.NewCoins(sdk.NewCoin("hard", sdk.NewInt(100)))},
|
|
|
|
blockTime: time.Date(2020, 11, 1, 14, 0, 0, 0, time.UTC),
|
|
|
|
expectedAccountBalance: sdk.NewCoins(sdk.NewCoin("bnb", sdk.NewInt(1000)), sdk.NewCoin("btcb", sdk.NewInt(1000)), sdk.NewCoin("hard", sdk.NewInt(100))),
|
|
|
|
expectedModAccountBalance: sdk.NewCoins(sdk.NewCoin("hard", sdk.NewInt(900))),
|
|
|
|
expectedPeriods: vesting.Periods{
|
|
|
|
vesting.Period{Amount: sdk.NewCoins(sdk.NewCoin("bnb", sdk.NewInt(100))), Length: 100},
|
|
|
|
},
|
|
|
|
expectedStartTime: time.Date(2020, 11, 1, 14, 0, 0, 0, time.UTC).Unix(),
|
|
|
|
expectedEndTime: time.Date(2020, 11, 1, 14, 0, 0, 0, time.UTC).Unix() + 100,
|
|
|
|
},
|
|
|
|
errArgs: errArgs{
|
|
|
|
expectPass: true,
|
|
|
|
contains: "",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "insert period at beginning of schedule",
|
|
|
|
args: args{
|
|
|
|
accArgs: accountArgs{
|
|
|
|
addr: sdk.AccAddress(crypto.AddressHash([]byte("test"))),
|
|
|
|
vestingAccountBefore: true,
|
|
|
|
vestingAccountAfter: true,
|
|
|
|
coins: cs(c("bnb", 20)),
|
|
|
|
periods: vesting.Periods{
|
|
|
|
vesting.Period{Length: 5, Amount: cs(c("bnb", 5))},
|
|
|
|
vesting.Period{Length: 5, Amount: cs(c("bnb", 5))},
|
|
|
|
vesting.Period{Length: 5, Amount: cs(c("bnb", 5))},
|
|
|
|
vesting.Period{Length: 5, Amount: cs(c("bnb", 5))}},
|
|
|
|
origVestingCoins: cs(c("bnb", 20)),
|
|
|
|
startTime: 100,
|
|
|
|
endTime: 120,
|
|
|
|
},
|
|
|
|
period: vesting.Period{Length: 2, Amount: cs(c("hard", 6))},
|
|
|
|
blockTime: time.Unix(101, 0),
|
|
|
|
expectedAccountBalance: cs(c("bnb", 20), c("hard", 6)),
|
|
|
|
expectedModAccountBalance: cs(c("hard", 994)),
|
|
|
|
expectedPeriods: vesting.Periods{
|
|
|
|
vesting.Period{Length: 3, Amount: cs(c("hard", 6))},
|
|
|
|
vesting.Period{Length: 2, Amount: cs(c("bnb", 5))},
|
|
|
|
vesting.Period{Length: 5, Amount: cs(c("bnb", 5))},
|
|
|
|
vesting.Period{Length: 5, Amount: cs(c("bnb", 5))},
|
|
|
|
vesting.Period{Length: 5, Amount: cs(c("bnb", 5))}},
|
|
|
|
expectedStartTime: 100,
|
|
|
|
expectedEndTime: 120,
|
|
|
|
},
|
|
|
|
errArgs: errArgs{
|
|
|
|
expectPass: true,
|
|
|
|
contains: "",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "insert period at beginning with new start time",
|
|
|
|
args: args{
|
|
|
|
accArgs: accountArgs{
|
|
|
|
addr: sdk.AccAddress(crypto.AddressHash([]byte("test"))),
|
|
|
|
vestingAccountBefore: true,
|
|
|
|
vestingAccountAfter: true,
|
|
|
|
coins: cs(c("bnb", 20)),
|
|
|
|
periods: vesting.Periods{
|
|
|
|
vesting.Period{Length: 5, Amount: cs(c("bnb", 5))},
|
|
|
|
vesting.Period{Length: 5, Amount: cs(c("bnb", 5))},
|
|
|
|
vesting.Period{Length: 5, Amount: cs(c("bnb", 5))},
|
|
|
|
vesting.Period{Length: 5, Amount: cs(c("bnb", 5))}},
|
|
|
|
origVestingCoins: cs(c("bnb", 20)),
|
|
|
|
startTime: 100,
|
|
|
|
endTime: 120,
|
|
|
|
},
|
|
|
|
period: vesting.Period{Length: 7, Amount: cs(c("hard", 6))},
|
|
|
|
blockTime: time.Unix(80, 0),
|
|
|
|
expectedAccountBalance: cs(c("bnb", 20), c("hard", 6)),
|
|
|
|
expectedModAccountBalance: cs(c("hard", 994)),
|
|
|
|
expectedPeriods: vesting.Periods{
|
|
|
|
vesting.Period{Length: 7, Amount: cs(c("hard", 6))},
|
|
|
|
vesting.Period{Length: 18, Amount: cs(c("bnb", 5))},
|
|
|
|
vesting.Period{Length: 5, Amount: cs(c("bnb", 5))},
|
|
|
|
vesting.Period{Length: 5, Amount: cs(c("bnb", 5))},
|
|
|
|
vesting.Period{Length: 5, Amount: cs(c("bnb", 5))}},
|
|
|
|
expectedStartTime: 80,
|
|
|
|
expectedEndTime: 120,
|
|
|
|
},
|
|
|
|
errArgs: errArgs{
|
|
|
|
expectPass: true,
|
|
|
|
contains: "",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "insert period in middle of schedule",
|
|
|
|
args: args{
|
|
|
|
accArgs: accountArgs{
|
|
|
|
addr: sdk.AccAddress(crypto.AddressHash([]byte("test"))),
|
|
|
|
vestingAccountBefore: true,
|
|
|
|
vestingAccountAfter: true,
|
|
|
|
coins: cs(c("bnb", 20)),
|
|
|
|
periods: vesting.Periods{
|
|
|
|
vesting.Period{Length: 5, Amount: cs(c("bnb", 5))},
|
|
|
|
vesting.Period{Length: 5, Amount: cs(c("bnb", 5))},
|
|
|
|
vesting.Period{Length: 5, Amount: cs(c("bnb", 5))},
|
|
|
|
vesting.Period{Length: 5, Amount: cs(c("bnb", 5))}},
|
|
|
|
origVestingCoins: cs(c("bnb", 20)),
|
|
|
|
startTime: 100,
|
|
|
|
endTime: 120,
|
|
|
|
},
|
|
|
|
period: vesting.Period{Length: 7, Amount: cs(c("hard", 6))},
|
|
|
|
blockTime: time.Unix(101, 0),
|
|
|
|
expectedAccountBalance: cs(c("bnb", 20), c("hard", 6)),
|
|
|
|
expectedModAccountBalance: cs(c("hard", 994)),
|
|
|
|
expectedPeriods: vesting.Periods{
|
|
|
|
vesting.Period{Length: 5, Amount: cs(c("bnb", 5))},
|
|
|
|
vesting.Period{Length: 3, Amount: cs(c("hard", 6))},
|
|
|
|
vesting.Period{Length: 2, Amount: cs(c("bnb", 5))},
|
|
|
|
vesting.Period{Length: 5, Amount: cs(c("bnb", 5))},
|
|
|
|
vesting.Period{Length: 5, Amount: cs(c("bnb", 5))}},
|
|
|
|
expectedStartTime: 100,
|
|
|
|
expectedEndTime: 120,
|
|
|
|
},
|
|
|
|
errArgs: errArgs{
|
|
|
|
expectPass: true,
|
|
|
|
contains: "",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "append to end of schedule",
|
|
|
|
args: args{
|
|
|
|
accArgs: accountArgs{
|
|
|
|
addr: sdk.AccAddress(crypto.AddressHash([]byte("test"))),
|
|
|
|
vestingAccountBefore: true,
|
|
|
|
vestingAccountAfter: true,
|
|
|
|
coins: cs(c("bnb", 20)),
|
|
|
|
periods: vesting.Periods{
|
|
|
|
vesting.Period{Length: 5, Amount: cs(c("bnb", 5))},
|
|
|
|
vesting.Period{Length: 5, Amount: cs(c("bnb", 5))},
|
|
|
|
vesting.Period{Length: 5, Amount: cs(c("bnb", 5))},
|
|
|
|
vesting.Period{Length: 5, Amount: cs(c("bnb", 5))}},
|
|
|
|
origVestingCoins: cs(c("bnb", 20)),
|
|
|
|
startTime: 100,
|
|
|
|
endTime: 120,
|
|
|
|
},
|
|
|
|
period: vesting.Period{Length: 7, Amount: cs(c("hard", 6))},
|
|
|
|
blockTime: time.Unix(125, 0),
|
|
|
|
expectedAccountBalance: cs(c("bnb", 20), c("hard", 6)),
|
|
|
|
expectedModAccountBalance: cs(c("hard", 994)),
|
|
|
|
expectedPeriods: vesting.Periods{
|
|
|
|
vesting.Period{Length: 5, Amount: cs(c("bnb", 5))},
|
|
|
|
vesting.Period{Length: 5, Amount: cs(c("bnb", 5))},
|
|
|
|
vesting.Period{Length: 5, Amount: cs(c("bnb", 5))},
|
|
|
|
vesting.Period{Length: 5, Amount: cs(c("bnb", 5))},
|
|
|
|
vesting.Period{Length: 12, Amount: cs(c("hard", 6))}},
|
|
|
|
expectedStartTime: 100,
|
|
|
|
expectedEndTime: 132,
|
|
|
|
},
|
|
|
|
errArgs: errArgs{
|
|
|
|
expectPass: true,
|
|
|
|
contains: "",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "add coins to existing period",
|
|
|
|
args: args{
|
|
|
|
accArgs: accountArgs{
|
|
|
|
addr: sdk.AccAddress(crypto.AddressHash([]byte("test"))),
|
|
|
|
vestingAccountBefore: true,
|
|
|
|
vestingAccountAfter: true,
|
|
|
|
coins: cs(c("bnb", 20)),
|
|
|
|
periods: vesting.Periods{
|
|
|
|
vesting.Period{Length: 5, Amount: cs(c("bnb", 5))},
|
|
|
|
vesting.Period{Length: 5, Amount: cs(c("bnb", 5))},
|
|
|
|
vesting.Period{Length: 5, Amount: cs(c("bnb", 5))},
|
|
|
|
vesting.Period{Length: 5, Amount: cs(c("bnb", 5))}},
|
|
|
|
origVestingCoins: cs(c("bnb", 20)),
|
|
|
|
startTime: 100,
|
|
|
|
endTime: 120,
|
|
|
|
},
|
|
|
|
period: vesting.Period{Length: 5, Amount: cs(c("hard", 6))},
|
|
|
|
blockTime: time.Unix(110, 0),
|
|
|
|
expectedAccountBalance: cs(c("bnb", 20), c("hard", 6)),
|
|
|
|
expectedModAccountBalance: cs(c("hard", 994)),
|
|
|
|
expectedPeriods: vesting.Periods{
|
|
|
|
vesting.Period{Length: 5, Amount: cs(c("bnb", 5))},
|
|
|
|
vesting.Period{Length: 5, Amount: cs(c("bnb", 5))},
|
|
|
|
vesting.Period{Length: 5, Amount: cs(c("bnb", 5), c("hard", 6))},
|
|
|
|
vesting.Period{Length: 5, Amount: cs(c("bnb", 5))}},
|
|
|
|
expectedStartTime: 100,
|
|
|
|
expectedEndTime: 120,
|
|
|
|
},
|
|
|
|
errArgs: errArgs{
|
|
|
|
expectPass: true,
|
|
|
|
contains: "",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
|
|
suite.Run(tc.name, func() {
|
|
|
|
// create new app with one funded account
|
2020-10-05 21:44:17 +00:00
|
|
|
|
2020-09-21 21:08:43 +00:00
|
|
|
// Initialize test app and set context
|
|
|
|
tApp := app.NewTestApp()
|
|
|
|
ctx := tApp.NewContext(true, abci.Header{Height: 1, Time: tc.args.blockTime})
|
|
|
|
authGS := app.NewAuthGenState([]sdk.AccAddress{tc.args.accArgs.addr}, []sdk.Coins{tc.args.accArgs.coins})
|
2020-10-30 09:59:47 +00:00
|
|
|
loanToValue := sdk.MustNewDecFromStr("0.6")
|
2020-12-21 17:18:55 +00:00
|
|
|
hardGS := types.NewGenesisState(types.NewParams(
|
2020-10-30 09:59:47 +00:00
|
|
|
types.MoneyMarkets{
|
2020-12-15 17:38:14 +00:00
|
|
|
types.NewMoneyMarket("usdx", types.NewBorrowLimit(false, sdk.NewDec(1000000000000000), loanToValue), "usdx:usd", sdk.NewInt(1000000), sdk.NewInt(USDX_CF*1000), types.NewInterestRateModel(sdk.MustNewDecFromStr("0.05"), sdk.MustNewDecFromStr("2"), sdk.MustNewDecFromStr("0.8"), sdk.MustNewDecFromStr("10")), sdk.MustNewDecFromStr("0.05"), sdk.ZeroDec()),
|
|
|
|
types.NewMoneyMarket("ukava", types.NewBorrowLimit(false, sdk.NewDec(1000000000000000), loanToValue), "kava:usd", sdk.NewInt(1000000), sdk.NewInt(KAVA_CF*1000), types.NewInterestRateModel(sdk.MustNewDecFromStr("0.05"), sdk.MustNewDecFromStr("2"), sdk.MustNewDecFromStr("0.8"), sdk.MustNewDecFromStr("10")), sdk.MustNewDecFromStr("0.05"), sdk.ZeroDec()),
|
2020-10-30 09:59:47 +00:00
|
|
|
},
|
2021-01-23 05:17:40 +00:00
|
|
|
), types.DefaultAccumulationTimes, types.DefaultDeposits, types.DefaultBorrows,
|
|
|
|
types.DefaultTotalSupplied, types.DefaultTotalBorrowed, types.DefaultTotalReserves,
|
|
|
|
)
|
2020-12-21 17:18:55 +00:00
|
|
|
tApp.InitializeFromGenesisStates(authGS, app.GenesisState{types.ModuleName: types.ModuleCdc.MustMarshalJSON(hardGS)})
|
2020-09-21 21:08:43 +00:00
|
|
|
if tc.args.accArgs.vestingAccountBefore {
|
|
|
|
ak := tApp.GetAccountKeeper()
|
|
|
|
acc := ak.GetAccount(ctx, tc.args.accArgs.addr)
|
|
|
|
bacc := auth.NewBaseAccount(acc.GetAddress(), acc.GetCoins(), acc.GetPubKey(), acc.GetAccountNumber(), acc.GetSequence())
|
|
|
|
bva, err := vesting.NewBaseVestingAccount(bacc, tc.args.accArgs.origVestingCoins, tc.args.accArgs.endTime)
|
|
|
|
suite.Require().NoError(err)
|
|
|
|
pva := vesting.NewPeriodicVestingAccountRaw(bva, tc.args.accArgs.startTime, tc.args.accArgs.periods)
|
|
|
|
ak.SetAccount(ctx, pva)
|
|
|
|
}
|
|
|
|
supplyKeeper := tApp.GetSupplyKeeper()
|
2021-02-09 20:33:58 +00:00
|
|
|
supplyKeeper.MintCoins(ctx, types.ModuleAccountName, sdk.NewCoins(sdk.NewCoin("hard", sdk.NewInt(1000))))
|
2020-12-21 17:18:55 +00:00
|
|
|
keeper := tApp.GetHardKeeper()
|
2020-09-21 21:08:43 +00:00
|
|
|
suite.app = tApp
|
|
|
|
suite.ctx = ctx
|
|
|
|
suite.keeper = keeper
|
|
|
|
|
2021-02-09 20:33:58 +00:00
|
|
|
err := suite.keeper.SendTimeLockedCoinsToAccount(suite.ctx, types.ModuleAccountName, tc.args.accArgs.addr, tc.args.period.Amount, tc.args.period.Length)
|
2020-09-21 21:08:43 +00:00
|
|
|
|
|
|
|
if tc.errArgs.expectPass {
|
|
|
|
suite.Require().NoError(err)
|
|
|
|
acc := suite.getAccount(tc.args.accArgs.addr)
|
|
|
|
suite.Require().Equal(tc.args.expectedAccountBalance, acc.GetCoins())
|
2021-02-09 20:33:58 +00:00
|
|
|
mAcc := suite.getModuleAccount(types.ModuleAccountName)
|
2020-09-21 21:08:43 +00:00
|
|
|
suite.Require().Equal(tc.args.expectedModAccountBalance, mAcc.GetCoins())
|
|
|
|
vacc, ok := acc.(*vesting.PeriodicVestingAccount)
|
|
|
|
if tc.args.accArgs.vestingAccountAfter {
|
|
|
|
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)
|
|
|
|
} else {
|
|
|
|
suite.Require().False(ok)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func c(denom string, amount int64) sdk.Coin { return sdk.NewInt64Coin(denom, amount) }
|
|
|
|
func cs(coins ...sdk.Coin) sdk.Coins { return sdk.NewCoins(coins...) }
|