mirror of
https://github.com/0glabs/0g-chain.git
synced 2024-12-24 15:25:18 +00:00
R4R: add collateral value, collateralization ratio to CDP querier (#347)
* AugmentedCDP type, codec registration, querier update * added unique error for augmented cdp loading * added AugmentedCDPs type for cdps query res * query results for cdps (by denom) & cdps-by-ratio (by denom & ratio) * status: converting collateral value into debt coin denom * collateral value denominated in debt coin * query cdps-by-ratio now searches by collateralization ratio instead of absolute ratio * updated alias, code comments * updated querier tests * support multiple principal coins and their associated fees * collateralization ratio calculations on updated fees * include calculated fees in total debt calculation
This commit is contained in:
parent
075a3089ce
commit
bf64a5c02c
@ -28,6 +28,7 @@ const (
|
||||
CodeCdpNotAvailable = types.CodeCdpNotAvailable
|
||||
CodeBelowDebtFloor = types.CodeBelowDebtFloor
|
||||
CodePaymentExceedsDebt = types.CodePaymentExceedsDebt
|
||||
CodeLoadingAugmentedCDP = types.CodeLoadingAugmentedCDP
|
||||
EventTypeCreateCdp = types.EventTypeCreateCdp
|
||||
EventTypeCdpDeposit = types.EventTypeCdpDeposit
|
||||
EventTypeCdpDraw = types.EventTypeCdpDraw
|
||||
@ -76,6 +77,7 @@ var (
|
||||
ErrCdpNotAvailable = types.ErrCdpNotAvailable
|
||||
ErrBelowDebtFloor = types.ErrBelowDebtFloor
|
||||
ErrPaymentExceedsDebt = types.ErrPaymentExceedsDebt
|
||||
ErrLoadingAugmentedCDP = types.ErrLoadingAugmentedCDP
|
||||
DefaultGenesisState = types.DefaultGenesisState
|
||||
GetCdpIDBytes = types.GetCdpIDBytes
|
||||
GetCdpIDFromBytes = types.GetCdpIDFromBytes
|
||||
@ -143,6 +145,8 @@ var (
|
||||
type (
|
||||
CDP = types.CDP
|
||||
CDPs = types.CDPs
|
||||
AugmentedCDP = types.AugmentedCDP
|
||||
AugmentedCDPs = types.AugmentedCDPs
|
||||
Deposit = types.Deposit
|
||||
Deposits = types.Deposits
|
||||
SupplyKeeper = types.SupplyKeeper
|
||||
|
@ -69,7 +69,7 @@ $ %s query %s cdp kava15qdefkmwswysgg4qxgqpqr35k3m49pkx2jdfnw uatom
|
||||
}
|
||||
|
||||
// Decode and print results
|
||||
var cdp types.CDP
|
||||
var cdp types.AugmentedCDP
|
||||
cdc.MustUnmarshalJSON(res, &cdp)
|
||||
return cliCtx.PrintOutput(cdp)
|
||||
},
|
||||
@ -105,9 +105,9 @@ $ %s query %s cdps uatom
|
||||
}
|
||||
|
||||
// Decode and print results
|
||||
var out types.CDPs
|
||||
cdc.MustUnmarshalJSON(res, &out)
|
||||
return cliCtx.PrintOutput(out)
|
||||
var cdps types.AugmentedCDPs
|
||||
cdc.MustUnmarshalJSON(res, &cdps)
|
||||
return cliCtx.PrintOutput(cdps)
|
||||
},
|
||||
}
|
||||
}
|
||||
@ -119,7 +119,7 @@ func QueryCdpsByDenomAndRatioCmd(queryRoute string, cdc *codec.Codec) *cobra.Com
|
||||
Use: "cdps-by-ratio [collateral-name] [collateralization-ratio]",
|
||||
Short: "get cdps under a collateralization ratio",
|
||||
Long: strings.TrimSpace(
|
||||
fmt.Sprintf(`List all CDPs under a collateralization ratios.
|
||||
fmt.Sprintf(`List all CDPs under a specified collateralization ratio.
|
||||
Collateralization ratio is: collateral * price / debt.
|
||||
|
||||
Example:
|
||||
@ -150,9 +150,9 @@ $ %s query %s cdps-by-ratio uatom 1.5
|
||||
}
|
||||
|
||||
// Decode and print results
|
||||
var out types.CDPs
|
||||
cdc.MustUnmarshalJSON(res, &out)
|
||||
return cliCtx.PrintOutput(out)
|
||||
var cdps types.AugmentedCDPs
|
||||
cdc.MustUnmarshalJSON(res, &cdps)
|
||||
return cliCtx.PrintOutput(cdps)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -9,6 +9,9 @@ import (
|
||||
"github.com/kava-labs/kava/x/cdp/types"
|
||||
)
|
||||
|
||||
// BaseDigitFactor is 10**18, used during coin calculations
|
||||
const BaseDigitFactor = 1000000000000000000
|
||||
|
||||
// AddCdp adds a cdp for a specific owner and collateral type
|
||||
func (k Keeper) AddCdp(ctx sdk.Context, owner sdk.AccAddress, collateral sdk.Coins, principal sdk.Coins) sdk.Error {
|
||||
// validation
|
||||
@ -410,6 +413,38 @@ func (k Keeper) CalculateCollateralToDebtRatio(ctx sdk.Context, collateral sdk.C
|
||||
return collateralBaseUnits.Quo(debtTotal)
|
||||
}
|
||||
|
||||
// LoadAugmentedCDP creates a new augmented CDP from an existing CDP
|
||||
func (k Keeper) LoadAugmentedCDP(ctx sdk.Context, cdp types.CDP) (types.AugmentedCDP, sdk.Error) {
|
||||
// calculate additional fees
|
||||
periods := sdk.NewInt(ctx.BlockTime().Unix()).Sub(sdk.NewInt(cdp.FeesUpdated.Unix()))
|
||||
fees := k.CalculateFees(ctx, cdp.Principal.Add(cdp.AccumulatedFees), periods, cdp.Collateral[0].Denom)
|
||||
totalFees := cdp.AccumulatedFees.Add(fees)
|
||||
|
||||
// calculate collateralization ratio
|
||||
collateralizationRatio, err := k.CalculateCollateralizationRatio(ctx, cdp.Collateral, cdp.Principal, totalFees)
|
||||
if err != nil {
|
||||
return types.AugmentedCDP{}, err
|
||||
}
|
||||
|
||||
// total debt is the sum of all oustanding principal and fees
|
||||
var totalDebt int64
|
||||
for _, principalCoin := range cdp.Principal {
|
||||
totalDebt += principalCoin.Amount.Int64()
|
||||
}
|
||||
for _, feeCoin := range cdp.AccumulatedFees.Add(fees) {
|
||||
totalDebt += feeCoin.Amount.Int64()
|
||||
}
|
||||
|
||||
// convert collateral value to debt coin
|
||||
debtBaseAdjusted := sdk.NewDec(totalDebt).QuoInt64(BaseDigitFactor)
|
||||
collateralValueInDebtDenom := collateralizationRatio.Mul(debtBaseAdjusted)
|
||||
collateralValueInDebt := sdk.NewInt64Coin(cdp.Principal[0].Denom, collateralValueInDebtDenom.Int64())
|
||||
|
||||
// create new augmuented cdp
|
||||
augmentedCDP := types.NewAugmentedCDP(cdp, collateralValueInDebt, collateralizationRatio)
|
||||
return augmentedCDP, nil
|
||||
}
|
||||
|
||||
// CalculateCollateralizationRatio returns the collateralization ratio of the input collateral to the input debt plus fees
|
||||
func (k Keeper) CalculateCollateralizationRatio(ctx sdk.Context, collateral sdk.Coins, principal sdk.Coins, fees sdk.Coins) (sdk.Dec, sdk.Error) {
|
||||
if collateral.IsZero() {
|
||||
@ -422,6 +457,7 @@ func (k Keeper) CalculateCollateralizationRatio(ctx sdk.Context, collateral sdk.
|
||||
}
|
||||
collateralBaseUnits := k.convertCollateralToBaseUnits(ctx, collateral[0])
|
||||
collateralValue := collateralBaseUnits.Mul(price.Price)
|
||||
|
||||
principalTotal := sdk.ZeroDec()
|
||||
for _, pc := range principal {
|
||||
prinicpalBaseUnits := k.convertDebtToBaseUnits(ctx, pc)
|
||||
@ -435,6 +471,19 @@ func (k Keeper) CalculateCollateralizationRatio(ctx sdk.Context, collateral sdk.
|
||||
return collateralRatio, nil
|
||||
}
|
||||
|
||||
// CalculateCollateralizationRatioFromAbsoluteRatio takes a coin's denom and an absolute ratio and returns the respective collateralization ratio
|
||||
func (k Keeper) CalculateCollateralizationRatioFromAbsoluteRatio(ctx sdk.Context, collateralDenom string, absoluteRatio sdk.Dec) (sdk.Dec, sdk.Error) {
|
||||
// get price collateral
|
||||
marketID := k.getMarketID(ctx, collateralDenom)
|
||||
price, err := k.pricefeedKeeper.GetCurrentPrice(ctx, marketID)
|
||||
if err != nil {
|
||||
return sdk.Dec{}, err
|
||||
}
|
||||
// convert absolute ratio to collateralization ratio
|
||||
respectiveCollateralRatio := absoluteRatio.Quo(price.Price)
|
||||
return respectiveCollateralRatio, nil
|
||||
}
|
||||
|
||||
// converts the input collateral to base units (ie multiplies the input by 10^(-ConversionFactor))
|
||||
func (k Keeper) convertCollateralToBaseUnits(ctx sdk.Context, collateral sdk.Coin) (baseUnits sdk.Dec) {
|
||||
cp, _ := k.GetCollateral(ctx, collateral.Denom)
|
||||
|
@ -44,7 +44,12 @@ func queryGetCdp(ctx sdk.Context, req abci.RequestQuery, keeper Keeper) ([]byte,
|
||||
return nil, types.ErrCdpNotFound(keeper.codespace, requestParams.Owner, requestParams.CollateralDenom)
|
||||
}
|
||||
|
||||
bz, err := codec.MarshalJSONIndent(keeper.cdc, cdp)
|
||||
augmentedCDP, err := keeper.LoadAugmentedCDP(ctx, cdp)
|
||||
if err != nil {
|
||||
return nil, types.ErrLoadingAugmentedCDP(keeper.codespace, cdp.ID)
|
||||
}
|
||||
|
||||
bz, err := codec.MarshalJSONIndent(keeper.cdc, augmentedCDP)
|
||||
if err != nil {
|
||||
return nil, sdk.ErrInternal(sdk.AppendMsgToErr("could not marshal result to JSON", err.Error()))
|
||||
}
|
||||
@ -64,8 +69,21 @@ func queryGetCdpsByRatio(ctx sdk.Context, req abci.RequestQuery, keeper Keeper)
|
||||
return nil, types.ErrInvalidCollateralDenom(keeper.codespace, requestParams.CollateralDenom)
|
||||
}
|
||||
|
||||
cdps := keeper.GetAllCdpsByDenomAndRatio(ctx, requestParams.CollateralDenom, requestParams.Ratio)
|
||||
bz, err := codec.MarshalJSONIndent(keeper.cdc, cdps)
|
||||
ratio, err := keeper.CalculateCollateralizationRatioFromAbsoluteRatio(ctx, requestParams.CollateralDenom, requestParams.Ratio)
|
||||
if err != nil {
|
||||
return nil, sdk.ErrInternal(sdk.AppendMsgToErr("could get collateralization ratio from absolute ratio", err.Error()))
|
||||
}
|
||||
|
||||
cdps := keeper.GetAllCdpsByDenomAndRatio(ctx, requestParams.CollateralDenom, ratio)
|
||||
// augment CDPs by adding collateral value and collateralization ratio
|
||||
var augmentedCDPs types.AugmentedCDPs
|
||||
for _, cdp := range cdps {
|
||||
augmentedCDP, err := keeper.LoadAugmentedCDP(ctx, cdp)
|
||||
if err == nil {
|
||||
augmentedCDPs = append(augmentedCDPs, augmentedCDP)
|
||||
}
|
||||
}
|
||||
bz, err := codec.MarshalJSONIndent(keeper.cdc, augmentedCDPs)
|
||||
if err != nil {
|
||||
return nil, sdk.ErrInternal(sdk.AppendMsgToErr("could not marshal result to JSON", err.Error()))
|
||||
}
|
||||
@ -85,7 +103,15 @@ func queryGetCdpsByDenom(ctx sdk.Context, req abci.RequestQuery, keeper Keeper)
|
||||
}
|
||||
|
||||
cdps := keeper.GetAllCdpsByDenom(ctx, requestParams.CollateralDenom)
|
||||
bz, err := codec.MarshalJSONIndent(keeper.cdc, cdps)
|
||||
// augment CDPs by adding collateral value and collateralization ratio
|
||||
var augmentedCDPs types.AugmentedCDPs
|
||||
for _, cdp := range cdps {
|
||||
augmentedCDP, err := keeper.LoadAugmentedCDP(ctx, cdp)
|
||||
if err == nil {
|
||||
augmentedCDPs = append(augmentedCDPs, augmentedCDP)
|
||||
}
|
||||
}
|
||||
bz, err := codec.MarshalJSONIndent(keeper.cdc, augmentedCDPs)
|
||||
if err != nil {
|
||||
return nil, sdk.ErrInternal(sdk.AppendMsgToErr("could not marshal result to JSON", err.Error()))
|
||||
}
|
||||
|
@ -5,12 +5,15 @@ import (
|
||||
"sort"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/simulation"
|
||||
"github.com/kava-labs/kava/app"
|
||||
"github.com/kava-labs/kava/x/cdp/keeper"
|
||||
"github.com/kava-labs/kava/x/cdp/types"
|
||||
pfkeeper "github.com/kava-labs/kava/x/pricefeed/keeper"
|
||||
pftypes "github.com/kava-labs/kava/x/pricefeed/types"
|
||||
"github.com/stretchr/testify/suite"
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
tmtime "github.com/tendermint/tendermint/types/time"
|
||||
@ -23,18 +26,21 @@ const (
|
||||
type QuerierTestSuite struct {
|
||||
suite.Suite
|
||||
|
||||
keeper keeper.Keeper
|
||||
addrs []sdk.AccAddress
|
||||
app app.TestApp
|
||||
cdps types.CDPs
|
||||
ctx sdk.Context
|
||||
querier sdk.Querier
|
||||
keeper keeper.Keeper
|
||||
pricefeedKeeper pfkeeper.Keeper
|
||||
addrs []sdk.AccAddress
|
||||
app app.TestApp
|
||||
cdps types.CDPs
|
||||
augmentedCDPs types.AugmentedCDPs
|
||||
ctx sdk.Context
|
||||
querier sdk.Querier
|
||||
}
|
||||
|
||||
func (suite *QuerierTestSuite) SetupTest() {
|
||||
tApp := app.NewTestApp()
|
||||
ctx := tApp.NewContext(true, abci.Header{Height: 1, Time: tmtime.Now()})
|
||||
cdps := make(types.CDPs, 100)
|
||||
augmentedCDPs := make(types.AugmentedCDPs, 100)
|
||||
_, addrs := app.GeneratePrivKeyAddressPairs(100)
|
||||
coins := []sdk.Coins{}
|
||||
|
||||
@ -53,6 +59,30 @@ func (suite *QuerierTestSuite) SetupTest() {
|
||||
suite.ctx = ctx
|
||||
suite.app = tApp
|
||||
suite.keeper = tApp.GetCDPKeeper()
|
||||
suite.pricefeedKeeper = tApp.GetPriceFeedKeeper()
|
||||
|
||||
// Set up markets
|
||||
oracle := addrs[9]
|
||||
marketParams := pftypes.Params{
|
||||
Markets: pftypes.Markets{
|
||||
pftypes.Market{MarketID: "xrp-usd", BaseAsset: "xrp", QuoteAsset: "usd", Oracles: []sdk.AccAddress{oracle}, Active: true},
|
||||
pftypes.Market{MarketID: "btc-usd", BaseAsset: "btc", QuoteAsset: "usd", Oracles: []sdk.AccAddress{oracle}, Active: true},
|
||||
},
|
||||
}
|
||||
suite.pricefeedKeeper.SetParams(ctx, marketParams)
|
||||
|
||||
// Set collateral prices for use in collateralization calculations
|
||||
_, err := suite.pricefeedKeeper.SetPrice(
|
||||
ctx, oracle, "xrp-usd",
|
||||
sdk.MustNewDecFromStr("0.75"),
|
||||
time.Now().Add(1*time.Hour))
|
||||
suite.Nil(err)
|
||||
|
||||
_, err = suite.pricefeedKeeper.SetPrice(
|
||||
ctx, oracle, "btc-usd",
|
||||
sdk.MustNewDecFromStr("5000"),
|
||||
time.Now().Add(1*time.Hour))
|
||||
suite.Nil(err)
|
||||
|
||||
for j := 0; j < 100; j++ {
|
||||
collateral := "xrp"
|
||||
@ -67,9 +97,12 @@ func (suite *QuerierTestSuite) SetupTest() {
|
||||
c, f := suite.keeper.GetCDP(suite.ctx, collateral, uint64(j+1))
|
||||
suite.True(f)
|
||||
cdps[j] = c
|
||||
aCDP, _ := suite.keeper.LoadAugmentedCDP(suite.ctx, c)
|
||||
augmentedCDPs[j] = aCDP
|
||||
}
|
||||
|
||||
suite.cdps = cdps
|
||||
suite.augmentedCDPs = augmentedCDPs
|
||||
suite.querier = keeper.NewQuerier(suite.keeper)
|
||||
suite.addrs = addrs
|
||||
}
|
||||
@ -84,9 +117,9 @@ func (suite *QuerierTestSuite) TestQueryCdp() {
|
||||
suite.Nil(err)
|
||||
suite.NotNil(bz)
|
||||
|
||||
var c types.CDP
|
||||
var c types.AugmentedCDP
|
||||
suite.Nil(types.ModuleCdc.UnmarshalJSON(bz, &c))
|
||||
suite.Equal(suite.cdps[0], c)
|
||||
suite.Equal(suite.augmentedCDPs[0], c)
|
||||
|
||||
query = abci.RequestQuery{
|
||||
Path: strings.Join([]string{custom, types.QuerierRoute, types.QueryGetCdp}, "/"),
|
||||
@ -125,7 +158,7 @@ func (suite *QuerierTestSuite) TestQueryCdpsByDenom() {
|
||||
suite.Nil(err)
|
||||
suite.NotNil(bz)
|
||||
|
||||
var c types.CDPs
|
||||
var c types.AugmentedCDPs
|
||||
suite.Nil(types.ModuleCdc.UnmarshalJSON(bz, &c))
|
||||
suite.Equal(50, len(c))
|
||||
|
||||
@ -140,19 +173,21 @@ func (suite *QuerierTestSuite) TestQueryCdpsByDenom() {
|
||||
func (suite *QuerierTestSuite) TestQueryCdpsByRatio() {
|
||||
ratioCountBtc := 0
|
||||
ratioCountXrp := 0
|
||||
xrpRatio := d("50.0")
|
||||
btcRatio := d("0.003")
|
||||
xrpRatio := d("2.0")
|
||||
btcRatio := d("2500")
|
||||
expectedXrpIds := []int{}
|
||||
expectedBtcIds := []int{}
|
||||
for _, cdp := range suite.cdps {
|
||||
r := suite.keeper.CalculateCollateralToDebtRatio(suite.ctx, cdp.Collateral, cdp.Principal)
|
||||
absoluteRatio := suite.keeper.CalculateCollateralToDebtRatio(suite.ctx, cdp.Collateral, cdp.Principal)
|
||||
collateralizationRatio, err := suite.keeper.CalculateCollateralizationRatioFromAbsoluteRatio(suite.ctx, cdp.Collateral[0].Denom, absoluteRatio)
|
||||
suite.Nil(err)
|
||||
if cdp.Collateral[0].Denom == "xrp" {
|
||||
if r.LT(xrpRatio) {
|
||||
if collateralizationRatio.LT(xrpRatio) {
|
||||
ratioCountXrp += 1
|
||||
expectedXrpIds = append(expectedXrpIds, int(cdp.ID))
|
||||
}
|
||||
} else {
|
||||
if r.LT(btcRatio) {
|
||||
if collateralizationRatio.LT(btcRatio) {
|
||||
ratioCountBtc += 1
|
||||
expectedBtcIds = append(expectedBtcIds, int(cdp.ID))
|
||||
}
|
||||
@ -168,7 +203,7 @@ func (suite *QuerierTestSuite) TestQueryCdpsByRatio() {
|
||||
suite.Nil(err)
|
||||
suite.NotNil(bz)
|
||||
|
||||
var c types.CDPs
|
||||
var c types.AugmentedCDPs
|
||||
actualXrpIds := []int{}
|
||||
suite.Nil(types.ModuleCdc.UnmarshalJSON(bz, &c))
|
||||
for _, k := range c {
|
||||
@ -185,7 +220,7 @@ func (suite *QuerierTestSuite) TestQueryCdpsByRatio() {
|
||||
suite.Nil(err)
|
||||
suite.NotNil(bz)
|
||||
|
||||
c = types.CDPs{}
|
||||
c = types.AugmentedCDPs{}
|
||||
actualBtcIds := []int{}
|
||||
suite.Nil(types.ModuleCdc.UnmarshalJSON(bz, &c))
|
||||
for _, k := range c {
|
||||
@ -201,7 +236,7 @@ func (suite *QuerierTestSuite) TestQueryCdpsByRatio() {
|
||||
bz, err = suite.querier(ctx, []string{types.QueryGetCdpsByCollateralization}, query)
|
||||
suite.Nil(err)
|
||||
suite.NotNil(bz)
|
||||
c = types.CDPs{}
|
||||
c = types.AugmentedCDPs{}
|
||||
suite.Nil(types.ModuleCdc.UnmarshalJSON(bz, &c))
|
||||
suite.Equal(0, len(c))
|
||||
}
|
||||
|
@ -62,3 +62,63 @@ func (cdps CDPs) String() string {
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
// AugmentedCDP provides additional information about an active CDP
|
||||
type AugmentedCDP struct {
|
||||
CDP `json:"cdp" yaml:"cdp"`
|
||||
CollateralValue sdk.Coin `json:"collateral_value" yaml:"collateral_value"` // collateral's market value in debt coin
|
||||
CollateralizationRatio sdk.Dec `json:"collateralization_ratio" yaml:"collateralization_ratio"` // current collateralization ratio
|
||||
}
|
||||
|
||||
// NewAugmentedCDP creates a new AugmentedCDP object
|
||||
func NewAugmentedCDP(cdp CDP, collateralValue sdk.Coin, collateralizationRatio sdk.Dec) AugmentedCDP {
|
||||
augmentedCDP := AugmentedCDP{
|
||||
CDP: CDP{
|
||||
ID: cdp.ID,
|
||||
Owner: cdp.Owner,
|
||||
Collateral: cdp.Collateral,
|
||||
Principal: cdp.Principal,
|
||||
AccumulatedFees: cdp.AccumulatedFees,
|
||||
FeesUpdated: cdp.FeesUpdated,
|
||||
},
|
||||
CollateralValue: collateralValue,
|
||||
CollateralizationRatio: collateralizationRatio,
|
||||
}
|
||||
return augmentedCDP
|
||||
}
|
||||
|
||||
// String implements fmt.stringer
|
||||
func (augCDP AugmentedCDP) String() string {
|
||||
return strings.TrimSpace(fmt.Sprintf(`AugmentedCDP:
|
||||
Owner: %s
|
||||
ID: %d
|
||||
Collateral Type: %s
|
||||
Collateral: %s
|
||||
Collateral Value: %s
|
||||
Principal: %s
|
||||
Fees: %s
|
||||
Fees Last Updated: %s
|
||||
Collateralization ratio: %s`,
|
||||
augCDP.Owner,
|
||||
augCDP.ID,
|
||||
augCDP.Collateral[0].Denom,
|
||||
augCDP.Collateral,
|
||||
augCDP.CollateralValue,
|
||||
augCDP.Principal,
|
||||
augCDP.AccumulatedFees,
|
||||
augCDP.FeesUpdated,
|
||||
augCDP.CollateralizationRatio,
|
||||
))
|
||||
}
|
||||
|
||||
// AugmentedCDPs a collection of AugmentedCDP objects
|
||||
type AugmentedCDPs []AugmentedCDP
|
||||
|
||||
// String implements stringer
|
||||
func (augcdps AugmentedCDPs) String() string {
|
||||
out := ""
|
||||
for _, augcdp := range augcdps {
|
||||
out += augcdp.String() + "\n"
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
@ -26,6 +26,7 @@ const (
|
||||
CodeCdpNotAvailable sdk.CodeType = 14
|
||||
CodeBelowDebtFloor sdk.CodeType = 15
|
||||
CodePaymentExceedsDebt sdk.CodeType = 16
|
||||
CodeLoadingAugmentedCDP sdk.CodeType = 17
|
||||
)
|
||||
|
||||
// ErrCdpAlreadyExists error for duplicate cdps
|
||||
@ -107,3 +108,8 @@ func ErrBelowDebtFloor(codespace sdk.CodespaceType, debt sdk.Coins, floor sdk.In
|
||||
func ErrPaymentExceedsDebt(codespace sdk.CodespaceType, payment sdk.Coins, principal sdk.Coins) sdk.Error {
|
||||
return sdk.NewError(codespace, CodePaymentExceedsDebt, fmt.Sprintf("payment of %s exceeds debt of %s", payment, principal))
|
||||
}
|
||||
|
||||
// ErrLoadingAugmentedCDP error loading augmented cdp
|
||||
func ErrLoadingAugmentedCDP(codespace sdk.CodespaceType, cdpID uint64) sdk.Error {
|
||||
return sdk.NewError(codespace, CodeCdpNotFound, fmt.Sprintf("augmented cdp could not be loaded from cdp id %d", cdpID))
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user