mirror of
https://github.com/0glabs/0g-chain.git
synced 2024-11-10 10:05:18 +00:00
update cdp keeper tests
This commit is contained in:
parent
6f3cb815a2
commit
ce2b2e2213
@ -34,13 +34,14 @@ import (
|
|||||||
// TestApp is a simple wrapper around an App. It exposes internal keepers for use in integration tests.
|
// TestApp is a simple wrapper around an App. It exposes internal keepers for use in integration tests.
|
||||||
// This file also contains test helpers. Ideally they would be in separate package.
|
// This file also contains test helpers. Ideally they would be in separate package.
|
||||||
// Basic Usage:
|
// Basic Usage:
|
||||||
// Create a test app with NewTestApp, then all keepers and their methods can be accessed for test setup and execution.
|
// Create a test app with NewTestApp, then all keepers and their methods can be accessed for test setup and execution.
|
||||||
// Advanced Usage:
|
// Advanced Usage:
|
||||||
// Some tests call for an app to be initialized with some state. This can be achieved through keeper method calls (ie keeper.SetParams(...)).
|
// Some tests call for an app to be initialized with some state. This can be achieved through keeper method calls (ie keeper.SetParams(...)).
|
||||||
// However this leads to a lot of duplicated logic similar to InitGenesis methods.
|
// However this leads to a lot of duplicated logic similar to InitGenesis methods.
|
||||||
// So TestApp.InitializeFromGenesisStates() will call InitGenesis with the default genesis state.
|
// So TestApp.InitializeFromGenesisStates() will call InitGenesis with the default genesis state.
|
||||||
//and TestApp.InitializeFromGenesisStates(authState, cdpState) will do the same but overwrite the auth and cdp sections of the default genesis state
|
// and TestApp.InitializeFromGenesisStates(authState, cdpState) will do the same but overwrite the auth and cdp sections of the default genesis state
|
||||||
// Creating the genesis states can be combersome, but helper methods can make it easier such as NewAuthGenStateFromAccounts below.
|
// Creating the genesis states can be combersome, but helper methods can make it easier such as NewAuthGenStateFromAccounts below.
|
||||||
|
//
|
||||||
type TestApp struct {
|
type TestApp struct {
|
||||||
App
|
App
|
||||||
}
|
}
|
||||||
|
@ -1,19 +1,19 @@
|
|||||||
package keeper
|
package keeper_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
"github.com/cosmos/cosmos-sdk/x/auth"
|
|
||||||
authexported "github.com/cosmos/cosmos-sdk/x/auth/exported"
|
|
||||||
"github.com/cosmos/cosmos-sdk/x/mock"
|
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
abci "github.com/tendermint/tendermint/abci/types"
|
abci "github.com/tendermint/tendermint/abci/types"
|
||||||
|
|
||||||
|
"github.com/kava-labs/kava/app"
|
||||||
|
keep "github.com/kava-labs/kava/x/cdp/keeper"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Test the bank functionality of the CDP keeper
|
// Test the bank functionality of the CDP keeper
|
||||||
func TestKeeper_AddSubtractGetCoins(t *testing.T) {
|
func TestKeeper_AddSubtractGetCoins(t *testing.T) {
|
||||||
_, addrs := mock.GeneratePrivKeyAddressPairs(1)
|
_, addrs := app.GeneratePrivKeyAddressPairs(1)
|
||||||
normalAddr := addrs[0]
|
normalAddr := addrs[0]
|
||||||
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
@ -25,28 +25,23 @@ func TestKeeper_AddSubtractGetCoins(t *testing.T) {
|
|||||||
}{
|
}{
|
||||||
{"addNormalAddress", normalAddr, true, cs(c("usdx", 53)), cs(c("usdx", 153), c("kava", 100))},
|
{"addNormalAddress", normalAddr, true, cs(c("usdx", 53)), cs(c("usdx", 153), c("kava", 100))},
|
||||||
{"subNormalAddress", normalAddr, false, cs(c("usdx", 53)), cs(c("usdx", 47), c("kava", 100))},
|
{"subNormalAddress", normalAddr, false, cs(c("usdx", 53)), cs(c("usdx", 47), c("kava", 100))},
|
||||||
{"addLiquidatorStable", LiquidatorAccountAddress, true, cs(c("usdx", 53)), cs(c("usdx", 153))},
|
{"addLiquidatorStable", keep.LiquidatorAccountAddress, true, cs(c("usdx", 53)), cs(c("usdx", 153))},
|
||||||
{"subLiquidatorStable", LiquidatorAccountAddress, false, cs(c("usdx", 53)), cs(c("usdx", 47))},
|
{"subLiquidatorStable", keep.LiquidatorAccountAddress, false, cs(c("usdx", 53)), cs(c("usdx", 47))},
|
||||||
{"addLiquidatorGov", LiquidatorAccountAddress, true, cs(c("kava", 53)), cs(c("usdx", 100))}, // no change to balance
|
{"addLiquidatorGov", keep.LiquidatorAccountAddress, true, cs(c("kava", 53)), cs(c("usdx", 100))}, // no change to balance
|
||||||
{"subLiquidatorGov", LiquidatorAccountAddress, false, cs(c("kava", 53)), cs(c("usdx", 100))}, // no change to balance
|
{"subLiquidatorGov", keep.LiquidatorAccountAddress, false, cs(c("kava", 53)), cs(c("usdx", 100))}, // no change to balance
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, tc := range tests {
|
for _, tc := range tests {
|
||||||
t.Run(tc.name, func(t *testing.T) {
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
// setup keeper
|
// setup app with an account
|
||||||
mapp, keeper, _, _ := setUpMockAppWithoutGenesis()
|
tApp := app.NewTestApp()
|
||||||
// initialize an account with coins
|
authGenState := tApp.NewAuthGenStateFromAccounts([]sdk.AccAddress{normalAddr}, []sdk.Coins{cs(c("usdx", 100), c("kava", 100))})
|
||||||
genAcc := auth.BaseAccount{
|
tApp.InitializeFromGenesisStates(authGenState)
|
||||||
Address: normalAddr,
|
|
||||||
Coins: cs(c("usdx", 100), c("kava", 100)),
|
|
||||||
}
|
|
||||||
mock.SetGenesis(mapp, []authexported.Account{&genAcc})
|
|
||||||
|
|
||||||
// create a new context and setup the liquidator account
|
// create a new context and setup the liquidator account
|
||||||
header := abci.Header{Height: mapp.LastBlockHeight() + 1}
|
ctx := tApp.NewContext(false, abci.Header{})
|
||||||
mapp.BeginBlock(abci.RequestBeginBlock{Header: header})
|
keeper := tApp.GetCDPKeeper()
|
||||||
ctx := mapp.BaseApp.NewContext(false, header)
|
keeper.SetLiquidatorModuleAccount(ctx, keep.LiquidatorModuleAccount{cs(c("usdx", 100))}) // set gov coin "balance" to zero
|
||||||
keeper.setLiquidatorModuleAccount(ctx, LiquidatorModuleAccount{cs(c("usdx", 100))}) // set gov coin "balance" to zero
|
|
||||||
|
|
||||||
// perform the test action
|
// perform the test action
|
||||||
var err sdk.Error
|
var err sdk.Error
|
||||||
@ -56,9 +51,6 @@ func TestKeeper_AddSubtractGetCoins(t *testing.T) {
|
|||||||
_, err = keeper.SubtractCoins(ctx, tc.address, tc.amount)
|
_, err = keeper.SubtractCoins(ctx, tc.address, tc.amount)
|
||||||
}
|
}
|
||||||
|
|
||||||
mapp.EndBlock(abci.RequestEndBlock{})
|
|
||||||
mapp.Commit()
|
|
||||||
|
|
||||||
// check balances are as expected
|
// check balances are as expected
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, tc.expectedCoins, keeper.GetCoins(ctx, tc.address))
|
require.Equal(t, tc.expectedCoins, keeper.GetCoins(ctx, tc.address))
|
||||||
|
46
x/cdp/keeper/integration_test.go
Normal file
46
x/cdp/keeper/integration_test.go
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
package keeper_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
|
|
||||||
|
"github.com/kava-labs/kava/x/cdp/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Avoid cluttering test cases with long function name
|
||||||
|
func i(in int64) sdk.Int { return sdk.NewInt(in) }
|
||||||
|
func d(str string) sdk.Dec { return sdk.MustNewDecFromStr(str) }
|
||||||
|
func c(denom string, amount int64) sdk.Coin { return sdk.NewInt64Coin(denom, amount) }
|
||||||
|
func cs(coins ...sdk.Coin) sdk.Coins { return sdk.NewCoins(coins...) }
|
||||||
|
|
||||||
|
func defaultParamsMulti() types.CdpParams {
|
||||||
|
return types.CdpParams{
|
||||||
|
GlobalDebtLimit: sdk.NewInt(1000000),
|
||||||
|
CollateralParams: []types.CollateralParams{
|
||||||
|
{
|
||||||
|
Denom: "btc",
|
||||||
|
LiquidationRatio: sdk.MustNewDecFromStr("1.5"),
|
||||||
|
DebtLimit: sdk.NewInt(500000),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Denom: "xrp",
|
||||||
|
LiquidationRatio: sdk.MustNewDecFromStr("2.0"),
|
||||||
|
DebtLimit: sdk.NewInt(500000),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
StableDenoms: []string{"usdx"},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func defaultParamsSingle() types.CdpParams {
|
||||||
|
return types.CdpParams{
|
||||||
|
GlobalDebtLimit: sdk.NewInt(1000000),
|
||||||
|
CollateralParams: []types.CollateralParams{
|
||||||
|
{
|
||||||
|
Denom: "xrp",
|
||||||
|
LiquidationRatio: sdk.MustNewDecFromStr("2.0"),
|
||||||
|
DebtLimit: sdk.NewInt(500000),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
StableDenoms: []string{"usdx"},
|
||||||
|
}
|
||||||
|
}
|
@ -126,13 +126,13 @@ func (k Keeper) ModifyCDP(ctx sdk.Context, owner sdk.AccAddress, collateralDenom
|
|||||||
}
|
}
|
||||||
// Set CDP
|
// Set CDP
|
||||||
if cdp.CollateralAmount.IsZero() && cdp.Debt.IsZero() { // TODO maybe abstract this logic into SetCDP
|
if cdp.CollateralAmount.IsZero() && cdp.Debt.IsZero() { // TODO maybe abstract this logic into SetCDP
|
||||||
k.deleteCDP(ctx, cdp)
|
k.DeleteCDP(ctx, cdp)
|
||||||
} else {
|
} else {
|
||||||
k.SetCDP(ctx, cdp)
|
k.SetCDP(ctx, cdp)
|
||||||
}
|
}
|
||||||
// set total debts
|
// set total debts
|
||||||
k.SetGlobalDebt(ctx, gDebt)
|
k.SetGlobalDebt(ctx, gDebt)
|
||||||
k.setCollateralState(ctx, collateralState)
|
k.SetCollateralState(ctx, collateralState)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -195,11 +195,11 @@ func (k Keeper) PartialSeizeCDP(ctx sdk.Context, owner sdk.AccAddress, collatera
|
|||||||
|
|
||||||
// Store updated state
|
// Store updated state
|
||||||
if cdp.CollateralAmount.IsZero() && cdp.Debt.IsZero() { // TODO maybe abstract this logic into SetCDP
|
if cdp.CollateralAmount.IsZero() && cdp.Debt.IsZero() { // TODO maybe abstract this logic into SetCDP
|
||||||
k.deleteCDP(ctx, cdp)
|
k.DeleteCDP(ctx, cdp)
|
||||||
} else {
|
} else {
|
||||||
k.SetCDP(ctx, cdp)
|
k.SetCDP(ctx, cdp)
|
||||||
}
|
}
|
||||||
k.setCollateralState(ctx, collateralState)
|
k.SetCollateralState(ctx, collateralState)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -264,7 +264,7 @@ func (k Keeper) SetCDP(ctx sdk.Context, cdp types.CDP) {
|
|||||||
bz := k.cdc.MustMarshalBinaryLengthPrefixed(cdp)
|
bz := k.cdc.MustMarshalBinaryLengthPrefixed(cdp)
|
||||||
store.Set(k.getCDPKey(cdp.Owner, cdp.CollateralDenom), bz)
|
store.Set(k.getCDPKey(cdp.Owner, cdp.CollateralDenom), bz)
|
||||||
}
|
}
|
||||||
func (k Keeper) deleteCDP(ctx sdk.Context, cdp types.CDP) { // TODO should this id the cdp by passing in owner,collateralDenom pair?
|
func (k Keeper) DeleteCDP(ctx sdk.Context, cdp types.CDP) { // TODO should this id the cdp by passing in owner,collateralDenom pair?
|
||||||
// get store
|
// get store
|
||||||
store := ctx.KVStore(k.key)
|
store := ctx.KVStore(k.key)
|
||||||
// delete key
|
// delete key
|
||||||
@ -354,7 +354,7 @@ func (k Keeper) GetCollateralState(ctx sdk.Context, collateralDenom string) (typ
|
|||||||
k.cdc.MustUnmarshalBinaryLengthPrefixed(bz, &collateralState)
|
k.cdc.MustUnmarshalBinaryLengthPrefixed(bz, &collateralState)
|
||||||
return collateralState, true
|
return collateralState, true
|
||||||
}
|
}
|
||||||
func (k Keeper) setCollateralState(ctx sdk.Context, collateralstate types.CollateralState) {
|
func (k Keeper) SetCollateralState(ctx sdk.Context, collateralstate types.CollateralState) {
|
||||||
// get store
|
// get store
|
||||||
store := ctx.KVStore(k.key)
|
store := ctx.KVStore(k.key)
|
||||||
// marshal and set
|
// marshal and set
|
||||||
@ -422,7 +422,7 @@ func (k Keeper) AddCoins(ctx sdk.Context, address sdk.AccAddress, amount sdk.Coi
|
|||||||
return amount, sdk.ErrInsufficientCoins(fmt.Sprintf("insufficient account funds; %s < %s", lma.Coins, amount))
|
return amount, sdk.ErrInsufficientCoins(fmt.Sprintf("insufficient account funds; %s < %s", lma.Coins, amount))
|
||||||
}
|
}
|
||||||
lma.Coins = updatedCoins
|
lma.Coins = updatedCoins
|
||||||
k.setLiquidatorModuleAccount(ctx, lma)
|
k.SetLiquidatorModuleAccount(ctx, lma)
|
||||||
return updatedCoins, nil
|
return updatedCoins, nil
|
||||||
} else {
|
} else {
|
||||||
return k.bankKeeper.AddCoins(ctx, address, amount)
|
return k.bankKeeper.AddCoins(ctx, address, amount)
|
||||||
@ -445,7 +445,7 @@ func (k Keeper) SubtractCoins(ctx sdk.Context, address sdk.AccAddress, amount sd
|
|||||||
return amount, sdk.ErrInsufficientCoins(fmt.Sprintf("insufficient account funds; %s < %s", lma.Coins, amount))
|
return amount, sdk.ErrInsufficientCoins(fmt.Sprintf("insufficient account funds; %s < %s", lma.Coins, amount))
|
||||||
}
|
}
|
||||||
lma.Coins = updatedCoins
|
lma.Coins = updatedCoins
|
||||||
k.setLiquidatorModuleAccount(ctx, lma)
|
k.SetLiquidatorModuleAccount(ctx, lma)
|
||||||
return updatedCoins, nil
|
return updatedCoins, nil
|
||||||
} else {
|
} else {
|
||||||
return k.bankKeeper.SubtractCoins(ctx, address, amount)
|
return k.bankKeeper.SubtractCoins(ctx, address, amount)
|
||||||
@ -483,7 +483,7 @@ func (k Keeper) getLiquidatorModuleAccount(ctx sdk.Context) LiquidatorModuleAcco
|
|||||||
k.cdc.MustUnmarshalBinaryLengthPrefixed(bz, &lma)
|
k.cdc.MustUnmarshalBinaryLengthPrefixed(bz, &lma)
|
||||||
return lma
|
return lma
|
||||||
}
|
}
|
||||||
func (k Keeper) setLiquidatorModuleAccount(ctx sdk.Context, lma LiquidatorModuleAccount) {
|
func (k Keeper) SetLiquidatorModuleAccount(ctx sdk.Context, lma LiquidatorModuleAccount) {
|
||||||
store := ctx.KVStore(k.key)
|
store := ctx.KVStore(k.key)
|
||||||
bz := k.cdc.MustMarshalBinaryLengthPrefixed(lma)
|
bz := k.cdc.MustMarshalBinaryLengthPrefixed(lma)
|
||||||
store.Set(liquidatorAccountKey, bz)
|
store.Set(liquidatorAccountKey, bz)
|
||||||
|
@ -1,27 +1,26 @@
|
|||||||
package keeper
|
package keeper_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
"github.com/cosmos/cosmos-sdk/x/auth"
|
|
||||||
authexported "github.com/cosmos/cosmos-sdk/x/auth/exported"
|
|
||||||
"github.com/cosmos/cosmos-sdk/x/mock"
|
|
||||||
"github.com/kava-labs/kava/x/cdp/types"
|
|
||||||
"github.com/kava-labs/kava/x/pricefeed"
|
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
abci "github.com/tendermint/tendermint/abci/types"
|
abci "github.com/tendermint/tendermint/abci/types"
|
||||||
|
|
||||||
|
"github.com/kava-labs/kava/app"
|
||||||
|
"github.com/kava-labs/kava/x/cdp/types"
|
||||||
|
"github.com/kava-labs/kava/x/pricefeed"
|
||||||
)
|
)
|
||||||
|
|
||||||
// How could one reduce the number of params in the test cases. Create a table driven test for each of the 4 add/withdraw collateral/debt?
|
// How could one reduce the number of params in the test cases. Create a table driven test for each of the 4 add/withdraw collateral/debt?
|
||||||
|
|
||||||
// These are more like app level tests - I think this is a symptom of having 'ModifyCDP' do a lot. Could be easier for testing purposes to break it down.
|
// These are more like app level tests - I think this is a symptom of having 'ModifyCDP' do a lot. Could be easier for testing purposes to break it down.
|
||||||
func TestKeeper_ModifyCDP(t *testing.T) {
|
func TestKeeper_ModifyCDP(t *testing.T) {
|
||||||
_, addrs := mock.GeneratePrivKeyAddressPairs(1)
|
_, addrs := app.GeneratePrivKeyAddressPairs(1)
|
||||||
ownerAddr := addrs[0]
|
ownerAddr := addrs[0]
|
||||||
|
|
||||||
type state struct { // TODO this allows invalid state to be set up, should it?
|
type state struct {
|
||||||
CDP types.CDP
|
CDP types.CDP
|
||||||
OwnerCoins sdk.Coins
|
OwnerCoins sdk.Coins
|
||||||
GlobalDebt sdk.Int
|
GlobalDebt sdk.Int
|
||||||
@ -95,26 +94,24 @@ func TestKeeper_ModifyCDP(t *testing.T) {
|
|||||||
for _, tc := range tests {
|
for _, tc := range tests {
|
||||||
t.Run(tc.name, func(t *testing.T) {
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
// setup keeper
|
// setup keeper
|
||||||
mapp, keeper, _, _ := setUpMockAppWithoutGenesis()
|
tApp := app.NewTestApp()
|
||||||
// initialize cdp owner account with coins
|
// initialize cdp owner account with coins
|
||||||
genAcc := auth.BaseAccount{
|
authGen := tApp.NewAuthGenStateFromAccounts([]sdk.AccAddress{ownerAddr}, []sdk.Coins{tc.priorState.OwnerCoins})
|
||||||
Address: ownerAddr,
|
tApp.InitializeFromGenesisStates(authGen)
|
||||||
Coins: tc.priorState.OwnerCoins,
|
// create a context for db access
|
||||||
}
|
ctx := tApp.NewContext(false, abci.Header{})
|
||||||
mock.SetGenesis(mapp, []authexported.Account{&genAcc})
|
|
||||||
// create a new context
|
|
||||||
header := abci.Header{Height: mapp.LastBlockHeight() + 1}
|
|
||||||
mapp.BeginBlock(abci.RequestBeginBlock{Header: header})
|
|
||||||
ctx := mapp.BaseApp.NewContext(false, header)
|
|
||||||
keeper.SetParams(ctx, defaultParamsSingle())
|
|
||||||
// setup store state
|
// setup store state
|
||||||
|
keeper := tApp.GetCDPKeeper()
|
||||||
|
keeper.SetParams(ctx, defaultParamsSingle())
|
||||||
|
pricefeedKeeper := tApp.GetPriceFeedKeeper()
|
||||||
ap := pricefeed.AssetParams{
|
ap := pricefeed.AssetParams{
|
||||||
Assets: []pricefeed.Asset{
|
Assets: []pricefeed.Asset{
|
||||||
pricefeed.Asset{AssetCode: "xrp", Description: ""},
|
pricefeed.Asset{AssetCode: "xrp", Description: ""},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
keeper.pricefeedKeeper.SetAssetParams(ctx, ap)
|
pricefeedKeeper.SetAssetParams(ctx, ap)
|
||||||
_, err := keeper.pricefeedKeeper.SetPrice(
|
_, err := pricefeedKeeper.SetPrice(
|
||||||
ctx, ownerAddr, "xrp",
|
ctx, ownerAddr, "xrp",
|
||||||
sdk.MustNewDecFromStr(tc.price),
|
sdk.MustNewDecFromStr(tc.price),
|
||||||
sdk.NewInt(ctx.BlockHeight()+10))
|
sdk.NewInt(ctx.BlockHeight()+10))
|
||||||
@ -123,7 +120,7 @@ func TestKeeper_ModifyCDP(t *testing.T) {
|
|||||||
t.Log(err)
|
t.Log(err)
|
||||||
t.Log(tc.name)
|
t.Log(tc.name)
|
||||||
}
|
}
|
||||||
err = keeper.pricefeedKeeper.SetCurrentPrices(ctx)
|
err = pricefeedKeeper.SetCurrentPrices(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Log("test context height", ctx.BlockHeight())
|
t.Log("test context height", ctx.BlockHeight())
|
||||||
t.Log(err)
|
t.Log(err)
|
||||||
@ -134,20 +131,17 @@ func TestKeeper_ModifyCDP(t *testing.T) {
|
|||||||
}
|
}
|
||||||
keeper.SetGlobalDebt(ctx, tc.priorState.GlobalDebt)
|
keeper.SetGlobalDebt(ctx, tc.priorState.GlobalDebt)
|
||||||
if tc.priorState.CollateralState.Denom != "" {
|
if tc.priorState.CollateralState.Denom != "" {
|
||||||
keeper.setCollateralState(ctx, tc.priorState.CollateralState)
|
keeper.SetCollateralState(ctx, tc.priorState.CollateralState)
|
||||||
}
|
}
|
||||||
|
|
||||||
// call func under test
|
// call func under test
|
||||||
err = keeper.ModifyCDP(ctx, tc.args.owner, tc.args.collateralDenom, tc.args.changeInCollateral, tc.args.changeInDebt)
|
err = keeper.ModifyCDP(ctx, tc.args.owner, tc.args.collateralDenom, tc.args.changeInCollateral, tc.args.changeInDebt)
|
||||||
mapp.EndBlock(abci.RequestEndBlock{})
|
|
||||||
mapp.Commit()
|
|
||||||
|
|
||||||
// get new state for verification
|
// get new state for verification
|
||||||
actualCDP, found := keeper.GetCDP(ctx, tc.args.owner, tc.args.collateralDenom)
|
actualCDP, found := keeper.GetCDP(ctx, tc.args.owner, tc.args.collateralDenom)
|
||||||
if tc.name == "removeTooMuchCollateral" {
|
if tc.name == "removeTooMuchCollateral" {
|
||||||
t.Log(actualCDP.String())
|
t.Log(actualCDP.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
// check for err
|
// check for err
|
||||||
if tc.expectPass {
|
if tc.expectPass {
|
||||||
require.NoError(t, err, fmt.Sprint(err))
|
require.NoError(t, err, fmt.Sprint(err))
|
||||||
@ -166,45 +160,48 @@ func TestKeeper_ModifyCDP(t *testing.T) {
|
|||||||
require.Equal(t, tc.expectedState.GlobalDebt, actualGDebt)
|
require.Equal(t, tc.expectedState.GlobalDebt, actualGDebt)
|
||||||
require.Equal(t, tc.expectedState.CollateralState, actualCstate)
|
require.Equal(t, tc.expectedState.CollateralState, actualCstate)
|
||||||
// check owner balance
|
// check owner balance
|
||||||
mock.CheckBalance(t, mapp, ownerAddr, tc.expectedState.OwnerCoins)
|
require.Equal(t, tc.expectedState.OwnerCoins, tApp.GetAccountKeeper().GetAccount(ctx, ownerAddr).GetCoins())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO change to table driven test to test more test cases
|
|
||||||
func TestKeeper_PartialSeizeCDP(t *testing.T) {
|
func TestKeeper_PartialSeizeCDP(t *testing.T) {
|
||||||
// Setup
|
// Setup
|
||||||
const collateral = "xrp"
|
const collateral = "xrp"
|
||||||
mapp, keeper, _, _ := setUpMockAppWithoutGenesis()
|
_, addrs := app.GeneratePrivKeyAddressPairs(1)
|
||||||
genAccs, addrs, _, _ := mock.CreateGenAccounts(1, cs(c(collateral, 100)))
|
|
||||||
testAddr := addrs[0]
|
testAddr := addrs[0]
|
||||||
mock.SetGenesis(mapp, genAccs)
|
|
||||||
|
tApp := app.NewTestApp()
|
||||||
|
authGenState := tApp.NewAuthGenStateFromAccounts(addrs, []sdk.Coins{cs(c(collateral, 100))})
|
||||||
|
tApp.InitializeFromGenesisStates(authGenState)
|
||||||
|
|
||||||
|
ctx := tApp.NewContext(false, abci.Header{})
|
||||||
|
keeper := tApp.GetCDPKeeper()
|
||||||
|
|
||||||
// setup pricefeed
|
// setup pricefeed
|
||||||
header := abci.Header{Height: mapp.LastBlockHeight() + 1}
|
pricefeedKeeper := tApp.GetPriceFeedKeeper()
|
||||||
mapp.BeginBlock(abci.RequestBeginBlock{Header: header})
|
|
||||||
ctx := mapp.BaseApp.NewContext(false, header)
|
|
||||||
keeper.SetParams(ctx, defaultParamsSingle())
|
|
||||||
ap := pricefeed.AssetParams{
|
ap := pricefeed.AssetParams{
|
||||||
Assets: []pricefeed.Asset{
|
Assets: []pricefeed.Asset{
|
||||||
pricefeed.Asset{AssetCode: "xrp", Description: ""},
|
pricefeed.Asset{AssetCode: collateral, Description: ""},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
keeper.pricefeedKeeper.SetAssetParams(ctx, ap)
|
pricefeedKeeper.SetAssetParams(ctx, ap)
|
||||||
keeper.pricefeedKeeper.SetPrice(
|
pricefeedKeeper.SetPrice(
|
||||||
ctx, sdk.AccAddress{}, collateral,
|
ctx, sdk.AccAddress{}, collateral,
|
||||||
sdk.MustNewDecFromStr("1.00"),
|
sdk.MustNewDecFromStr("1.00"),
|
||||||
i(10))
|
i(10))
|
||||||
keeper.pricefeedKeeper.SetCurrentPrices(ctx)
|
require.NoError(t, pricefeedKeeper.SetCurrentPrices(ctx))
|
||||||
|
|
||||||
// Create CDP
|
// Create CDP
|
||||||
keeper.SetGlobalDebt(ctx, i(0))
|
keeper.SetParams(ctx, defaultParamsSingle())
|
||||||
err := keeper.ModifyCDP(ctx, testAddr, collateral, i(10), i(5))
|
err := keeper.ModifyCDP(ctx, testAddr, collateral, i(10), i(5))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
// Reduce price
|
// Reduce price
|
||||||
keeper.pricefeedKeeper.SetPrice(
|
pricefeedKeeper.SetPrice(
|
||||||
ctx, sdk.AccAddress{}, collateral,
|
ctx, sdk.AccAddress{}, collateral,
|
||||||
sdk.MustNewDecFromStr("0.90"),
|
sdk.MustNewDecFromStr("0.90"),
|
||||||
i(10))
|
i(10))
|
||||||
keeper.pricefeedKeeper.SetCurrentPrices(ctx)
|
require.NoError(t, pricefeedKeeper.SetCurrentPrices(ctx))
|
||||||
|
|
||||||
// Seize entire CDP
|
// Seize entire CDP
|
||||||
err = keeper.PartialSeizeCDP(ctx, testAddr, collateral, i(10), i(5))
|
err = keeper.PartialSeizeCDP(ctx, testAddr, collateral, i(10), i(5))
|
||||||
@ -220,14 +217,12 @@ func TestKeeper_PartialSeizeCDP(t *testing.T) {
|
|||||||
|
|
||||||
func TestKeeper_GetCDPs(t *testing.T) {
|
func TestKeeper_GetCDPs(t *testing.T) {
|
||||||
// setup keeper
|
// setup keeper
|
||||||
mapp, keeper, _, _ := setUpMockAppWithoutGenesis()
|
tApp := app.NewTestApp()
|
||||||
mock.SetGenesis(mapp, []authexported.Account(nil))
|
ctx := tApp.NewContext(true, abci.Header{})
|
||||||
header := abci.Header{Height: mapp.LastBlockHeight() + 1}
|
keeper := tApp.GetCDPKeeper()
|
||||||
mapp.BeginBlock(abci.RequestBeginBlock{Header: header})
|
|
||||||
ctx := mapp.BaseApp.NewContext(false, header)
|
|
||||||
keeper.SetParams(ctx, defaultParamsMulti())
|
keeper.SetParams(ctx, defaultParamsMulti())
|
||||||
// setup CDPs
|
// setup CDPs
|
||||||
_, addrs := mock.GeneratePrivKeyAddressPairs(2)
|
_, addrs := app.GeneratePrivKeyAddressPairs(2)
|
||||||
cdps := types.CDPs{
|
cdps := types.CDPs{
|
||||||
{addrs[0], "xrp", i(4000), i(5)},
|
{addrs[0], "xrp", i(4000), i(5)},
|
||||||
{addrs[1], "xrp", i(4000), i(2000)},
|
{addrs[1], "xrp", i(4000), i(2000)},
|
||||||
@ -285,7 +280,7 @@ func TestKeeper_GetCDPs(t *testing.T) {
|
|||||||
_, err = keeper.GetCDPs(ctx, "", d("0.34023"))
|
_, err = keeper.GetCDPs(ctx, "", d("0.34023"))
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
// Check deleting a CDP removes it
|
// Check deleting a CDP removes it
|
||||||
keeper.deleteCDP(ctx, cdps[0])
|
keeper.DeleteCDP(ctx, cdps[0])
|
||||||
returnedCdps, err = keeper.GetCDPs(ctx, "", sdk.Dec{})
|
returnedCdps, err = keeper.GetCDPs(ctx, "", sdk.Dec{})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t,
|
require.Equal(t,
|
||||||
@ -295,14 +290,15 @@ func TestKeeper_GetCDPs(t *testing.T) {
|
|||||||
returnedCdps,
|
returnedCdps,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestKeeper_GetSetDeleteCDP(t *testing.T) {
|
func TestKeeper_GetSetDeleteCDP(t *testing.T) {
|
||||||
// setup keeper, create CDP
|
// setup keeper, create CDP
|
||||||
mapp, keeper, _, _ := setUpMockAppWithoutGenesis()
|
tApp := app.NewTestApp()
|
||||||
header := abci.Header{Height: mapp.LastBlockHeight() + 1}
|
ctx := tApp.NewContext(true, abci.Header{})
|
||||||
mapp.BeginBlock(abci.RequestBeginBlock{Header: header})
|
keeper := tApp.GetCDPKeeper()
|
||||||
ctx := mapp.BaseApp.NewContext(false, header)
|
|
||||||
keeper.SetParams(ctx, defaultParamsSingle())
|
keeper.SetParams(ctx, defaultParamsSingle())
|
||||||
_, addrs := mock.GeneratePrivKeyAddressPairs(1)
|
_, addrs := app.GeneratePrivKeyAddressPairs(1)
|
||||||
cdp := types.CDP{addrs[0], "xrp", i(412), i(56)}
|
cdp := types.CDP{addrs[0], "xrp", i(412), i(56)}
|
||||||
|
|
||||||
// write and read from store
|
// write and read from store
|
||||||
@ -314,7 +310,7 @@ func TestKeeper_GetSetDeleteCDP(t *testing.T) {
|
|||||||
require.Equal(t, cdp, readCDP)
|
require.Equal(t, cdp, readCDP)
|
||||||
|
|
||||||
// delete auction
|
// delete auction
|
||||||
keeper.deleteCDP(ctx, cdp)
|
keeper.DeleteCDP(ctx, cdp)
|
||||||
|
|
||||||
// check auction does not exist
|
// check auction does not exist
|
||||||
_, found = keeper.GetCDP(ctx, cdp.Owner, cdp.CollateralDenom)
|
_, found = keeper.GetCDP(ctx, cdp.Owner, cdp.CollateralDenom)
|
||||||
@ -322,10 +318,9 @@ func TestKeeper_GetSetDeleteCDP(t *testing.T) {
|
|||||||
}
|
}
|
||||||
func TestKeeper_GetSetGDebt(t *testing.T) {
|
func TestKeeper_GetSetGDebt(t *testing.T) {
|
||||||
// setup keeper, create GDebt
|
// setup keeper, create GDebt
|
||||||
mapp, keeper, _, _ := setUpMockAppWithoutGenesis()
|
tApp := app.NewTestApp()
|
||||||
header := abci.Header{Height: mapp.LastBlockHeight() + 1}
|
ctx := tApp.NewContext(true, abci.Header{})
|
||||||
mapp.BeginBlock(abci.RequestBeginBlock{Header: header})
|
keeper := tApp.GetCDPKeeper()
|
||||||
ctx := mapp.BaseApp.NewContext(false, header)
|
|
||||||
keeper.SetParams(ctx, defaultParamsSingle())
|
keeper.SetParams(ctx, defaultParamsSingle())
|
||||||
gDebt := i(4120000)
|
gDebt := i(4120000)
|
||||||
|
|
||||||
@ -339,15 +334,14 @@ func TestKeeper_GetSetGDebt(t *testing.T) {
|
|||||||
|
|
||||||
func TestKeeper_GetSetCollateralState(t *testing.T) {
|
func TestKeeper_GetSetCollateralState(t *testing.T) {
|
||||||
// setup keeper, create CState
|
// setup keeper, create CState
|
||||||
mapp, keeper, _, _ := setUpMockAppWithoutGenesis()
|
tApp := app.NewTestApp()
|
||||||
header := abci.Header{Height: mapp.LastBlockHeight() + 1}
|
ctx := tApp.NewContext(true, abci.Header{})
|
||||||
mapp.BeginBlock(abci.RequestBeginBlock{Header: header})
|
keeper := tApp.GetCDPKeeper()
|
||||||
ctx := mapp.BaseApp.NewContext(false, header)
|
|
||||||
keeper.SetParams(ctx, defaultParamsSingle())
|
keeper.SetParams(ctx, defaultParamsSingle())
|
||||||
collateralState := types.CollateralState{"xrp", i(15400)}
|
collateralState := types.CollateralState{"xrp", i(15400)}
|
||||||
|
|
||||||
// write and read from store
|
// write and read from store
|
||||||
keeper.setCollateralState(ctx, collateralState)
|
keeper.SetCollateralState(ctx, collateralState)
|
||||||
readCState, found := keeper.GetCollateralState(ctx, collateralState.Denom)
|
readCState, found := keeper.GetCollateralState(ctx, collateralState.Denom)
|
||||||
|
|
||||||
// check before and after match
|
// check before and after match
|
||||||
|
@ -1,88 +0,0 @@
|
|||||||
package keeper
|
|
||||||
|
|
||||||
import (
|
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
|
||||||
"github.com/cosmos/cosmos-sdk/x/bank"
|
|
||||||
"github.com/cosmos/cosmos-sdk/x/mock"
|
|
||||||
|
|
||||||
"github.com/kava-labs/kava/x/cdp/types"
|
|
||||||
"github.com/kava-labs/kava/x/pricefeed"
|
|
||||||
"github.com/tendermint/tendermint/crypto"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Mock app is an ABCI app with an in memory database.
|
|
||||||
// This function creates an app, setting up the keepers, routes, begin and end blockers.
|
|
||||||
// But leaves it to the tests to call InitChain (done by calling mock.SetGenesis)
|
|
||||||
// The app works by submitting ABCI messages.
|
|
||||||
// - InitChain sets up the app db from genesis.
|
|
||||||
// - BeginBlock starts the delivery of a new block
|
|
||||||
// - DeliverTx delivers a tx
|
|
||||||
// - EndBlock signals the end of a block
|
|
||||||
// - Commit ?
|
|
||||||
func setUpMockAppWithoutGenesis() (*mock.App, Keeper, []sdk.AccAddress, []crypto.PrivKey) {
|
|
||||||
// Create uninitialized mock app
|
|
||||||
mapp := mock.NewApp()
|
|
||||||
|
|
||||||
// Register codecs
|
|
||||||
types.RegisterCodec(mapp.Cdc)
|
|
||||||
|
|
||||||
// Create keepers
|
|
||||||
keyCDP := sdk.NewKVStoreKey("cdp")
|
|
||||||
keyPriceFeed := sdk.NewKVStoreKey(pricefeed.StoreKey)
|
|
||||||
pk := mapp.ParamsKeeper
|
|
||||||
priceFeedKeeper := pricefeed.NewKeeper(keyPriceFeed, mapp.Cdc, pk.Subspace(pricefeed.DefaultParamspace).WithKeyTable(pricefeed.ParamKeyTable()), pricefeed.DefaultCodespace)
|
|
||||||
blacklistedAddrs := make(map[string]bool)
|
|
||||||
bankKeeper := bank.NewBaseKeeper(mapp.AccountKeeper, pk.Subspace(bank.DefaultParamspace), bank.DefaultCodespace, blacklistedAddrs)
|
|
||||||
cdpKeeper := NewKeeper(mapp.Cdc, keyCDP, pk.Subspace(types.DefaultParamspace), priceFeedKeeper, bankKeeper)
|
|
||||||
|
|
||||||
// Mount and load the stores
|
|
||||||
err := mapp.CompleteSetup(keyPriceFeed, keyCDP)
|
|
||||||
if err != nil {
|
|
||||||
panic("mock app setup failed")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create a bunch (ie 10) of pre-funded accounts to use for tests
|
|
||||||
genAccs, addrs, _, privKeys := mock.CreateGenAccounts(10, sdk.NewCoins(sdk.NewInt64Coin("token1", 100), sdk.NewInt64Coin("token2", 100)))
|
|
||||||
mock.SetGenesis(mapp, genAccs)
|
|
||||||
|
|
||||||
return mapp, cdpKeeper, addrs, privKeys
|
|
||||||
}
|
|
||||||
|
|
||||||
// Avoid cluttering test cases with long function name
|
|
||||||
func i(in int64) sdk.Int { return sdk.NewInt(in) }
|
|
||||||
func d(str string) sdk.Dec { return sdk.MustNewDecFromStr(str) }
|
|
||||||
func c(denom string, amount int64) sdk.Coin { return sdk.NewInt64Coin(denom, amount) }
|
|
||||||
func cs(coins ...sdk.Coin) sdk.Coins { return sdk.NewCoins(coins...) }
|
|
||||||
|
|
||||||
func defaultParamsMulti() types.CdpParams {
|
|
||||||
return types.CdpParams{
|
|
||||||
GlobalDebtLimit: sdk.NewInt(1000000),
|
|
||||||
CollateralParams: []types.CollateralParams{
|
|
||||||
{
|
|
||||||
Denom: "btc",
|
|
||||||
LiquidationRatio: sdk.MustNewDecFromStr("1.5"),
|
|
||||||
DebtLimit: sdk.NewInt(500000),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Denom: "xrp",
|
|
||||||
LiquidationRatio: sdk.MustNewDecFromStr("2.0"),
|
|
||||||
DebtLimit: sdk.NewInt(500000),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
StableDenoms: []string{"usdx"},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func defaultParamsSingle() types.CdpParams {
|
|
||||||
return types.CdpParams{
|
|
||||||
GlobalDebtLimit: sdk.NewInt(1000000),
|
|
||||||
CollateralParams: []types.CollateralParams{
|
|
||||||
{
|
|
||||||
Denom: "xrp",
|
|
||||||
LiquidationRatio: sdk.MustNewDecFromStr("2.0"),
|
|
||||||
DebtLimit: sdk.NewInt(500000),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
StableDenoms: []string{"usdx"},
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user