mirror of
https://github.com/0glabs/0g-chain.git
synced 2024-12-24 15:25:18 +00:00
Add Init/ExportGenesis for Earn module (#1280)
* Add vault and vault shares to genesis * Fix error and denoms * Update init and export genesis with correct data * Fix total supply genesis check, remove legacy test for enum errors * Add vault slice validate tests * Update denom validation, add additional test
This commit is contained in:
parent
82e2f26e14
commit
ed9991d44a
@ -10,16 +10,54 @@ import (
|
||||
)
|
||||
|
||||
// InitGenesis initializes genesis state
|
||||
func InitGenesis(ctx sdk.Context, k keeper.Keeper, ak types.AccountKeeper, gs types.GenesisState) {
|
||||
func InitGenesis(
|
||||
ctx sdk.Context,
|
||||
k keeper.Keeper,
|
||||
ak types.AccountKeeper,
|
||||
gs types.GenesisState,
|
||||
) {
|
||||
if err := gs.Validate(); err != nil {
|
||||
panic(fmt.Sprintf("failed to validate %s genesis state: %s", types.ModuleName, err))
|
||||
}
|
||||
|
||||
// Total of all vault share records, vault record total supply should equal this
|
||||
vaultTotalSupplies := sdk.NewCoins()
|
||||
|
||||
for _, vaultShareRecord := range gs.VaultShareRecords {
|
||||
if err := vaultShareRecord.Validate(); err != nil {
|
||||
panic(fmt.Sprintf("invalid vault share: %s", err))
|
||||
}
|
||||
|
||||
vaultTotalSupplies = vaultTotalSupplies.Add(vaultShareRecord.AmountSupplied...)
|
||||
|
||||
k.SetVaultShareRecord(ctx, vaultShareRecord)
|
||||
}
|
||||
|
||||
for _, vaultRecord := range gs.VaultRecords {
|
||||
if err := vaultRecord.Validate(); err != nil {
|
||||
panic(fmt.Sprintf("invalid vault record: %s", err))
|
||||
}
|
||||
|
||||
if !vaultRecord.TotalSupply.Amount.Equal(vaultTotalSupplies.AmountOf(vaultRecord.Denom)) {
|
||||
panic(fmt.Sprintf(
|
||||
"invalid vault record total supply for %s, got %s but sum of vault shares is %s",
|
||||
vaultRecord.Denom,
|
||||
vaultRecord.TotalSupply.Amount,
|
||||
vaultTotalSupplies.AmountOf(vaultRecord.Denom),
|
||||
))
|
||||
}
|
||||
|
||||
k.SetVaultRecord(ctx, vaultRecord)
|
||||
}
|
||||
|
||||
k.SetParams(ctx, gs.Params)
|
||||
}
|
||||
|
||||
// ExportGenesis returns a GenesisState for a given context and keeper
|
||||
func ExportGenesis(ctx sdk.Context, k keeper.Keeper) types.GenesisState {
|
||||
params := k.GetParams(ctx)
|
||||
return types.NewGenesisState(params)
|
||||
vaultRecords := k.GetAllVaultRecords(ctx)
|
||||
vaultShareRecords := k.GetAllVaultShareRecords(ctx)
|
||||
|
||||
return types.NewGenesisState(params, vaultRecords, vaultShareRecords)
|
||||
}
|
||||
|
145
x/earn/genesis_test.go
Normal file
145
x/earn/genesis_test.go
Normal file
@ -0,0 +1,145 @@
|
||||
package earn_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/kava-labs/kava/app"
|
||||
"github.com/kava-labs/kava/x/earn"
|
||||
"github.com/kava-labs/kava/x/earn/testutil"
|
||||
"github.com/kava-labs/kava/x/earn/types"
|
||||
"github.com/stretchr/testify/suite"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
)
|
||||
|
||||
type genesisTestSuite struct {
|
||||
testutil.Suite
|
||||
}
|
||||
|
||||
func (suite *genesisTestSuite) Test_InitGenesis_ValidationPanic() {
|
||||
invalidState := types.NewGenesisState(
|
||||
types.Params{
|
||||
AllowedVaults: types.AllowedVaults{
|
||||
types.NewAllowedVault("usdx", types.STRATEGY_TYPE_HARD),
|
||||
},
|
||||
},
|
||||
types.VaultRecords{
|
||||
{
|
||||
Denom: "",
|
||||
TotalSupply: sdk.NewInt64Coin("usdx", 0),
|
||||
},
|
||||
},
|
||||
types.VaultShareRecords{},
|
||||
)
|
||||
|
||||
suite.Panics(func() {
|
||||
earn.InitGenesis(suite.Ctx, suite.Keeper, suite.AccountKeeper, invalidState)
|
||||
}, "expected init genesis to panic with invalid state")
|
||||
}
|
||||
|
||||
func (suite *genesisTestSuite) Test_InitAndExportGenesis() {
|
||||
depositor_1, err := sdk.AccAddressFromBech32("kava1esagqd83rhqdtpy5sxhklaxgn58k2m3s3mnpea")
|
||||
suite.Require().NoError(err)
|
||||
depositor_2, err := sdk.AccAddressFromBech32("kava1mq9qxlhze029lm0frzw2xr6hem8c3k9ts54w0w")
|
||||
suite.Require().NoError(err)
|
||||
|
||||
// slices are sorted by key as stored in the data store, so init and export can be compared with equal
|
||||
state := types.NewGenesisState(
|
||||
types.Params{
|
||||
AllowedVaults: types.AllowedVaults{
|
||||
types.NewAllowedVault("usdx", types.STRATEGY_TYPE_HARD),
|
||||
types.NewAllowedVault("ukava", types.STRATEGY_TYPE_SAVINGS),
|
||||
},
|
||||
},
|
||||
types.VaultRecords{
|
||||
types.VaultRecord{
|
||||
Denom: "ukava",
|
||||
TotalSupply: sdk.NewInt64Coin("ukava", 2000000),
|
||||
},
|
||||
types.VaultRecord{
|
||||
Denom: "usdx",
|
||||
TotalSupply: sdk.NewInt64Coin("usdx", 1000000),
|
||||
},
|
||||
},
|
||||
types.VaultShareRecords{
|
||||
types.VaultShareRecord{
|
||||
Depositor: depositor_1,
|
||||
AmountSupplied: sdk.NewCoins(sdk.NewInt64Coin("usdx", 500000), sdk.NewInt64Coin("ukava", 1900000)),
|
||||
},
|
||||
types.VaultShareRecord{
|
||||
Depositor: depositor_2,
|
||||
AmountSupplied: sdk.NewCoins(sdk.NewInt64Coin("usdx", 500000), sdk.NewInt64Coin("ukava", 100000)),
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
earn.InitGenesis(suite.Ctx, suite.Keeper, suite.AccountKeeper, state)
|
||||
suite.Equal(state.Params, suite.Keeper.GetParams(suite.Ctx))
|
||||
|
||||
vaultRecord1, _ := suite.Keeper.GetVaultRecord(suite.Ctx, "ukava")
|
||||
vaultRecord2, _ := suite.Keeper.GetVaultRecord(suite.Ctx, "usdx")
|
||||
suite.Equal(state.VaultRecords[0], vaultRecord1)
|
||||
suite.Equal(state.VaultRecords[1], vaultRecord2)
|
||||
|
||||
shareRecord1, _ := suite.Keeper.GetVaultShareRecord(suite.Ctx, depositor_1)
|
||||
shareRecord2, _ := suite.Keeper.GetVaultShareRecord(suite.Ctx, depositor_2)
|
||||
|
||||
suite.Equal(state.VaultShareRecords[0], shareRecord1)
|
||||
suite.Equal(state.VaultShareRecords[1], shareRecord2)
|
||||
|
||||
exportedState := earn.ExportGenesis(suite.Ctx, suite.Keeper)
|
||||
suite.Equal(state, exportedState)
|
||||
}
|
||||
|
||||
func (suite *genesisTestSuite) Test_Marshall() {
|
||||
depositor_1, err := sdk.AccAddressFromBech32("kava1esagqd83rhqdtpy5sxhklaxgn58k2m3s3mnpea")
|
||||
suite.Require().NoError(err)
|
||||
depositor_2, err := sdk.AccAddressFromBech32("kava1mq9qxlhze029lm0frzw2xr6hem8c3k9ts54w0w")
|
||||
suite.Require().NoError(err)
|
||||
|
||||
// slices are sorted by key as stored in the data store, so init and export can be compared with equal
|
||||
state := types.NewGenesisState(
|
||||
types.Params{
|
||||
AllowedVaults: types.AllowedVaults{
|
||||
types.NewAllowedVault("usdx", types.STRATEGY_TYPE_HARD),
|
||||
types.NewAllowedVault("ukava", types.STRATEGY_TYPE_SAVINGS),
|
||||
},
|
||||
},
|
||||
types.VaultRecords{
|
||||
types.VaultRecord{
|
||||
Denom: "ukava",
|
||||
TotalSupply: sdk.NewInt64Coin("ukava", 2000000),
|
||||
},
|
||||
types.VaultRecord{
|
||||
Denom: "usdx",
|
||||
TotalSupply: sdk.NewInt64Coin("usdx", 1000000),
|
||||
},
|
||||
},
|
||||
types.VaultShareRecords{
|
||||
types.VaultShareRecord{
|
||||
Depositor: depositor_1,
|
||||
AmountSupplied: sdk.NewCoins(sdk.NewInt64Coin("usdx", 500000), sdk.NewInt64Coin("ukava", 1900000)),
|
||||
},
|
||||
types.VaultShareRecord{
|
||||
Depositor: depositor_2,
|
||||
AmountSupplied: sdk.NewCoins(sdk.NewInt64Coin("usdx", 500000), sdk.NewInt64Coin("ukava", 100000)),
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
encodingCfg := app.MakeEncodingConfig()
|
||||
cdc := encodingCfg.Marshaler
|
||||
|
||||
bz, err := cdc.Marshal(&state)
|
||||
suite.Require().NoError(err, "expected genesis state to marshal without error")
|
||||
|
||||
var decodedState types.GenesisState
|
||||
err = cdc.Unmarshal(bz, &decodedState)
|
||||
suite.Require().NoError(err, "expected genesis state to unmarshal without error")
|
||||
|
||||
suite.Equal(state, decodedState)
|
||||
}
|
||||
|
||||
func TestGenesisTestSuite(t *testing.T) {
|
||||
suite.Run(t, new(genesisTestSuite))
|
||||
}
|
@ -222,3 +222,34 @@ func (k *Keeper) SetVaultShareRecord(
|
||||
bz := k.cdc.MustMarshal(&record)
|
||||
store.Set(types.DepositorVaultSharesKey(record.Depositor), bz)
|
||||
}
|
||||
|
||||
// IterateVaultShareRecords iterates over all vault share objects in the store
|
||||
// and performs a callback function.
|
||||
func (k Keeper) IterateVaultShareRecords(
|
||||
ctx sdk.Context,
|
||||
cb func(record types.VaultShareRecord) (stop bool),
|
||||
) {
|
||||
store := prefix.NewStore(ctx.KVStore(k.key), types.VaultShareRecordKeyPrefix)
|
||||
iterator := sdk.KVStorePrefixIterator(store, []byte{})
|
||||
defer iterator.Close()
|
||||
|
||||
for ; iterator.Valid(); iterator.Next() {
|
||||
var record types.VaultShareRecord
|
||||
k.cdc.MustUnmarshal(iterator.Value(), &record)
|
||||
if cb(record) {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// GetAllVaultShareRecords returns all vault share records from the store.
|
||||
func (k Keeper) GetAllVaultShareRecords(ctx sdk.Context) types.VaultShareRecords {
|
||||
var records types.VaultShareRecords
|
||||
|
||||
k.IterateVaultShareRecords(ctx, func(record types.VaultShareRecord) bool {
|
||||
records = append(records, record)
|
||||
return false
|
||||
})
|
||||
|
||||
return records
|
||||
}
|
||||
|
@ -1,9 +1,15 @@
|
||||
package types
|
||||
|
||||
// NewGenesisState creates a new genesis state.
|
||||
func NewGenesisState(params Params) GenesisState {
|
||||
func NewGenesisState(
|
||||
params Params,
|
||||
vaultRecords VaultRecords,
|
||||
vaultShareRecords VaultShareRecords,
|
||||
) GenesisState {
|
||||
return GenesisState{
|
||||
Params: params,
|
||||
Params: params,
|
||||
VaultRecords: vaultRecords,
|
||||
VaultShareRecords: vaultShareRecords,
|
||||
}
|
||||
}
|
||||
|
||||
@ -13,6 +19,14 @@ func (gs GenesisState) Validate() error {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := gs.VaultRecords.Validate(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := gs.VaultShareRecords.Validate(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -20,5 +34,7 @@ func (gs GenesisState) Validate() error {
|
||||
func DefaultGenesisState() GenesisState {
|
||||
return NewGenesisState(
|
||||
DefaultParams(),
|
||||
VaultRecords{},
|
||||
VaultShareRecords{},
|
||||
)
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ import (
|
||||
"fmt"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
||||
)
|
||||
|
||||
// NewVaultRecord returns a new VaultRecord with 0 supply.
|
||||
@ -14,9 +15,48 @@ func NewVaultRecord(vaultDenom string) VaultRecord {
|
||||
}
|
||||
}
|
||||
|
||||
// Validate returns an error if a VaultRecord is invalid.
|
||||
func (vr *VaultRecord) Validate() error {
|
||||
if err := sdk.ValidateDenom(vr.Denom); err != nil {
|
||||
return sdkerrors.Wrap(ErrInvalidVaultDenom, err.Error())
|
||||
}
|
||||
|
||||
if vr.TotalSupply.Denom != vr.Denom {
|
||||
return fmt.Errorf(
|
||||
"total supply denom %v does not match vault record denom %v",
|
||||
vr.TotalSupply.Denom,
|
||||
vr.Denom,
|
||||
)
|
||||
}
|
||||
|
||||
if err := vr.TotalSupply.Validate(); err != nil {
|
||||
return fmt.Errorf("vault total supply is invalid: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// VaultRecords is a slice of VaultRecord.
|
||||
type VaultRecords []VaultRecord
|
||||
|
||||
type VaultShareRecords []VaultShareRecord
|
||||
// Validate returns an error if a slice of VaultRecords is invalid.
|
||||
func (vrs VaultRecords) Validate() error {
|
||||
denoms := make(map[string]bool)
|
||||
|
||||
for _, vr := range vrs {
|
||||
if err := vr.Validate(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if denoms[vr.Denom] {
|
||||
return fmt.Errorf("duplicate vault denom %s", vr.Denom)
|
||||
}
|
||||
|
||||
denoms[vr.Denom] = true
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// NewVaultShareRecord returns a new VaultShareRecord with the provided supplied
|
||||
// coins.
|
||||
@ -27,6 +67,41 @@ func NewVaultShareRecord(depositor sdk.AccAddress, supplied ...sdk.Coin) VaultSh
|
||||
}
|
||||
}
|
||||
|
||||
// Validate returns an error if an VaultShareRecord is invalid.
|
||||
func (vsr VaultShareRecord) Validate() error {
|
||||
if vsr.Depositor.Empty() {
|
||||
return fmt.Errorf("depositor is empty")
|
||||
}
|
||||
|
||||
if err := vsr.AmountSupplied.Validate(); err != nil {
|
||||
return fmt.Errorf("invalid vault share record amount supplied: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// VaultShareRecords is a slice of VaultShareRecord.
|
||||
type VaultShareRecords []VaultShareRecord
|
||||
|
||||
// Validate returns an error if a slice of VaultRecords is invalid.
|
||||
func (vsrs VaultShareRecords) Validate() error {
|
||||
addrs := make(map[string]bool)
|
||||
|
||||
for _, vr := range vsrs {
|
||||
if err := vr.Validate(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, found := addrs[vr.Depositor.String()]; found {
|
||||
return fmt.Errorf("duplicate address %s", vr.Depositor.String())
|
||||
}
|
||||
|
||||
addrs[vr.Depositor.String()] = true
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// NewAllowedVaults returns a new AllowedVaults with the given denom and strategy type.
|
||||
func NewAllowedVault(denom string, strategyType StrategyType) AllowedVault {
|
||||
return AllowedVault{
|
||||
@ -55,8 +130,8 @@ func (a AllowedVaults) Validate() error {
|
||||
}
|
||||
|
||||
func (a *AllowedVault) Validate() error {
|
||||
if a.Denom == "" {
|
||||
return ErrInvalidVaultDenom
|
||||
if err := sdk.ValidateDenom(a.Denom); err != nil {
|
||||
return sdkerrors.Wrap(ErrInvalidVaultDenom, err.Error())
|
||||
}
|
||||
|
||||
if a.VaultStrategy == STRATEGY_TYPE_UNSPECIFIED {
|
||||
|
310
x/earn/types/vault_test.go
Normal file
310
x/earn/types/vault_test.go
Normal file
@ -0,0 +1,310 @@
|
||||
package types_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/kava-labs/kava/app"
|
||||
"github.com/kava-labs/kava/x/earn/types"
|
||||
)
|
||||
|
||||
func TestVaultRecordValidate(t *testing.T) {
|
||||
type errArgs struct {
|
||||
expectPass bool
|
||||
contains string
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
vaultRecords types.VaultRecords
|
||||
errArgs errArgs
|
||||
}{
|
||||
{
|
||||
name: "valid vault records",
|
||||
vaultRecords: types.VaultRecords{
|
||||
{
|
||||
Denom: "usdx",
|
||||
TotalSupply: sdk.NewInt64Coin("usdx", 0),
|
||||
},
|
||||
{
|
||||
Denom: "ukava",
|
||||
TotalSupply: sdk.NewInt64Coin("ukava", 5),
|
||||
},
|
||||
},
|
||||
errArgs: errArgs{
|
||||
expectPass: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "invalid - duplicate denom",
|
||||
vaultRecords: types.VaultRecords{
|
||||
{
|
||||
Denom: "usdx",
|
||||
TotalSupply: sdk.NewInt64Coin("usdx", 0),
|
||||
},
|
||||
{
|
||||
Denom: "usdx",
|
||||
TotalSupply: sdk.NewInt64Coin("usdx", 5),
|
||||
},
|
||||
},
|
||||
errArgs: errArgs{
|
||||
expectPass: false,
|
||||
contains: "duplicate vault denom usdx",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "invalid - invalid denom",
|
||||
vaultRecords: types.VaultRecords{
|
||||
{
|
||||
Denom: "",
|
||||
TotalSupply: sdk.NewInt64Coin("ukava", 0),
|
||||
},
|
||||
},
|
||||
errArgs: errArgs{
|
||||
expectPass: false,
|
||||
contains: "invalid denom",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "invalid - mismatch denom",
|
||||
vaultRecords: types.VaultRecords{
|
||||
{
|
||||
Denom: "usdx",
|
||||
TotalSupply: sdk.NewInt64Coin("ukava", 0),
|
||||
},
|
||||
},
|
||||
errArgs: errArgs{
|
||||
expectPass: false,
|
||||
contains: "total supply denom ukava does not match vault record denom usdx",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "invalid - negative",
|
||||
vaultRecords: types.VaultRecords{
|
||||
{
|
||||
Denom: "usdx",
|
||||
TotalSupply: sdk.Coin{Denom: "usdx", Amount: sdk.NewInt(-1)},
|
||||
},
|
||||
},
|
||||
errArgs: errArgs{
|
||||
expectPass: false,
|
||||
contains: "negative coin amount",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
err := test.vaultRecords.Validate()
|
||||
|
||||
if test.errArgs.expectPass {
|
||||
require.NoError(t, err)
|
||||
} else {
|
||||
require.Error(t, err)
|
||||
require.Contains(t, err.Error(), test.errArgs.contains)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestVaultShareRecordsValidate(t *testing.T) {
|
||||
_, addrs := app.GeneratePrivKeyAddressPairs(2)
|
||||
|
||||
type errArgs struct {
|
||||
expectPass bool
|
||||
contains string
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
vaultRecords types.VaultShareRecords
|
||||
errArgs errArgs
|
||||
}{
|
||||
{
|
||||
name: "valid vault share records",
|
||||
vaultRecords: types.VaultShareRecords{
|
||||
{
|
||||
Depositor: addrs[0],
|
||||
AmountSupplied: sdk.NewCoins(
|
||||
sdk.NewInt64Coin("usdx", 0),
|
||||
),
|
||||
},
|
||||
{
|
||||
Depositor: addrs[1],
|
||||
AmountSupplied: sdk.NewCoins(
|
||||
sdk.NewInt64Coin("usdx", 0),
|
||||
sdk.NewInt64Coin("ukava", 5),
|
||||
),
|
||||
},
|
||||
},
|
||||
errArgs: errArgs{
|
||||
expectPass: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "invalid - duplicate address",
|
||||
vaultRecords: types.VaultShareRecords{
|
||||
{
|
||||
Depositor: addrs[0],
|
||||
AmountSupplied: sdk.NewCoins(
|
||||
sdk.NewInt64Coin("usdx", 0),
|
||||
),
|
||||
},
|
||||
{
|
||||
Depositor: addrs[0],
|
||||
AmountSupplied: sdk.NewCoins(
|
||||
sdk.NewInt64Coin("usdx", 0),
|
||||
sdk.NewInt64Coin("ukava", 5),
|
||||
),
|
||||
},
|
||||
},
|
||||
errArgs: errArgs{
|
||||
expectPass: false,
|
||||
contains: "duplicate address",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "invalid - invalid address",
|
||||
vaultRecords: types.VaultShareRecords{
|
||||
{
|
||||
Depositor: sdk.AccAddress{},
|
||||
AmountSupplied: sdk.NewCoins(
|
||||
sdk.NewInt64Coin("usdx", 0),
|
||||
),
|
||||
},
|
||||
},
|
||||
errArgs: errArgs{
|
||||
expectPass: false,
|
||||
contains: "depositor is empty",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "invalid - negative",
|
||||
vaultRecords: types.VaultShareRecords{
|
||||
{
|
||||
Depositor: addrs[0],
|
||||
AmountSupplied: sdk.Coins{
|
||||
sdk.Coin{Denom: "ukava", Amount: sdk.NewInt(-1)},
|
||||
},
|
||||
},
|
||||
},
|
||||
errArgs: errArgs{
|
||||
expectPass: false,
|
||||
contains: "amount is not positive",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
err := test.vaultRecords.Validate()
|
||||
|
||||
if test.errArgs.expectPass {
|
||||
require.NoError(t, err)
|
||||
} else {
|
||||
require.Error(t, err)
|
||||
require.Contains(t, err.Error(), test.errArgs.contains)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestAllowedVaultsValidate(t *testing.T) {
|
||||
type errArgs struct {
|
||||
expectPass bool
|
||||
contains string
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
vaultRecords types.AllowedVaults
|
||||
errArgs errArgs
|
||||
}{
|
||||
{
|
||||
name: "valid vault share records",
|
||||
vaultRecords: types.AllowedVaults{
|
||||
{
|
||||
Denom: "usdx",
|
||||
VaultStrategy: types.STRATEGY_TYPE_HARD,
|
||||
},
|
||||
{
|
||||
Denom: "busd",
|
||||
VaultStrategy: types.STRATEGY_TYPE_HARD,
|
||||
},
|
||||
},
|
||||
errArgs: errArgs{
|
||||
expectPass: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "invalid - duplicate denom",
|
||||
vaultRecords: types.AllowedVaults{
|
||||
{
|
||||
Denom: "usdx",
|
||||
VaultStrategy: types.STRATEGY_TYPE_HARD,
|
||||
},
|
||||
{
|
||||
Denom: "usdx",
|
||||
VaultStrategy: types.STRATEGY_TYPE_HARD,
|
||||
},
|
||||
},
|
||||
errArgs: errArgs{
|
||||
expectPass: false,
|
||||
contains: "duplicate vault denom usdx",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "invalid - invalid denom",
|
||||
vaultRecords: types.AllowedVaults{
|
||||
{
|
||||
Denom: "",
|
||||
VaultStrategy: types.STRATEGY_TYPE_HARD,
|
||||
},
|
||||
},
|
||||
errArgs: errArgs{
|
||||
expectPass: false,
|
||||
contains: "invalid denom",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "invalid - invalid strategy",
|
||||
vaultRecords: types.AllowedVaults{
|
||||
{
|
||||
Denom: "usdx",
|
||||
VaultStrategy: types.STRATEGY_TYPE_UNSPECIFIED,
|
||||
},
|
||||
},
|
||||
errArgs: errArgs{
|
||||
expectPass: false,
|
||||
contains: "invalid vault strategy",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
err := test.vaultRecords.Validate()
|
||||
|
||||
if test.errArgs.expectPass {
|
||||
require.NoError(t, err)
|
||||
} else {
|
||||
require.Error(t, err)
|
||||
require.Contains(t, err.Error(), test.errArgs.contains)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewVaultShareRecord(t *testing.T) {
|
||||
_, addrs := app.GeneratePrivKeyAddressPairs(1)
|
||||
|
||||
coins := sdk.NewCoins(
|
||||
sdk.NewInt64Coin("usdx", 10),
|
||||
sdk.NewInt64Coin("ukava", 5),
|
||||
)
|
||||
|
||||
shareRecord := types.NewVaultShareRecord(addrs[0], coins...)
|
||||
require.Equal(t, coins, shareRecord.AmountSupplied)
|
||||
}
|
Loading…
Reference in New Issue
Block a user