mirror of
https://github.com/0glabs/0g-chain.git
synced 2024-12-26 00:05:18 +00:00
Querier improvements: CDP and Auction priority 1 queries (#644)
* query auction by lot owner * add SavingsRateDistributed to store * v2cdps: filtered cdps query * update v2cdps cli examples * add savings rate dist counter to begin blocker * implement savings rate dist cli query * implement cdp REST queries * minor auction CLI/REST updates * fix auction querier bug * update REST endpoint to 'cdps' * update to savings-rate-dist * update SavingsRateDistributed get/set * update tests * fix savings rate dist rounding errors * 'collateralDenom' -> 'collateralType' * refactor 'v2cdps' -> 'cdps', add ratio param * fix augmented CDP type, msg string() method * fix cdp querier test * filter query results efficiently * querier tests * limit type iteration if owner defined * improve savings rate dist genesis validation * default sdk.Dec{} to sdk.ZeroDec in queries * update condition logic for finding intersection * fix cdp querier filtering * Update kava-4 swagger (#653) * add collateral_type, update cdp params * savings rate, auctions, get cdps * drop owner from AuctionResponse * remove duplicate collateral denom * update query paths with {collateral-type}
This commit is contained in:
parent
641d946ae7
commit
e2f515ba9e
@ -410,6 +410,8 @@
|
||||
$ref: '#/definitions/CoinCollateral'
|
||||
principal:
|
||||
$ref: '#/definitions/CoinPrincipal'
|
||||
collateral_type:
|
||||
$ref: '#/definitions/CollateralType'
|
||||
responses:
|
||||
200:
|
||||
description: Tx was successfully generated
|
||||
@ -419,7 +421,7 @@
|
||||
description: Invalid request
|
||||
500:
|
||||
description: Server internal error
|
||||
/cdp/{owner}/{denom}/deposits:
|
||||
/cdp/{owner}/{collateral-type}/deposits:
|
||||
post:
|
||||
summary: Create a deposit to cdp transaction
|
||||
tags:
|
||||
@ -436,11 +438,11 @@
|
||||
type: string
|
||||
x-example: kava1ffv7nhd3z6sych2qpqkk03ec6hzkmufy0r2s4c
|
||||
- in: path
|
||||
name: denom
|
||||
description: Collateral denom
|
||||
name: collateral_type
|
||||
description: Collateral type
|
||||
required: true
|
||||
type: string
|
||||
x-example: xrp
|
||||
x-example: xrp-a
|
||||
- description: deposit cdp post parameters
|
||||
name: post_deposit_req
|
||||
in: body
|
||||
@ -456,6 +458,8 @@
|
||||
$ref: '#/definitions/Address'
|
||||
collateral:
|
||||
$ref: '#/definitions/CoinCollateral'
|
||||
collateral_type:
|
||||
$ref: '#/definitions/CollateralType'
|
||||
responses:
|
||||
200:
|
||||
description: Tx was successfully generated
|
||||
@ -465,7 +469,7 @@
|
||||
description: Invalid request
|
||||
500:
|
||||
description: Server internal error
|
||||
/cdp/{owner}/{denom}/withdraw:
|
||||
/cdp/{owner}/{collateral-type}/withdraw:
|
||||
post:
|
||||
summary: create a withdraw collateral transaction
|
||||
tags:
|
||||
@ -482,11 +486,11 @@
|
||||
type: string
|
||||
x-example: kava1ffv7nhd3z6sych2qpqkk03ec6hzkmufy0r2s4c
|
||||
- in: path
|
||||
name: denom
|
||||
description: Collateral denom
|
||||
name: collateral_type
|
||||
description: Collateral type
|
||||
required: true
|
||||
type: string
|
||||
x-example: xrp
|
||||
x-example: xrp-a
|
||||
- description: withdraw cdp post parameters
|
||||
name: post_withdraw_req
|
||||
in: body
|
||||
@ -502,6 +506,8 @@
|
||||
$ref: '#/definitions/Address'
|
||||
collateral:
|
||||
$ref: '#/definitions/CoinCollateral'
|
||||
collateral_type:
|
||||
$ref: '#/definitions/CollateralType'
|
||||
responses:
|
||||
200:
|
||||
description: Tx was successfully generated
|
||||
@ -511,7 +517,7 @@
|
||||
description: Invalid request
|
||||
500:
|
||||
description: Server internal error
|
||||
/cdp/{owner}/{denom}/draw:
|
||||
/cdp/{owner}/{collateral-type}/draw:
|
||||
post:
|
||||
summary: Create a draw debt transaction
|
||||
tags:
|
||||
@ -528,11 +534,11 @@
|
||||
type: string
|
||||
x-example: kava1ffv7nhd3z6sych2qpqkk03ec6hzkmufy0r2s4c
|
||||
- in: path
|
||||
name: denom
|
||||
description: Collateral denom
|
||||
name: collateral_type
|
||||
description: Collateral type
|
||||
required: true
|
||||
type: string
|
||||
x-example: xrp
|
||||
x-example: xrp-a
|
||||
- description: draw cdp post parameters
|
||||
name: post_draw_req
|
||||
in: body
|
||||
@ -546,6 +552,8 @@
|
||||
$ref: '#/definitions/Address'
|
||||
principal:
|
||||
$ref: '#/definitions/CoinPrincipal'
|
||||
collateral_type:
|
||||
$ref: '#/definitions/CollateralType'
|
||||
responses:
|
||||
200:
|
||||
description: Tx was successfully generated
|
||||
@ -555,7 +563,7 @@
|
||||
description: Invalid request
|
||||
500:
|
||||
description: Server internal error
|
||||
/cdp/{owner}/{denom}/repay:
|
||||
/cdp/{owner}/{collateral-type}/repay:
|
||||
post:
|
||||
summary: Repay debt from a CDP
|
||||
tags:
|
||||
@ -571,12 +579,12 @@
|
||||
required: true
|
||||
type: string
|
||||
x-example: kava1ffv7nhd3z6sych2qpqkk03ec6hzkmufy0r2s4c
|
||||
- in: path
|
||||
name: denom
|
||||
description: Collateral denom
|
||||
- in: path
|
||||
name: collateral_type
|
||||
description: Collateral type
|
||||
required: true
|
||||
type: string
|
||||
x-example: xrp
|
||||
x-example: xrp-a
|
||||
- description: repay cdp post parameters
|
||||
name: post_repay_req
|
||||
in: body
|
||||
@ -590,6 +598,8 @@
|
||||
$ref: '#/definitions/Address'
|
||||
payment:
|
||||
$ref: '#/definitions/CoinPrincipal'
|
||||
collateral_type:
|
||||
$ref: '#/definitions/CollateralType'
|
||||
responses:
|
||||
200:
|
||||
description: Tx was successfully generated
|
||||
@ -640,7 +650,6 @@
|
||||
type: number
|
||||
500:
|
||||
description: Server internal error
|
||||
|
||||
/cdp/parameters:
|
||||
get:
|
||||
summary: Get the parameters of the cdp module
|
||||
@ -669,17 +678,26 @@
|
||||
surplus_auction_threshold:
|
||||
type: string
|
||||
example: '1000000000'
|
||||
surplus_auction_lot:
|
||||
type: string
|
||||
example: '10000000'
|
||||
debt_auction_threshold:
|
||||
type: string
|
||||
example: '1000000000'
|
||||
surplus_auction_lot:
|
||||
type: string
|
||||
example: '10000000'
|
||||
savings_distribution_frequency:
|
||||
type: string
|
||||
example: '60000000'
|
||||
circuit_breaker:
|
||||
type: boolean
|
||||
example: false
|
||||
500:
|
||||
description: Server internal error
|
||||
/cdp/cdps/cdp/{owner}/{denom}:
|
||||
/cdp/cdps/cdp/{owner}/{collateral-type}:
|
||||
get:
|
||||
summary: Get the cdp associated with the input owner address and collateral denom
|
||||
summary: Get the cdp associated with the input owner address and collateral type
|
||||
tags:
|
||||
- CDP
|
||||
produces:
|
||||
@ -692,11 +710,11 @@
|
||||
type: string
|
||||
x-example: kava1ffv7nhd3z6sych2qpqkk03ec6hzkmufy0r2s4c
|
||||
- in: path
|
||||
name: denom
|
||||
description: Collateral denom
|
||||
name: type
|
||||
description: Collateral type
|
||||
required: true
|
||||
type: string
|
||||
x-example: xrp
|
||||
x-example: xrp-a
|
||||
responses:
|
||||
200:
|
||||
description: CDP associated with owner
|
||||
@ -704,23 +722,23 @@
|
||||
$ref: '#/definitions/CdpResponse'
|
||||
500:
|
||||
description: Server internal error
|
||||
/cdp/cdps/denom/{denom}:
|
||||
/cdp/cdps/denom/{collateral-type}:
|
||||
get:
|
||||
summary: Get all cdps with collateral type equal to the input collateral denom
|
||||
summary: Get all cdps with collateral type equal to the input collateral type
|
||||
tags:
|
||||
- CDP
|
||||
produces:
|
||||
- application/json
|
||||
parameters:
|
||||
- in: path
|
||||
name: denom
|
||||
description: Collateral denom
|
||||
name: type
|
||||
description: Collateral Type
|
||||
required: true
|
||||
type: string
|
||||
x-example: xrp
|
||||
x-example: xrp-a
|
||||
responses:
|
||||
200:
|
||||
description: All CDPs with the input collateral denom
|
||||
description: All CDPs with the input collateral type
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
@ -734,20 +752,20 @@
|
||||
$ref: '#/definitions/CdpResponse'
|
||||
500:
|
||||
description: Server internal error
|
||||
/cdp/cdps/ratio/{denom}/{ratio}:
|
||||
/cdp/cdps/ratio/{collateral-type}/{ratio}:
|
||||
get:
|
||||
summary: Get all cdps with collateral type equal to the input collateral denom and collateralization ratio strictly less than the input ratio
|
||||
summary: Get all cdps with collateral type equal to the input collateral type and collateralization ratio strictly less than the input ratio
|
||||
tags:
|
||||
- CDP
|
||||
produces:
|
||||
- application/json
|
||||
parameters:
|
||||
- in: path
|
||||
name: denom
|
||||
description: Collateral denom
|
||||
name: type
|
||||
description: Collateral type
|
||||
required: true
|
||||
type: string
|
||||
x-example: xrp
|
||||
x-example: xrp-a
|
||||
- in: path
|
||||
name: ratio
|
||||
description: Collateralization ratio
|
||||
@ -756,7 +774,7 @@
|
||||
x-example: "2.0"
|
||||
responses:
|
||||
200:
|
||||
description: All CDPs with the input collateral denom and collateralization ratio less than the input ratio
|
||||
description: All CDPs with the input collateral type and collateralization ratio less than the input ratio
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
@ -770,9 +788,9 @@
|
||||
$ref: '#/definitions/CdpResponse'
|
||||
500:
|
||||
description: Server internal error
|
||||
/cdp/cdps/cdp/deposits/{owner}/{denom}:
|
||||
/cdp/cdps/cdp/deposits/{owner}/{collateral-type}:
|
||||
get:
|
||||
summary: Get the deposits associated with the cdp owned by the input owner address and with collateral type equal to the input collateral denom
|
||||
summary: Get the deposits associated with the cdp owned by an address for a collateral type
|
||||
tags:
|
||||
- CDP
|
||||
produces:
|
||||
@ -785,11 +803,11 @@
|
||||
type: string
|
||||
x-example: kava1ffv7nhd3z6sych2qpqkk03ec6hzkmufy0r2s4c
|
||||
- in: path
|
||||
name: denom
|
||||
description: Collateral denom
|
||||
name: type
|
||||
description: Collateral type
|
||||
required: true
|
||||
type: string
|
||||
x-example: xrp
|
||||
x-example: xrp-a
|
||||
responses:
|
||||
200:
|
||||
description: Deposits associated with the cdp
|
||||
@ -805,6 +823,73 @@
|
||||
$ref: '#/definitions/CdpDepositResponse'
|
||||
500:
|
||||
description: Server internal error
|
||||
/cdp/savings-rate-dist:
|
||||
get:
|
||||
summary: Get the total savings rate distributed by the cdp module
|
||||
tags:
|
||||
- CDP
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
200:
|
||||
description: The distributed savings rate
|
||||
properties:
|
||||
height:
|
||||
type: string
|
||||
example: "100"
|
||||
result:
|
||||
savings_rate_distributed:
|
||||
type: string
|
||||
example: "5000000000000"
|
||||
500:
|
||||
description: Server internal error
|
||||
/cdp/cdps:
|
||||
get:
|
||||
summary: Query all active cdps
|
||||
tags:
|
||||
- CDP
|
||||
produces:
|
||||
- application/json
|
||||
parameters:
|
||||
- in: query
|
||||
name: owner
|
||||
description: Owner address in bech32 format
|
||||
required: false
|
||||
type: string
|
||||
x-example: kava1ffv7nhd3z6sych2qpqkk03ec6hzkmufy0r2s4c
|
||||
- in: query
|
||||
name: collateral-type
|
||||
description: Collateral type
|
||||
required: false
|
||||
type: string
|
||||
x-example: xrp-a
|
||||
- in: query
|
||||
name: id
|
||||
description: CDP ID
|
||||
required: false
|
||||
type: string
|
||||
x-example: "4"
|
||||
- in: query
|
||||
name: ratio
|
||||
description: Collateralization ratio
|
||||
required: false
|
||||
type: string
|
||||
x-example: "2.75"
|
||||
responses:
|
||||
200:
|
||||
description: Query cdps
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
height:
|
||||
type: string
|
||||
example: "100"
|
||||
result:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/definitions/CdpResponse'
|
||||
500:
|
||||
description: Internal Server Error
|
||||
/bep3/swap/create:
|
||||
post:
|
||||
summary: Generate a create atomic swap transaction
|
||||
@ -1273,7 +1358,7 @@
|
||||
$ref: '#/definitions/BaseReq'
|
||||
owner:
|
||||
$ref: '#/definitions/Address'
|
||||
denom:
|
||||
type:
|
||||
type: string
|
||||
example: bnb
|
||||
responses:
|
||||
@ -1285,9 +1370,9 @@
|
||||
description: Invalid request
|
||||
500:
|
||||
description: Internal server error
|
||||
/incentive/claims/{owner}/{denom}:
|
||||
/incentive/claims/{owner}/{collateral-type}:
|
||||
get:
|
||||
summary: Get outstanding claims for the input owner and denom
|
||||
summary: Get outstanding claims for the input owner and collateral type
|
||||
tags:
|
||||
- Incentive
|
||||
produces:
|
||||
@ -1299,11 +1384,11 @@
|
||||
type: string
|
||||
x-example: kava1ffv7nhd3z6sych2qpqkk03ec6hzkmufy0r2s4c
|
||||
- in: path
|
||||
name: denom
|
||||
description: Collateral denom
|
||||
name: type
|
||||
description: Collateral type
|
||||
required: true
|
||||
type: string
|
||||
x-example: bnb
|
||||
x-example: bnb-a
|
||||
responses:
|
||||
200:
|
||||
description: USDX Incentive Claims
|
||||
@ -3457,6 +3542,9 @@
|
||||
amount:
|
||||
type: string
|
||||
example: '555555'
|
||||
CollateralType:
|
||||
type: string
|
||||
example: xrp-a
|
||||
CoinCollateral:
|
||||
type: object
|
||||
properties:
|
||||
@ -3904,6 +3992,9 @@
|
||||
example: kava1q53rwutgpzx7szcrgzqguxyccjpzt9j4cyctn9
|
||||
collateral:
|
||||
$ref: '#/definitions/CoinCollateral'
|
||||
type:
|
||||
type: string
|
||||
example: "xrp-a"
|
||||
principal:
|
||||
$ref: '#/definitions/CoinPrincipal'
|
||||
accumulated_fees:
|
||||
@ -3987,6 +4078,15 @@
|
||||
bid_duration:
|
||||
type: string
|
||||
example: 600000000000
|
||||
increment_surplus:
|
||||
type: string
|
||||
example: "0.05"
|
||||
increment_debt:
|
||||
type: string
|
||||
example: "0.05"
|
||||
increment_collateral:
|
||||
type: string
|
||||
example: "0.05"
|
||||
AuctionResponse:
|
||||
type: object
|
||||
properties:
|
||||
|
@ -22,6 +22,7 @@ const (
|
||||
flagType = "type"
|
||||
flagDenom = "denom"
|
||||
flagPhase = "phase"
|
||||
flagOwner = "owner"
|
||||
)
|
||||
|
||||
// GetQueryCmd returns the cli query commands for this module
|
||||
@ -77,6 +78,7 @@ func QueryGetAuctionsCmd(queryRoute string, cdc *codec.Codec) *cobra.Command {
|
||||
Long: strings.TrimSpace(`Query for all paginated auctions that match optional filters:
|
||||
Example:
|
||||
$ kvcli q auction auctions --type=(collateral|surplus|debt)
|
||||
$ kvcli q auction auctions --owner=kava1hatdq32u5x4wnxrtv5wzjzmq49sxgjgsj0mffm
|
||||
$ kvcli q auction auctions --denom=bnb
|
||||
$ kvcli q auction auctions --phase=(forward|reverse)
|
||||
$ kvcli q auction auctions --page=2 --limit=100
|
||||
@ -84,6 +86,7 @@ $ kvcli q auction auctions --page=2 --limit=100
|
||||
),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
strType := viper.GetString(flagType)
|
||||
strOwner := viper.GetString(flagOwner)
|
||||
strDenom := viper.GetString(flagDenom)
|
||||
strPhase := viper.GetString(flagPhase)
|
||||
page := viper.GetInt(flags.FlagPage)
|
||||
@ -91,11 +94,12 @@ $ kvcli q auction auctions --page=2 --limit=100
|
||||
|
||||
var (
|
||||
auctionType string
|
||||
auctionOwner sdk.AccAddress
|
||||
auctionDenom string
|
||||
auctionPhase string
|
||||
)
|
||||
|
||||
params := types.NewQueryAllAuctionParams(page, limit, auctionType, auctionDenom, auctionPhase)
|
||||
params := types.NewQueryAllAuctionParams(page, limit, auctionType, auctionDenom, auctionPhase, auctionOwner)
|
||||
|
||||
if len(strType) != 0 {
|
||||
auctionType = strings.ToLower(strings.TrimSpace(strType))
|
||||
@ -107,6 +111,18 @@ $ kvcli q auction auctions --page=2 --limit=100
|
||||
params.Type = auctionType
|
||||
}
|
||||
|
||||
if len(auctionOwner) != 0 {
|
||||
if auctionType != types.CollateralAuctionType {
|
||||
return fmt.Errorf("cannot apply owner flag to non-collateral auction type")
|
||||
}
|
||||
auctionOwnerStr := strings.ToLower(strings.TrimSpace(strOwner))
|
||||
auctionOwner, err := sdk.AccAddressFromBech32(auctionOwnerStr)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot parse address from auction owner %s", auctionOwnerStr)
|
||||
}
|
||||
params.Owner = auctionOwner
|
||||
}
|
||||
|
||||
if len(strDenom) != 0 {
|
||||
auctionDenom := strings.TrimSpace(strDenom)
|
||||
err := sdk.ValidateDenom(auctionDenom)
|
||||
@ -160,6 +176,7 @@ $ kvcli q auction auctions --page=2 --limit=100
|
||||
cmd.Flags().Int(flags.FlagPage, 1, "pagination page of auctions to to query for")
|
||||
cmd.Flags().Int(flags.FlagLimit, 100, "pagination limit of auctions to query for")
|
||||
cmd.Flags().String(flagType, "", "(optional) filter by auction type, type: collateral, debt, surplus")
|
||||
cmd.Flags().String(flagOwner, "", "(optional) filter by collateral auction owner")
|
||||
cmd.Flags().String(flagDenom, "", "(optional) filter by auction denom")
|
||||
cmd.Flags().String(flagPhase, "", "(optional) filter by collateral auction phase, phase: forward/reverse")
|
||||
|
||||
|
@ -69,6 +69,7 @@ func queryAuctionsHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
|
||||
}
|
||||
|
||||
var auctionType string
|
||||
var auctionOwner sdk.AccAddress
|
||||
var auctionDenom string
|
||||
var auctionPhase string
|
||||
|
||||
@ -82,6 +83,17 @@ func queryAuctionsHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
|
||||
}
|
||||
}
|
||||
|
||||
if x := r.URL.Query().Get(RestOwner); len(x) != 0 {
|
||||
if auctionType != types.CollateralAuctionType {
|
||||
rest.WriteErrorResponse(w, http.StatusBadRequest, "cannot apply owner flag to non-collateral auction type")
|
||||
}
|
||||
auctionOwnerStr := strings.ToLower(strings.TrimSpace(x))
|
||||
auctionOwner, err = sdk.AccAddressFromBech32(auctionOwnerStr)
|
||||
if err != nil {
|
||||
rest.WriteErrorResponse(w, http.StatusBadRequest, fmt.Sprintf("cannot parse address from auction owner %s", auctionOwnerStr))
|
||||
}
|
||||
}
|
||||
|
||||
if x := r.URL.Query().Get(RestDenom); len(x) != 0 {
|
||||
auctionDenom = strings.TrimSpace(x)
|
||||
err := sdk.ValidateDenom(auctionDenom)
|
||||
@ -103,7 +115,7 @@ func queryAuctionsHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
|
||||
}
|
||||
}
|
||||
|
||||
params := types.NewQueryAllAuctionParams(page, limit, auctionType, auctionDenom, auctionPhase)
|
||||
params := types.NewQueryAllAuctionParams(page, limit, auctionType, auctionDenom, auctionPhase, auctionOwner)
|
||||
bz, err := cliCtx.Codec.MarshalJSON(params)
|
||||
if err != nil {
|
||||
rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error())
|
||||
|
@ -12,6 +12,7 @@ import (
|
||||
// nolint
|
||||
const (
|
||||
RestType = "type"
|
||||
RestOwner = "owner"
|
||||
RestDenom = "denom"
|
||||
RestPhase = "phase"
|
||||
)
|
||||
|
@ -1,12 +1,11 @@
|
||||
package keeper
|
||||
|
||||
import (
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
|
||||
"github.com/kava-labs/kava/x/auction/types"
|
||||
)
|
||||
@ -93,13 +92,29 @@ func filterAuctions(ctx sdk.Context, auctions types.Auctions, params types.Query
|
||||
filteredAuctions := make(types.Auctions, 0, len(auctions))
|
||||
|
||||
for _, auc := range auctions {
|
||||
matchType, matchDenom, matchPhase := true, true, true
|
||||
matchType, matchOwner, matchDenom, matchPhase := true, true, true, true
|
||||
|
||||
// match auction type (if supplied)
|
||||
if len(params.Type) > 0 {
|
||||
matchType = auc.GetType() == params.Type
|
||||
}
|
||||
|
||||
// match auction owner (if supplied)
|
||||
if len(params.Owner) > 0 {
|
||||
if cAuc, ok := auc.(types.CollateralAuction); ok {
|
||||
foundOwnerAddr := false
|
||||
for _, addr := range cAuc.GetLotReturns().Addresses {
|
||||
if addr.Equals(params.Owner) {
|
||||
foundOwnerAddr = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !foundOwnerAddr {
|
||||
matchOwner = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// match auction denom (if supplied)
|
||||
if len(params.Denom) > 0 {
|
||||
matchDenom = auc.GetBid().Denom == params.Denom || auc.GetLot().Denom == params.Denom
|
||||
@ -110,7 +125,7 @@ func filterAuctions(ctx sdk.Context, auctions types.Auctions, params types.Query
|
||||
matchPhase = auc.GetPhase() == params.Phase
|
||||
}
|
||||
|
||||
if matchType && matchDenom && matchPhase {
|
||||
if matchType && matchOwner && matchDenom && matchPhase {
|
||||
filteredAuctions = append(filteredAuctions, auc)
|
||||
}
|
||||
}
|
||||
|
@ -41,7 +41,7 @@ func (suite *QuerierTestSuite) SetupTest() {
|
||||
tApp := app.NewTestApp()
|
||||
ctx := tApp.NewContext(true, abci.Header{Height: 1, Time: tmtime.Now()})
|
||||
|
||||
_, addrs := app.GeneratePrivKeyAddressPairs(1)
|
||||
_, addrs := app.GeneratePrivKeyAddressPairs(10)
|
||||
buyer := addrs[0]
|
||||
modName := cdp.LiquidatorMacc
|
||||
|
||||
@ -64,8 +64,16 @@ func (suite *QuerierTestSuite) SetupTest() {
|
||||
// Populate with auctions
|
||||
randSrc := rand.New(rand.NewSource(int64(1234)))
|
||||
for j := 0; j < TestAuctionCount; j++ {
|
||||
lotAmount := simulation.RandIntBetween(randSrc, 10, 100)
|
||||
id, err := suite.keeper.StartSurplusAuction(suite.ctx, modName, c("token1", int64(lotAmount)), "token2")
|
||||
var id uint64
|
||||
var err error
|
||||
lotAmount := int64(simulation.RandIntBetween(randSrc, 10, 100))
|
||||
ownerAddrIndex := simulation.RandIntBetween(randSrc, 1, 9)
|
||||
if ownerAddrIndex%2 == 0 {
|
||||
id, err = suite.keeper.StartSurplusAuction(suite.ctx, modName, c("token1", lotAmount), "token2")
|
||||
} else {
|
||||
id, err = suite.keeper.StartCollateralAuction(suite.ctx, modName, c("token1", lotAmount), c("usdx", int64(20)),
|
||||
[]sdk.AccAddress{addrs[ownerAddrIndex]}, []sdk.Int{sdk.NewInt(lotAmount)}, c("debt", int64(10)))
|
||||
}
|
||||
suite.NoError(err)
|
||||
|
||||
auc, found := suite.keeper.GetAuction(suite.ctx, id)
|
||||
@ -108,7 +116,7 @@ func (suite *QuerierTestSuite) TestQueryAuctions() {
|
||||
query := abci.RequestQuery{
|
||||
Path: strings.Join([]string{custom, types.QuerierRoute, types.QueryGetAuctions}, "/"),
|
||||
Data: types.ModuleCdc.MustMarshalJSON(
|
||||
types.NewQueryAllAuctionParams(int(1), int(TestAuctionCount), "", "", ""),
|
||||
types.NewQueryAllAuctionParams(int(1), int(TestAuctionCount), "", "", "", nil),
|
||||
),
|
||||
}
|
||||
|
||||
|
@ -244,6 +244,11 @@ func (a CollateralAuction) GetPhase() string {
|
||||
return ForwardAuctionPhase
|
||||
}
|
||||
|
||||
// GetLotReturns returns a collateral auction's lot owners
|
||||
func (a CollateralAuction) GetLotReturns() WeightedAddresses {
|
||||
return a.LotReturns
|
||||
}
|
||||
|
||||
// Validate validates the CollateralAuction fields values.
|
||||
func (a CollateralAuction) Validate() error {
|
||||
if !a.CorrespondingDebt.IsValid() {
|
||||
|
@ -1,5 +1,9 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
)
|
||||
|
||||
const (
|
||||
// QueryGetAuction is the query path for querying one auction
|
||||
QueryGetAuction = "auction"
|
||||
@ -25,19 +29,21 @@ func NewQueryAuctionParams(id uint64) QueryAuctionParams {
|
||||
|
||||
// QueryAllAuctionParams is the params for an auctions query
|
||||
type QueryAllAuctionParams struct {
|
||||
Page int `json:"page" yaml:"page"`
|
||||
Limit int `json:"limit" yaml:"limit"`
|
||||
Type string `json:"type" yaml:"type"`
|
||||
Denom string `json:"denom" yaml:"denom"`
|
||||
Phase string `json:"phase" yaml:"phase"`
|
||||
Page int `json:"page" yaml:"page"`
|
||||
Limit int `json:"limit" yaml:"limit"`
|
||||
Type string `json:"type" yaml:"type"`
|
||||
Owner sdk.AccAddress `json:"owner" yaml:"owner"`
|
||||
Denom string `json:"denom" yaml:"denom"`
|
||||
Phase string `json:"phase" yaml:"phase"`
|
||||
}
|
||||
|
||||
// NewQueryAllAuctionParams creates a new QueryAllAuctionParams
|
||||
func NewQueryAllAuctionParams(page, limit int, aucType, aucDenom, aucPhase string) QueryAllAuctionParams {
|
||||
func NewQueryAllAuctionParams(page, limit int, aucType, aucDenom, aucPhase string, aucOwner sdk.AccAddress) QueryAllAuctionParams {
|
||||
return QueryAllAuctionParams{
|
||||
Page: page,
|
||||
Limit: limit,
|
||||
Type: aucType,
|
||||
Owner: aucOwner,
|
||||
Denom: aucDenom,
|
||||
Phase: aucPhase,
|
||||
}
|
||||
|
@ -137,7 +137,9 @@ var (
|
||||
DefaultDebtLot = types.DefaultDebtLot
|
||||
DefaultPreviousDistributionTime = types.DefaultPreviousDistributionTime
|
||||
DefaultSavingsDistributionFrequency = types.DefaultSavingsDistributionFrequency
|
||||
DefaultSavingsRateDistributed = types.DefaultSavingsRateDistributed
|
||||
MaxSortableDec = types.MaxSortableDec
|
||||
SavingsRateDistributedKey = types.SavingsRateDistributedKey
|
||||
)
|
||||
|
||||
type (
|
||||
|
@ -2,9 +2,11 @@ package cli
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client/context"
|
||||
"github.com/cosmos/cosmos-sdk/client/flags"
|
||||
@ -16,6 +18,14 @@ import (
|
||||
"github.com/kava-labs/kava/x/cdp/types"
|
||||
)
|
||||
|
||||
// Query CDP flags
|
||||
const (
|
||||
flagCollateralType = "collateral-type"
|
||||
flagOwner = "owner"
|
||||
flagID = "id"
|
||||
flagRatio = "ratio" // returns CDPs under the given collateralization ratio threshold
|
||||
)
|
||||
|
||||
// GetQueryCmd returns the cli query commands for this module
|
||||
func GetQueryCmd(queryRoute string, cdc *codec.Codec) *cobra.Command {
|
||||
// Group nameservice queries under a subcommand
|
||||
@ -26,11 +36,11 @@ func GetQueryCmd(queryRoute string, cdc *codec.Codec) *cobra.Command {
|
||||
|
||||
cdpQueryCmd.AddCommand(flags.GetCommands(
|
||||
QueryCdpCmd(queryRoute, cdc),
|
||||
QueryCdpsByCollateralTypeCmd(queryRoute, cdc),
|
||||
QueryCdpsByCollateralTypeAndRatioCmd(queryRoute, cdc),
|
||||
QueryGetCdpsCmd(queryRoute, cdc),
|
||||
QueryCdpDepositsCmd(queryRoute, cdc),
|
||||
QueryParamsCmd(queryRoute, cdc),
|
||||
QueryGetAccounts(queryRoute, cdc),
|
||||
QueryGetSavingsRateDistributed(queryRoute, cdc),
|
||||
)...)
|
||||
|
||||
return cdpQueryCmd
|
||||
@ -79,85 +89,103 @@ $ %s query %s cdp kava15qdefkmwswysgg4qxgqpqr35k3m49pkx2jdfnw atom-a
|
||||
}
|
||||
}
|
||||
|
||||
// QueryCdpsByCollateralTypeCmd returns the command handler for querying cdps for a collateral type
|
||||
func QueryCdpsByCollateralTypeCmd(queryRoute string, cdc *codec.Codec) *cobra.Command {
|
||||
return &cobra.Command{
|
||||
Use: "cdps [collateral-type]",
|
||||
Short: "query CDPs by collateral",
|
||||
Long: strings.TrimSpace(
|
||||
fmt.Sprintf(`List all CDPs collateralized with the specified asset.
|
||||
|
||||
// QueryGetCdpsCmd queries the cdps in the store
|
||||
func QueryGetCdpsCmd(queryRoute string, cdc *codec.Codec) *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "cdps",
|
||||
Short: "query cdps with optional filters",
|
||||
Long: strings.TrimSpace(`Query for all paginated cdps that match optional filters:
|
||||
Example:
|
||||
$ %s query %s cdps atom-a
|
||||
`, version.ClientName, types.ModuleName)),
|
||||
Args: cobra.ExactArgs(1),
|
||||
$ kvcli q cdp cdps --collateral-type=bnb
|
||||
$ kvcli q cdp cdps --owner=kava1hatdq32u5x4wnxrtv5wzjzmq49sxgjgsj0mffm
|
||||
$ kvcli q cdp cdps --id=21
|
||||
$ kvcli q cdp cdps --ratio=2.75
|
||||
$ kvcli q cdp cdps --page=2 --limit=100
|
||||
`,
|
||||
),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
cliCtx := context.NewCLIContext().WithCodec(cdc)
|
||||
strCollateralType := viper.GetString(flagCollateralType)
|
||||
strOwner := viper.GetString(flagOwner)
|
||||
strID := viper.GetString(flagID)
|
||||
strRatio := viper.GetString(flagRatio)
|
||||
page := viper.GetInt(flags.FlagPage)
|
||||
limit := viper.GetInt(flags.FlagLimit)
|
||||
|
||||
// Prepare params for querier
|
||||
bz, err := cdc.MarshalJSON(types.QueryCdpsParams{CollateralType: args[0]})
|
||||
var (
|
||||
cdpCollateralType string
|
||||
cdpOwner sdk.AccAddress
|
||||
cdpID uint64
|
||||
cdpRatio sdk.Dec
|
||||
)
|
||||
|
||||
params := types.NewQueryCdpsParams(page, limit, cdpCollateralType, cdpOwner, cdpID, cdpRatio)
|
||||
|
||||
if len(strCollateralType) != 0 {
|
||||
cdpCollateralType = strings.ToLower(strings.TrimSpace(strCollateralType))
|
||||
params.CollateralType = cdpCollateralType
|
||||
}
|
||||
|
||||
if len(strOwner) != 0 {
|
||||
cdpOwner, err := sdk.AccAddressFromBech32(strings.ToLower(strings.TrimSpace(strOwner)))
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot parse address from cdp owner %s", strOwner)
|
||||
}
|
||||
params.Owner = cdpOwner
|
||||
}
|
||||
|
||||
if len(strID) != 0 {
|
||||
cdpID, err := strconv.ParseUint(strID, 10, 64)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot parse cdp ID %s", strID)
|
||||
}
|
||||
params.ID = cdpID
|
||||
}
|
||||
|
||||
params.Ratio = sdk.ZeroDec()
|
||||
if len(strRatio) != 0 {
|
||||
cdpRatio, err := sdk.NewDecFromStr(strRatio)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot parse cdp ratio %s", strRatio)
|
||||
}
|
||||
params.Ratio = cdpRatio
|
||||
} else {
|
||||
// Set to sdk.Dec(0) so that if not specified in params it doesn't panic when unmarshaled
|
||||
params.Ratio = sdk.ZeroDec()
|
||||
}
|
||||
|
||||
bz, err := cdc.MarshalJSON(params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cliCtx := context.NewCLIContext().WithCodec(cdc)
|
||||
|
||||
// Query
|
||||
route := fmt.Sprintf("custom/%s/%s", queryRoute, types.QueryGetCdps)
|
||||
res, _, err := cliCtx.QueryWithData(route, bz)
|
||||
res, height, err := cliCtx.QueryWithData(fmt.Sprintf("custom/%s/%s", queryRoute, types.QueryGetCdps), bz)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Decode and print results
|
||||
var cdps types.AugmentedCDPs
|
||||
cdc.MustUnmarshalJSON(res, &cdps)
|
||||
return cliCtx.PrintOutput(cdps)
|
||||
var matchingCDPs types.AugmentedCDPs
|
||||
cdc.MustUnmarshalJSON(res, &matchingCDPs)
|
||||
if len(matchingCDPs) == 0 {
|
||||
return fmt.Errorf("No matching CDPs found")
|
||||
}
|
||||
|
||||
cliCtx = cliCtx.WithHeight(height)
|
||||
return cliCtx.PrintOutput(matchingCDPs) // nolint:errcheck
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// QueryCdpsByCollateralTypeAndRatioCmd returns the command handler for querying cdps
|
||||
// that are under the specified collateral ratio
|
||||
func QueryCdpsByCollateralTypeAndRatioCmd(queryRoute string, cdc *codec.Codec) *cobra.Command {
|
||||
return &cobra.Command{
|
||||
Use: "cdps-by-ratio [collateral-type] [collateralization-ratio]",
|
||||
Short: "get cdps under a collateralization ratio",
|
||||
Long: strings.TrimSpace(
|
||||
fmt.Sprintf(`List all CDPs under a specified collateralization ratio.
|
||||
Collateralization ratio is: collateral * price / debt.
|
||||
cmd.Flags().Int(flags.FlagPage, 1, "pagination page of CDPs to to query for")
|
||||
cmd.Flags().Int(flags.FlagLimit, 100, "pagination limit of CDPs to query for")
|
||||
cmd.Flags().String(flagCollateralType, "", "(optional) filter by CDP collateral type")
|
||||
cmd.Flags().String(flagOwner, "", "(optional) filter by CDP owner")
|
||||
cmd.Flags().String(flagID, "", "(optional) filter by CDP ID")
|
||||
cmd.Flags().String(flagRatio, "", "(optional) filter by CDP collateralization ratio threshold")
|
||||
|
||||
Example:
|
||||
$ %s query %s cdps-by-ratio atom-a 1.6
|
||||
`, version.ClientName, types.ModuleName)),
|
||||
Args: cobra.ExactArgs(2),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
cliCtx := context.NewCLIContext().WithCodec(cdc)
|
||||
|
||||
// Prepare params for querier
|
||||
ratio, err := sdk.NewDecFromStr(args[1])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
bz, err := cdc.MarshalJSON(types.QueryCdpsByRatioParams{
|
||||
CollateralType: args[0],
|
||||
Ratio: ratio,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Query
|
||||
route := fmt.Sprintf("custom/%s/%s", queryRoute, types.QueryGetCdpsByCollateralization)
|
||||
res, _, err := cliCtx.QueryWithData(route, bz)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Decode and print results
|
||||
var cdps types.AugmentedCDPs
|
||||
cdc.MustUnmarshalJSON(res, &cdps)
|
||||
return cliCtx.PrintOutput(cdps)
|
||||
},
|
||||
}
|
||||
return cmd
|
||||
}
|
||||
|
||||
// QueryCdpDepositsCmd returns the command handler for querying the deposits of a particular cdp
|
||||
@ -208,7 +236,7 @@ func QueryParamsCmd(queryRoute string, cdc *codec.Codec) *cobra.Command {
|
||||
return &cobra.Command{
|
||||
Use: "params",
|
||||
Short: "get the cdp module parameters",
|
||||
Long: "Get the current global cdp module parameters.",
|
||||
Long: "get the current global cdp module parameters.",
|
||||
Args: cobra.NoArgs,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
cliCtx := context.NewCLIContext().WithCodec(cdc)
|
||||
@ -228,11 +256,12 @@ func QueryParamsCmd(queryRoute string, cdc *codec.Codec) *cobra.Command {
|
||||
}
|
||||
}
|
||||
|
||||
// QueryGetAccounts queries CDP module accounts
|
||||
func QueryGetAccounts(queryRoute string, cdc *codec.Codec) *cobra.Command {
|
||||
return &cobra.Command{
|
||||
Use: "accounts",
|
||||
Short: "Get module accounts",
|
||||
Long: "Get cdp module account addresses",
|
||||
Short: "get module accounts",
|
||||
Long: "get cdp module account addresses",
|
||||
Args: cobra.NoArgs,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
cliCtx := context.NewCLIContext().WithCodec(cdc)
|
||||
@ -253,3 +282,30 @@ func QueryGetAccounts(queryRoute string, cdc *codec.Codec) *cobra.Command {
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// QueryGetSavingsRateDistributed queries the total amount of savings rate distributed in USDX
|
||||
func QueryGetSavingsRateDistributed(queryRoute string, cdc *codec.Codec) *cobra.Command {
|
||||
return &cobra.Command{
|
||||
Use: "savings-rate-dist",
|
||||
Short: "get total amount of savings rate distributed in USDX",
|
||||
Long: "get total amount of savings rate distributed",
|
||||
Args: cobra.NoArgs,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
cliCtx := context.NewCLIContext().WithCodec(cdc)
|
||||
|
||||
// Query
|
||||
res, height, err := cliCtx.QueryWithData(fmt.Sprintf("custom/%s/%s", queryRoute, types.QueryGetSavingsRateDistributed), nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cliCtx = cliCtx.WithHeight(height)
|
||||
|
||||
// Decode and print results
|
||||
var out sdk.Int
|
||||
if err := cdc.UnmarshalJSON(res, &out); err != nil {
|
||||
return fmt.Errorf("failed to unmarshal sdk.Int: %w", err)
|
||||
}
|
||||
return cliCtx.PrintOutput(out)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,8 @@ package rest
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client/context"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
@ -16,9 +18,11 @@ import (
|
||||
func registerQueryRoutes(cliCtx context.CLIContext, r *mux.Router) {
|
||||
r.HandleFunc("/cdp/accounts", getAccountsHandlerFn(cliCtx)).Methods("GET")
|
||||
r.HandleFunc("/cdp/parameters", getParamsHandlerFn(cliCtx)).Methods("GET")
|
||||
r.HandleFunc("/cdp/savingsRateDist", getSavingsRateDistributedHandler(cliCtx)).Methods("GET")
|
||||
r.HandleFunc(fmt.Sprintf("/cdp/cdps/cdp/{%s}/{%s}", types.RestOwner, types.RestCollateralType), queryCdpHandlerFn(cliCtx)).Methods("GET")
|
||||
r.HandleFunc(fmt.Sprintf("/cdp/cdps/collateralType/{%s}", types.RestCollateralType), queryCdpsHandlerFn(cliCtx)).Methods("GET")
|
||||
r.HandleFunc(fmt.Sprintf("/cdp/cdps/ratio/{%s}/{%s}", types.RestCollateralType, types.RestRatio), queryCdpsByRatioHandlerFn(cliCtx)).Methods("GET")
|
||||
r.HandleFunc(fmt.Sprintf("/cdp/cdps"), queryCdpsHandlerFn(cliCtx)).Methods("GET")
|
||||
r.HandleFunc(fmt.Sprintf("/cdp/cdps/collateralType/{%s}", types.RestCollateralType), queryCdpsByCollateralTypeHandlerFn(cliCtx)).Methods("GET") // legacy
|
||||
r.HandleFunc(fmt.Sprintf("/cdp/cdps/ratio/{%s}/{%s}", types.RestCollateralType, types.RestRatio), queryCdpsByRatioHandlerFn(cliCtx)).Methods("GET") // legacy
|
||||
r.HandleFunc(fmt.Sprintf("/cdp/cdps/cdp/deposits/{%s}/{%s}", types.RestOwner, types.RestCollateralType), queryCdpDepositsHandlerFn(cliCtx)).Methods("GET")
|
||||
}
|
||||
|
||||
@ -58,7 +62,7 @@ func queryCdpHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
|
||||
}
|
||||
}
|
||||
|
||||
func queryCdpsHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
|
||||
func queryCdpsByCollateralTypeHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
cliCtx, ok := rest.ParseQueryHeightOrReturnBadRequest(w, cliCtx, r)
|
||||
if !ok {
|
||||
@ -68,7 +72,7 @@ func queryCdpsHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
|
||||
vars := mux.Vars(r)
|
||||
collateralType := vars[types.RestCollateralType]
|
||||
|
||||
params := types.NewQueryCdpsParams(collateralType)
|
||||
params := types.NewQueryCdpsByCollateralTypeParams(collateralType)
|
||||
|
||||
bz, err := cliCtx.Codec.MarshalJSON(params)
|
||||
if err != nil {
|
||||
@ -76,7 +80,7 @@ func queryCdpsHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
|
||||
return
|
||||
}
|
||||
|
||||
res, height, err := cliCtx.QueryWithData(fmt.Sprintf("custom/cdp/%s", types.QueryGetCdps), bz)
|
||||
res, height, err := cliCtx.QueryWithData(fmt.Sprintf("custom/cdp/%s", types.QueryGetCdpsByCollateralType), bz)
|
||||
if err != nil {
|
||||
rest.WriteErrorResponse(w, http.StatusNotFound, err.Error())
|
||||
return
|
||||
@ -193,3 +197,91 @@ func getAccountsHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
|
||||
rest.PostProcessResponse(w, cliCtx, res)
|
||||
}
|
||||
}
|
||||
|
||||
func getSavingsRateDistributedHandler(cliCtx context.CLIContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
cliCtx, ok := rest.ParseQueryHeightOrReturnBadRequest(w, cliCtx, r)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
res, height, err := cliCtx.QueryWithData(fmt.Sprintf("custom/cdp/%s", types.QueryGetSavingsRateDistributed), nil)
|
||||
cliCtx = cliCtx.WithHeight(height)
|
||||
if err != nil {
|
||||
rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
rest.PostProcessResponse(w, cliCtx, res)
|
||||
}
|
||||
}
|
||||
|
||||
func queryCdpsHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
_, page, limit, err := rest.ParseHTTPArgsWithLimit(r, 0)
|
||||
if err != nil {
|
||||
rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
// Parse the query height
|
||||
cliCtx, ok := rest.ParseQueryHeightOrReturnBadRequest(w, cliCtx, r)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
var cdpCollateralType string
|
||||
var cdpOwner sdk.AccAddress
|
||||
var cdpID uint64
|
||||
var cdpRatio sdk.Dec
|
||||
|
||||
if x := r.URL.Query().Get(RestCollateralType); len(x) != 0 {
|
||||
cdpCollateralType = strings.TrimSpace(x)
|
||||
}
|
||||
|
||||
if x := r.URL.Query().Get(RestOwner); len(x) != 0 {
|
||||
cdpOwnerStr := strings.ToLower(strings.TrimSpace(x))
|
||||
cdpOwner, err = sdk.AccAddressFromBech32(cdpOwnerStr)
|
||||
if err != nil {
|
||||
rest.WriteErrorResponse(w, http.StatusBadRequest, fmt.Sprintf("cannot parse address from cdp owner %s", cdpOwnerStr))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if x := r.URL.Query().Get(RestID); len(x) != 0 {
|
||||
cdpID, err = strconv.ParseUint(strings.TrimSpace(x), 10, 64)
|
||||
if err != nil {
|
||||
rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if x := r.URL.Query().Get(RestRatio); len(x) != 0 {
|
||||
cdpRatio, err = sdk.NewDecFromStr(strings.TrimSpace(x))
|
||||
if err != nil {
|
||||
rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
} else {
|
||||
// Set to sdk.Dec(0) so that if not specified in params it doesn't panic when unmarshaled
|
||||
cdpRatio = sdk.ZeroDec()
|
||||
}
|
||||
|
||||
params := types.NewQueryCdpsParams(page, limit, cdpCollateralType, cdpOwner, cdpID, cdpRatio)
|
||||
bz, err := cliCtx.Codec.MarshalJSON(params)
|
||||
if err != nil {
|
||||
rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
route := fmt.Sprintf("custom/%s/%s", types.ModuleName, types.QueryGetCdps)
|
||||
res, height, err := cliCtx.QueryWithData(route, bz)
|
||||
cliCtx = cliCtx.WithHeight(height)
|
||||
if err != nil {
|
||||
rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
rest.PostProcessResponse(w, cliCtx, res)
|
||||
}
|
||||
}
|
||||
|
@ -8,6 +8,15 @@ import (
|
||||
"github.com/cosmos/cosmos-sdk/types/rest"
|
||||
)
|
||||
|
||||
// REST Variable names
|
||||
// nolint
|
||||
const (
|
||||
RestOwner = "owner"
|
||||
RestCollateralType = "collateral-type"
|
||||
RestID = "id"
|
||||
RestRatio = "ratio"
|
||||
)
|
||||
|
||||
// RegisterRoutes - Central function to define routes that get registered by the main application
|
||||
func RegisterRoutes(cliCtx context.CLIContext, r *mux.Router) {
|
||||
registerQueryRoutes(cliCtx, r)
|
||||
|
@ -20,7 +20,6 @@ func registerTxRoutes(cliCtx context.CLIContext, r *mux.Router) {
|
||||
r.HandleFunc("/cdp/{owner}/{collateralType}/withdraw", postWithdrawHandlerFn(cliCtx)).Methods("POST")
|
||||
r.HandleFunc("/cdp/{owner}/{collateralType}/draw", postDrawHandlerFn(cliCtx)).Methods("POST")
|
||||
r.HandleFunc("/cdp/{owner}/{collateralType}/repay", postRepayHandlerFn(cliCtx)).Methods("POST")
|
||||
|
||||
}
|
||||
|
||||
func postCdpHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
|
||||
|
@ -88,6 +88,8 @@ func InitGenesis(ctx sdk.Context, k Keeper, pk types.PricefeedKeeper, sk types.S
|
||||
for _, d := range gs.Deposits {
|
||||
k.SetDeposit(ctx, d)
|
||||
}
|
||||
|
||||
k.SetSavingsRateDistributed(ctx, gs.SavingsRateDistributed)
|
||||
}
|
||||
|
||||
// ExportGenesis export genesis state for cdp module
|
||||
@ -108,11 +110,12 @@ func ExportGenesis(ctx sdk.Context, k Keeper) GenesisState {
|
||||
cdpID := k.GetNextCdpID(ctx)
|
||||
debtDenom := k.GetDebtDenom(ctx)
|
||||
govDenom := k.GetGovDenom(ctx)
|
||||
savingsRateDist := k.GetSavingsRateDistributed(ctx)
|
||||
|
||||
previousDistributionTime, found := k.GetPreviousSavingsDistribution(ctx)
|
||||
if !found {
|
||||
previousDistributionTime = DefaultPreviousDistributionTime
|
||||
}
|
||||
|
||||
return NewGenesisState(params, cdps, deposits, cdpID, debtDenom, govDenom, previousDistributionTime)
|
||||
return NewGenesisState(params, cdps, deposits, cdpID, debtDenom, govDenom, previousDistributionTime, savingsRateDist)
|
||||
}
|
||||
|
@ -22,13 +22,14 @@ type GenesisTestSuite struct {
|
||||
|
||||
func (suite *GenesisTestSuite) TestInvalidGenState() {
|
||||
type args struct {
|
||||
params cdp.Params
|
||||
cdps cdp.CDPs
|
||||
deposits cdp.Deposits
|
||||
startingID uint64
|
||||
debtDenom string
|
||||
govDenom string
|
||||
prevDistTime time.Time
|
||||
params cdp.Params
|
||||
cdps cdp.CDPs
|
||||
deposits cdp.Deposits
|
||||
startingID uint64
|
||||
debtDenom string
|
||||
govDenom string
|
||||
prevDistTime time.Time
|
||||
savingsRateDist sdk.Int
|
||||
}
|
||||
type errArgs struct {
|
||||
expectPass bool
|
||||
@ -47,12 +48,13 @@ func (suite *GenesisTestSuite) TestInvalidGenState() {
|
||||
{
|
||||
name: "empty debt denom",
|
||||
args: args{
|
||||
params: cdp.DefaultParams(),
|
||||
cdps: cdp.CDPs{},
|
||||
deposits: cdp.Deposits{},
|
||||
debtDenom: "",
|
||||
govDenom: cdp.DefaultGovDenom,
|
||||
prevDistTime: cdp.DefaultPreviousDistributionTime,
|
||||
params: cdp.DefaultParams(),
|
||||
cdps: cdp.CDPs{},
|
||||
deposits: cdp.Deposits{},
|
||||
debtDenom: "",
|
||||
govDenom: cdp.DefaultGovDenom,
|
||||
prevDistTime: cdp.DefaultPreviousDistributionTime,
|
||||
savingsRateDist: cdp.DefaultSavingsRateDistributed,
|
||||
},
|
||||
errArgs: errArgs{
|
||||
expectPass: false,
|
||||
@ -62,12 +64,13 @@ func (suite *GenesisTestSuite) TestInvalidGenState() {
|
||||
{
|
||||
name: "empty gov denom",
|
||||
args: args{
|
||||
params: cdp.DefaultParams(),
|
||||
cdps: cdp.CDPs{},
|
||||
deposits: cdp.Deposits{},
|
||||
debtDenom: cdp.DefaultDebtDenom,
|
||||
govDenom: "",
|
||||
prevDistTime: cdp.DefaultPreviousDistributionTime,
|
||||
params: cdp.DefaultParams(),
|
||||
cdps: cdp.CDPs{},
|
||||
deposits: cdp.Deposits{},
|
||||
debtDenom: cdp.DefaultDebtDenom,
|
||||
govDenom: "",
|
||||
prevDistTime: cdp.DefaultPreviousDistributionTime,
|
||||
savingsRateDist: cdp.DefaultSavingsRateDistributed,
|
||||
},
|
||||
errArgs: errArgs{
|
||||
expectPass: false,
|
||||
@ -77,27 +80,46 @@ func (suite *GenesisTestSuite) TestInvalidGenState() {
|
||||
{
|
||||
name: "empty distribution time",
|
||||
args: args{
|
||||
params: cdp.DefaultParams(),
|
||||
cdps: cdp.CDPs{},
|
||||
deposits: cdp.Deposits{},
|
||||
debtDenom: cdp.DefaultDebtDenom,
|
||||
govDenom: cdp.DefaultGovDenom,
|
||||
prevDistTime: time.Time{},
|
||||
params: cdp.DefaultParams(),
|
||||
cdps: cdp.CDPs{},
|
||||
deposits: cdp.Deposits{},
|
||||
debtDenom: cdp.DefaultDebtDenom,
|
||||
govDenom: cdp.DefaultGovDenom,
|
||||
prevDistTime: time.Time{},
|
||||
savingsRateDist: cdp.DefaultSavingsRateDistributed,
|
||||
},
|
||||
errArgs: errArgs{
|
||||
expectPass: false,
|
||||
contains: "previous distribution time not set",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "negative savings rate distributed",
|
||||
args: args{
|
||||
params: cdp.DefaultParams(),
|
||||
cdps: cdp.CDPs{},
|
||||
deposits: cdp.Deposits{},
|
||||
debtDenom: cdp.DefaultDebtDenom,
|
||||
govDenom: cdp.DefaultGovDenom,
|
||||
prevDistTime: cdp.DefaultPreviousDistributionTime,
|
||||
savingsRateDist: sdk.NewInt(-100),
|
||||
},
|
||||
errArgs: errArgs{
|
||||
expectPass: false,
|
||||
contains: "savings rate distributed should not be negative",
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
suite.Run(tc.name, func() {
|
||||
gs := cdp.NewGenesisState(tc.args.params, tc.args.cdps, tc.args.deposits, tc.args.startingID, tc.args.debtDenom, tc.args.govDenom, tc.args.prevDistTime)
|
||||
gs := cdp.NewGenesisState(tc.args.params, tc.args.cdps, tc.args.deposits, tc.args.startingID,
|
||||
tc.args.debtDenom, tc.args.govDenom, tc.args.prevDistTime, tc.args.savingsRateDist)
|
||||
err := gs.Validate()
|
||||
if tc.errArgs.expectPass {
|
||||
suite.Require().NoError(err)
|
||||
} else {
|
||||
suite.Require().Error(err)
|
||||
suite.T().Log(err)
|
||||
suite.Require().True(strings.Contains(err.Error(), tc.errArgs.contains))
|
||||
}
|
||||
})
|
||||
|
@ -110,3 +110,23 @@ func (k Keeper) IterateCdpsByCollateralRatio(ctx sdk.Context, collateralType str
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// SetSavingsRateDistributed sets the SavingsRateDistributed in the store
|
||||
func (k Keeper) SetSavingsRateDistributed(ctx sdk.Context, totalDistributed sdk.Int) {
|
||||
store := prefix.NewStore(ctx.KVStore(k.key), types.SavingsRateDistributedKey)
|
||||
bz := k.cdc.MustMarshalBinaryLengthPrefixed(totalDistributed)
|
||||
store.Set([]byte{}, bz)
|
||||
}
|
||||
|
||||
// GetSavingsRateDistributed gets the SavingsRateDistributed from the store
|
||||
func (k Keeper) GetSavingsRateDistributed(ctx sdk.Context) sdk.Int {
|
||||
savingsRateDistributed := sdk.ZeroInt()
|
||||
store := prefix.NewStore(ctx.KVStore(k.key), types.SavingsRateDistributedKey)
|
||||
bz := store.Get([]byte{})
|
||||
if bz == nil {
|
||||
return savingsRateDistributed
|
||||
}
|
||||
|
||||
k.cdc.MustUnmarshalBinaryLengthPrefixed(bz, &savingsRateDistributed)
|
||||
return savingsRateDistributed
|
||||
}
|
||||
|
48
x/cdp/keeper/keeper_test.go
Normal file
48
x/cdp/keeper/keeper_test.go
Normal file
@ -0,0 +1,48 @@
|
||||
package keeper_test
|
||||
|
||||
import (
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/stretchr/testify/suite"
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
tmtime "github.com/tendermint/tendermint/types/time"
|
||||
|
||||
"github.com/kava-labs/kava/app"
|
||||
"github.com/kava-labs/kava/x/cdp/keeper"
|
||||
)
|
||||
|
||||
type KeeperTestSuite struct {
|
||||
suite.Suite
|
||||
|
||||
keeper keeper.Keeper
|
||||
app app.TestApp
|
||||
ctx sdk.Context
|
||||
}
|
||||
|
||||
func (suite *KeeperTestSuite) SetupTest() {
|
||||
config := sdk.GetConfig()
|
||||
app.SetBech32AddressPrefixes(config)
|
||||
suite.ResetChain()
|
||||
return
|
||||
}
|
||||
|
||||
func (suite *KeeperTestSuite) ResetChain() {
|
||||
tApp := app.NewTestApp()
|
||||
ctx := tApp.NewContext(true, abci.Header{Height: 1, Time: tmtime.Now()})
|
||||
keeper := tApp.GetCDPKeeper()
|
||||
|
||||
suite.app = tApp
|
||||
suite.ctx = ctx
|
||||
suite.keeper = keeper
|
||||
}
|
||||
|
||||
func (suite *KeeperTestSuite) TestGetSetSavingsRateDistributed() {
|
||||
suite.ResetChain()
|
||||
|
||||
// Set savings rate distributed value
|
||||
savingsRateDist := sdk.NewInt(555000555000)
|
||||
suite.keeper.SetSavingsRateDistributed(suite.ctx, savingsRateDist)
|
||||
|
||||
// Check store's savings rate distributed value
|
||||
s := suite.keeper.GetSavingsRateDistributed(suite.ctx)
|
||||
suite.Equal(savingsRateDist, s)
|
||||
}
|
@ -31,6 +31,16 @@ func (k Keeper) GetCollateral(ctx sdk.Context, collateralType string) (types.Col
|
||||
return types.CollateralParam{}, false
|
||||
}
|
||||
|
||||
// GetCollateralTypes returns an array of collateral types
|
||||
func (k Keeper) GetCollateralTypes(ctx sdk.Context) []string {
|
||||
params := k.GetParams(ctx)
|
||||
var denoms []string
|
||||
for _, cp := range params.CollateralParams {
|
||||
denoms = append(denoms, cp.Type)
|
||||
}
|
||||
return denoms
|
||||
}
|
||||
|
||||
// GetDebtParam returns the debt param with matching denom
|
||||
func (k Keeper) GetDebtParam(ctx sdk.Context, denom string) (types.DebtParam, bool) {
|
||||
dp := k.GetParams(ctx).DebtParam
|
||||
|
@ -3,6 +3,7 @@ package keeper
|
||||
import (
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
||||
@ -18,15 +19,19 @@ func NewQuerier(keeper Keeper) sdk.Querier {
|
||||
case types.QueryGetCdp:
|
||||
return queryGetCdp(ctx, req, keeper)
|
||||
case types.QueryGetCdps:
|
||||
return queryGetCdps(ctx, req, keeper)
|
||||
case types.QueryGetCdpDeposits:
|
||||
return queryGetDeposits(ctx, req, keeper)
|
||||
case types.QueryGetCdpsByCollateralType: // legacy, maintained for REST API
|
||||
return queryGetCdpsByCollateralType(ctx, req, keeper)
|
||||
case types.QueryGetCdpsByCollateralization:
|
||||
case types.QueryGetCdpsByCollateralization: // legacy, maintained for REST API
|
||||
return queryGetCdpsByRatio(ctx, req, keeper)
|
||||
case types.QueryGetParams:
|
||||
return queryGetParams(ctx, req, keeper)
|
||||
case types.QueryGetCdpDeposits:
|
||||
return queryGetDeposits(ctx, req, keeper)
|
||||
case types.QueryGetAccounts:
|
||||
return queryGetAccounts(ctx, req, keeper)
|
||||
case types.QueryGetSavingsRateDistributed:
|
||||
return queryGetSavingsRateDistributed(ctx, req, keeper)
|
||||
default:
|
||||
return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unknown %s query endpoint %s", types.ModuleName, path[0])
|
||||
}
|
||||
@ -43,7 +48,7 @@ func queryGetCdp(ctx sdk.Context, req abci.RequestQuery, keeper Keeper) ([]byte,
|
||||
|
||||
_, valid := keeper.GetCollateralTypePrefix(ctx, requestParams.CollateralType)
|
||||
if !valid {
|
||||
return nil, sdkerrors.Wrap(types.ErrCollateralNotSupported, requestParams.CollateralType)
|
||||
return nil, sdkerrors.Wrap(types.ErrInvalidCollateral, requestParams.CollateralType)
|
||||
}
|
||||
|
||||
cdp, found := keeper.GetCdpByOwnerAndCollateralType(ctx, requestParams.Owner, requestParams.CollateralType)
|
||||
@ -71,7 +76,7 @@ func queryGetDeposits(ctx sdk.Context, req abci.RequestQuery, keeper Keeper) ([]
|
||||
|
||||
_, valid := keeper.GetCollateralTypePrefix(ctx, requestParams.CollateralType)
|
||||
if !valid {
|
||||
return nil, sdkerrors.Wrap(types.ErrCollateralNotSupported, requestParams.CollateralType)
|
||||
return nil, sdkerrors.Wrap(types.ErrInvalidCollateral, requestParams.CollateralType)
|
||||
}
|
||||
|
||||
cdp, found := keeper.GetCdpByOwnerAndCollateralType(ctx, requestParams.Owner, requestParams.CollateralType)
|
||||
@ -98,7 +103,7 @@ func queryGetCdpsByRatio(ctx sdk.Context, req abci.RequestQuery, keeper Keeper)
|
||||
}
|
||||
_, valid := keeper.GetCollateralTypePrefix(ctx, requestParams.CollateralType)
|
||||
if !valid {
|
||||
return nil, sdkerrors.Wrap(types.ErrCollateralNotSupported, requestParams.CollateralType)
|
||||
return nil, sdkerrors.Wrap(types.ErrInvalidCollateral, requestParams.CollateralType)
|
||||
}
|
||||
|
||||
ratio, err := keeper.CalculateCollateralizationRatioFromAbsoluteRatio(ctx, requestParams.CollateralType, requestParams.Ratio, "liquidation")
|
||||
@ -120,16 +125,16 @@ func queryGetCdpsByRatio(ctx sdk.Context, req abci.RequestQuery, keeper Keeper)
|
||||
return bz, nil
|
||||
}
|
||||
|
||||
// query all cdps with matching collateral denom
|
||||
// query all cdps with matching collateral type
|
||||
func queryGetCdpsByCollateralType(ctx sdk.Context, req abci.RequestQuery, keeper Keeper) ([]byte, error) {
|
||||
var requestParams types.QueryCdpsParams
|
||||
var requestParams types.QueryCdpsByCollateralTypeParams
|
||||
err := types.ModuleCdc.UnmarshalJSON(req.Data, &requestParams)
|
||||
if err != nil {
|
||||
return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error())
|
||||
}
|
||||
_, valid := keeper.GetCollateralTypePrefix(ctx, requestParams.CollateralType)
|
||||
if !valid {
|
||||
return nil, sdkerrors.Wrap(types.ErrCollateralNotSupported, requestParams.CollateralType)
|
||||
return nil, sdkerrors.Wrap(types.ErrInvalidCollateral, requestParams.CollateralType)
|
||||
}
|
||||
|
||||
cdps := keeper.GetAllCdpsByCollateralType(ctx, requestParams.CollateralType)
|
||||
@ -178,3 +183,175 @@ func queryGetAccounts(ctx sdk.Context, req abci.RequestQuery, keeper Keeper) ([]
|
||||
}
|
||||
return bz, nil
|
||||
}
|
||||
|
||||
// query get savings rate distributed in the cdp store
|
||||
func queryGetSavingsRateDistributed(ctx sdk.Context, req abci.RequestQuery, keeper Keeper) ([]byte, error) {
|
||||
// Get savings rate distributed
|
||||
savingsRateDist := keeper.GetSavingsRateDistributed(ctx)
|
||||
|
||||
// Encode results
|
||||
bz, err := codec.MarshalJSONIndent(types.ModuleCdc, savingsRateDist)
|
||||
if err != nil {
|
||||
return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error())
|
||||
}
|
||||
return bz, nil
|
||||
}
|
||||
|
||||
// query cdps in store and filter by request params
|
||||
func queryGetCdps(ctx sdk.Context, req abci.RequestQuery, keeper Keeper) ([]byte, error) {
|
||||
var params types.QueryCdpsParams
|
||||
err := types.ModuleCdc.UnmarshalJSON(req.Data, ¶ms)
|
||||
if err != nil {
|
||||
return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error())
|
||||
}
|
||||
|
||||
// Filter CDPs
|
||||
filteredCDPs := FilterCDPs(ctx, keeper, params)
|
||||
|
||||
bz, err := codec.MarshalJSONIndent(keeper.cdc, filteredCDPs)
|
||||
if err != nil {
|
||||
return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error())
|
||||
}
|
||||
|
||||
return bz, nil
|
||||
}
|
||||
|
||||
// FilterCDPs queries the store for all CDPs that match query params
|
||||
func FilterCDPs(ctx sdk.Context, k Keeper, params types.QueryCdpsParams) types.AugmentedCDPs {
|
||||
var matchCollateralType, matchOwner, matchID, matchRatio types.CDPs
|
||||
|
||||
// match cdp owner (if supplied)
|
||||
if len(params.Owner) > 0 {
|
||||
denoms := k.GetCollateralTypes(ctx)
|
||||
for _, denom := range denoms {
|
||||
cdp, found := k.GetCdpByOwnerAndCollateralType(ctx, params.Owner, denom)
|
||||
if found {
|
||||
matchOwner = append(matchOwner, cdp)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// match cdp collateral denom (if supplied)
|
||||
if len(params.CollateralType) > 0 {
|
||||
// if owner is specified only iterate over already matched cdps for efficiency
|
||||
if len(params.Owner) > 0 {
|
||||
for _, cdp := range matchOwner {
|
||||
if cdp.Type == params.CollateralType {
|
||||
matchCollateralType = append(matchCollateralType, cdp)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
matchCollateralType = k.GetAllCdpsByCollateralType(ctx, params.CollateralType)
|
||||
}
|
||||
}
|
||||
|
||||
// match cdp ID (if supplied)
|
||||
if params.ID != 0 {
|
||||
denoms := k.GetCollateralTypes(ctx)
|
||||
for _, denom := range denoms {
|
||||
cdp, found := k.GetCDP(ctx, denom, params.ID)
|
||||
if found {
|
||||
matchID = append(matchID, cdp)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// match cdp ratio (if supplied)
|
||||
if params.Ratio.GT(sdk.ZeroDec()) {
|
||||
denoms := k.GetCollateralTypes(ctx)
|
||||
for _, denom := range denoms {
|
||||
ratio, err := k.CalculateCollateralizationRatioFromAbsoluteRatio(ctx, denom, params.Ratio, "liquidation")
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
cdpsUnderRatio := k.GetAllCdpsByCollateralTypeAndRatio(ctx, denom, ratio)
|
||||
matchRatio = append(matchRatio, cdpsUnderRatio...)
|
||||
}
|
||||
}
|
||||
|
||||
var commonCDPs types.CDPs
|
||||
// If no params specified, fetch all CDPs
|
||||
if len(params.CollateralType) == 0 && len(params.Owner) == 0 && params.ID == 0 && params.Ratio.Equal(sdk.ZeroDec()) {
|
||||
commonCDPs = k.GetAllCdps(ctx)
|
||||
}
|
||||
|
||||
// Find the intersection of any matched CDPs
|
||||
if len(params.CollateralType) > 0 {
|
||||
if len(matchCollateralType) > 0 {
|
||||
commonCDPs = matchCollateralType
|
||||
} else {
|
||||
return types.AugmentedCDPs{}
|
||||
}
|
||||
}
|
||||
|
||||
if len(params.Owner) > 0 {
|
||||
if len(matchCollateralType) > 0 {
|
||||
if len(commonCDPs) > 0 {
|
||||
commonCDPs = FindIntersection(commonCDPs, matchOwner)
|
||||
} else {
|
||||
commonCDPs = matchOwner
|
||||
}
|
||||
} else {
|
||||
commonCDPs = matchOwner
|
||||
}
|
||||
}
|
||||
if params.ID != 0 {
|
||||
if len(matchID) > 0 {
|
||||
if len(commonCDPs) > 0 {
|
||||
commonCDPs = FindIntersection(commonCDPs, matchID)
|
||||
} else {
|
||||
commonCDPs = matchID
|
||||
}
|
||||
} else {
|
||||
return types.AugmentedCDPs{}
|
||||
}
|
||||
}
|
||||
if params.Ratio.GT(sdk.ZeroDec()) {
|
||||
if len(matchRatio) > 0 {
|
||||
if len(commonCDPs) > 0 {
|
||||
commonCDPs = FindIntersection(commonCDPs, matchRatio)
|
||||
} else {
|
||||
commonCDPs = matchRatio
|
||||
}
|
||||
} else {
|
||||
return types.AugmentedCDPs{}
|
||||
}
|
||||
}
|
||||
// Load augmented CDPs
|
||||
var augmentedCDPs types.AugmentedCDPs
|
||||
for _, cdp := range commonCDPs {
|
||||
augmentedCDP := k.LoadAugmentedCDP(ctx, cdp)
|
||||
augmentedCDPs = append(augmentedCDPs, augmentedCDP)
|
||||
}
|
||||
|
||||
// Apply page and limit params
|
||||
var paginatedCDPs types.AugmentedCDPs
|
||||
start, end := client.Paginate(len(augmentedCDPs), params.Page, params.Limit, 100)
|
||||
if start < 0 || end < 0 {
|
||||
paginatedCDPs = types.AugmentedCDPs{}
|
||||
} else {
|
||||
paginatedCDPs = augmentedCDPs[start:end]
|
||||
}
|
||||
|
||||
return paginatedCDPs
|
||||
}
|
||||
|
||||
// FindIntersection finds the intersection of two CDP arrays in linear time complexity O(n + n)
|
||||
func FindIntersection(x types.CDPs, y types.CDPs) types.CDPs {
|
||||
cdpSet := make(types.CDPs, 0)
|
||||
cdpMap := make(map[uint64]bool)
|
||||
|
||||
for i := 0; i < len(x); i++ {
|
||||
cdp := x[i]
|
||||
cdpMap[cdp.ID] = true
|
||||
}
|
||||
|
||||
for i := 0; i < len(y); i++ {
|
||||
cdp := y[i]
|
||||
if _, found := cdpMap[cdp.ID]; found {
|
||||
cdpSet = append(cdpSet, cdp)
|
||||
}
|
||||
}
|
||||
|
||||
return cdpSet
|
||||
}
|
||||
|
@ -116,7 +116,7 @@ func (suite *QuerierTestSuite) TestQueryCdp() {
|
||||
ctx := suite.ctx.WithIsCheckTx(false)
|
||||
query := abci.RequestQuery{
|
||||
Path: strings.Join([]string{custom, types.QuerierRoute, types.QueryGetCdp}, "/"),
|
||||
Data: types.ModuleCdc.MustMarshalJSON(types.NewQueryCdpParams(suite.cdps[0].Owner, suite.cdps[0].Collateral.Denom+"-a")),
|
||||
Data: types.ModuleCdc.MustMarshalJSON(types.NewQueryCdpParams(suite.cdps[0].Owner, suite.cdps[0].Type)),
|
||||
}
|
||||
bz, err := suite.querier(ctx, []string{types.QueryGetCdp}, query)
|
||||
suite.Nil(err)
|
||||
@ -156,10 +156,10 @@ func (suite *QuerierTestSuite) TestQueryCdp() {
|
||||
func (suite *QuerierTestSuite) TestQueryCdpsByCollateralType() {
|
||||
ctx := suite.ctx.WithIsCheckTx(false)
|
||||
query := abci.RequestQuery{
|
||||
Path: strings.Join([]string{custom, types.QuerierRoute, types.QueryGetCdps}, "/"),
|
||||
Data: types.ModuleCdc.MustMarshalJSON(types.NewQueryCdpsParams(suite.cdps[0].Collateral.Denom + "-a")),
|
||||
Path: strings.Join([]string{custom, types.QuerierRoute, types.QueryGetCdpsByCollateralType}, "/"),
|
||||
Data: types.ModuleCdc.MustMarshalJSON(types.NewQueryCdpsByCollateralTypeParams(suite.cdps[0].Type)),
|
||||
}
|
||||
bz, err := suite.querier(ctx, []string{types.QueryGetCdps}, query)
|
||||
bz, err := suite.querier(ctx, []string{types.QueryGetCdpsByCollateralType}, query)
|
||||
suite.Nil(err)
|
||||
suite.NotNil(bz)
|
||||
|
||||
@ -168,10 +168,10 @@ func (suite *QuerierTestSuite) TestQueryCdpsByCollateralType() {
|
||||
suite.Equal(50, len(c))
|
||||
|
||||
query = abci.RequestQuery{
|
||||
Path: strings.Join([]string{custom, types.QuerierRoute, types.QueryGetCdps}, "/"),
|
||||
Data: types.ModuleCdc.MustMarshalJSON(types.NewQueryCdpsParams("lol-a")),
|
||||
Path: strings.Join([]string{custom, types.QuerierRoute, types.QueryGetCdpsByCollateralType}, "/"),
|
||||
Data: types.ModuleCdc.MustMarshalJSON(types.NewQueryCdpsByCollateralTypeParams("lol-a")),
|
||||
}
|
||||
_, err = suite.querier(ctx, []string{types.QueryGetCdps}, query)
|
||||
_, err = suite.querier(ctx, []string{types.QueryGetCdpsByCollateralType}, query)
|
||||
suite.Error(err)
|
||||
}
|
||||
|
||||
@ -265,7 +265,7 @@ func (suite *QuerierTestSuite) TestQueryDeposits() {
|
||||
ctx := suite.ctx.WithIsCheckTx(false)
|
||||
query := abci.RequestQuery{
|
||||
Path: strings.Join([]string{custom, types.QuerierRoute, types.QueryGetCdpDeposits}, "/"),
|
||||
Data: types.ModuleCdc.MustMarshalJSON(types.NewQueryCdpDeposits(suite.cdps[0].Owner, suite.cdps[0].Collateral.Denom+"-a")),
|
||||
Data: types.ModuleCdc.MustMarshalJSON(types.NewQueryCdpDeposits(suite.cdps[0].Owner, suite.cdps[0].Type)),
|
||||
}
|
||||
|
||||
bz, err := suite.querier(ctx, []string{types.QueryGetCdpDeposits}, query)
|
||||
@ -303,6 +303,89 @@ func (suite *QuerierTestSuite) TestQueryAccounts() {
|
||||
suite.Require().True(findByName("savings"))
|
||||
}
|
||||
|
||||
func (suite *QuerierTestSuite) TestQuerySavingsRateDistributed() {
|
||||
ctx := suite.ctx.WithIsCheckTx(false)
|
||||
bz, err := suite.querier(ctx, []string{types.QueryGetSavingsRateDistributed}, abci.RequestQuery{})
|
||||
suite.Nil(err)
|
||||
suite.NotNil(bz)
|
||||
|
||||
var distAmount sdk.Int
|
||||
suite.Nil(types.ModuleCdc.UnmarshalJSON(bz, &distAmount))
|
||||
suite.True(sdk.ZeroInt().Equal(distAmount))
|
||||
}
|
||||
|
||||
func (suite *QuerierTestSuite) TestFindIntersection() {
|
||||
a := types.CDPs{suite.cdps[0], suite.cdps[1], suite.cdps[2], suite.cdps[3], suite.cdps[4]}
|
||||
b := types.CDPs{suite.cdps[3], suite.cdps[4], suite.cdps[5], suite.cdps[6], suite.cdps[7]}
|
||||
expectedIntersection1 := types.CDPs{suite.cdps[3], suite.cdps[4]}
|
||||
|
||||
intersection1 := keeper.FindIntersection(a, b)
|
||||
suite.Require().Equal(intersection1, expectedIntersection1)
|
||||
|
||||
c := types.CDPs{suite.cdps[0], suite.cdps[1], suite.cdps[2], suite.cdps[3], suite.cdps[4]}
|
||||
d := types.CDPs{suite.cdps[5], suite.cdps[6], suite.cdps[7], suite.cdps[8], suite.cdps[9]}
|
||||
expectedIntersection2 := types.CDPs{}
|
||||
|
||||
intersection2 := keeper.FindIntersection(c, d)
|
||||
suite.Require().Equal(intersection2, expectedIntersection2)
|
||||
|
||||
e := types.CDPs{suite.cdps[0]}
|
||||
f := types.CDPs{}
|
||||
expectedIntersection3 := types.CDPs{}
|
||||
|
||||
intersection3 := keeper.FindIntersection(e, f)
|
||||
suite.Require().Equal(intersection3, expectedIntersection3)
|
||||
}
|
||||
|
||||
func (suite *QuerierTestSuite) TestFilterCDPs() {
|
||||
paramsType := types.NewQueryCdpsParams(1, 100, "btc-a", sdk.AccAddress{}, 0, sdk.ZeroDec())
|
||||
filteredCDPs1 := keeper.FilterCDPs(suite.ctx, suite.keeper, paramsType)
|
||||
suite.Require().Equal(len(filteredCDPs1), 50)
|
||||
|
||||
paramsOwner := types.NewQueryCdpsParams(1, 100, "", suite.cdps[10].Owner, 0, sdk.ZeroDec())
|
||||
filteredCDPs2 := keeper.FilterCDPs(suite.ctx, suite.keeper, paramsOwner)
|
||||
suite.Require().Equal(len(filteredCDPs2), 1)
|
||||
suite.Require().Equal(filteredCDPs2[0].Owner, suite.cdps[10].Owner)
|
||||
|
||||
paramsID := types.NewQueryCdpsParams(1, 100, "", sdk.AccAddress{}, 68, sdk.ZeroDec())
|
||||
filteredCDPs3 := keeper.FilterCDPs(suite.ctx, suite.keeper, paramsID)
|
||||
suite.Require().Equal(len(filteredCDPs3), 1)
|
||||
suite.Require().Equal(filteredCDPs3[0].ID, suite.cdps[68-1].ID)
|
||||
|
||||
ratioCountBtc := 0
|
||||
btcRatio := d("2500")
|
||||
for _, cdp := range suite.cdps {
|
||||
if cdp.Type == "btc-a" {
|
||||
absoluteRatio := suite.keeper.CalculateCollateralToDebtRatio(suite.ctx, cdp.Collateral, cdp.Type, cdp.Principal)
|
||||
collateralizationRatio, _ := suite.keeper.CalculateCollateralizationRatioFromAbsoluteRatio(suite.ctx, cdp.Type, absoluteRatio, "liquidation")
|
||||
if collateralizationRatio.LT(btcRatio) {
|
||||
ratioCountBtc += 1
|
||||
}
|
||||
}
|
||||
}
|
||||
paramsTypeAndRatio := types.NewQueryCdpsParams(1, 100, "btc-a", sdk.AccAddress{}, 0, sdk.NewDec(2500))
|
||||
filteredCDPs4 := keeper.FilterCDPs(suite.ctx, suite.keeper, paramsTypeAndRatio)
|
||||
suite.Require().Equal(len(filteredCDPs4), ratioCountBtc)
|
||||
}
|
||||
|
||||
func (suite *QuerierTestSuite) TestQueryCdps() {
|
||||
ctx := suite.ctx.WithIsCheckTx(false)
|
||||
params := types.NewQueryCdpsParams(1, 100, "btc-a", sdk.AccAddress{}, 0, sdk.ZeroDec())
|
||||
|
||||
query := abci.RequestQuery{
|
||||
Path: strings.Join([]string{custom, types.QuerierRoute, types.QueryGetCdps}, "/"),
|
||||
Data: types.ModuleCdc.MustMarshalJSON(params),
|
||||
}
|
||||
|
||||
bz, err := suite.querier(ctx, []string{types.QueryGetCdps}, query)
|
||||
suite.Nil(err)
|
||||
suite.NotNil(bz)
|
||||
|
||||
output := types.AugmentedCDPs{}
|
||||
suite.Nil(types.ModuleCdc.UnmarshalJSON(bz, &output))
|
||||
suite.Equal(50, len(output))
|
||||
}
|
||||
|
||||
func TestQuerierTestSuite(t *testing.T) {
|
||||
suite.Run(t, new(QuerierTestSuite))
|
||||
}
|
||||
|
@ -58,6 +58,11 @@ func (k Keeper) DistributeSavingsRate(ctx sdk.Context, debtDenom string) error {
|
||||
return false
|
||||
}
|
||||
|
||||
// update total savings rate distributed by surplus to distribute
|
||||
previousSavingsDistributed := k.GetSavingsRateDistributed(ctx)
|
||||
newTotalDistributed := previousSavingsDistributed.Add(interest)
|
||||
k.SetSavingsRateDistributed(ctx, newTotalDistributed)
|
||||
|
||||
interestCoins := sdk.NewCoins(sdk.NewCoin(debtDenom, interest))
|
||||
err := k.supplyKeeper.SendCoinsFromModuleToAccount(ctx, types.SavingsRateMacc, acc.GetAddress(), interestCoins)
|
||||
if err != nil {
|
||||
|
@ -18,15 +18,17 @@ import (
|
||||
type SavingsTestSuite struct {
|
||||
suite.Suite
|
||||
|
||||
keeper keeper.Keeper
|
||||
app app.TestApp
|
||||
ctx sdk.Context
|
||||
addrs []sdk.AccAddress
|
||||
keeper keeper.Keeper
|
||||
app app.TestApp
|
||||
ctx sdk.Context
|
||||
addrs []sdk.AccAddress
|
||||
amountToDistribute int64
|
||||
}
|
||||
|
||||
func (suite *SavingsTestSuite) SetupTest() {
|
||||
tApp := app.NewTestApp()
|
||||
ctx := tApp.NewContext(true, abci.Header{Height: 1, Time: tmtime.Now()})
|
||||
|
||||
_, addrs := app.GeneratePrivKeyAddressPairs(3)
|
||||
authGS := app.NewAuthGenState(
|
||||
addrs,
|
||||
@ -34,25 +36,33 @@ func (suite *SavingsTestSuite) SetupTest() {
|
||||
cs(c("usdx", 100000)), cs(c("usdx", 50000)), cs(c("usdx", 50000)),
|
||||
},
|
||||
)
|
||||
|
||||
tApp.InitializeFromGenesisStates(
|
||||
authGS,
|
||||
NewPricefeedGenStateMulti(),
|
||||
NewCDPGenStateMulti(),
|
||||
)
|
||||
|
||||
sk := tApp.GetSupplyKeeper()
|
||||
macc := sk.GetModuleAccount(ctx, types.SavingsRateMacc)
|
||||
err := sk.MintCoins(ctx, macc.GetName(), cs(c("usdx", 10000)))
|
||||
distAmount := int64(10000)
|
||||
err := sk.MintCoins(ctx, macc.GetName(), cs(c("usdx", distAmount)))
|
||||
suite.NoError(err)
|
||||
|
||||
keeper := tApp.GetCDPKeeper()
|
||||
suite.app = tApp
|
||||
suite.keeper = keeper
|
||||
suite.ctx = ctx
|
||||
suite.addrs = addrs
|
||||
suite.amountToDistribute = distAmount
|
||||
}
|
||||
|
||||
func (suite *SavingsTestSuite) TestApplySavingsRate() {
|
||||
preSavingsRateDistAmount := suite.keeper.GetSavingsRateDistributed(suite.ctx)
|
||||
|
||||
err := suite.keeper.DistributeSavingsRate(suite.ctx, "usdx")
|
||||
suite.NoError(err)
|
||||
|
||||
ak := suite.app.GetAccountKeeper()
|
||||
acc0 := ak.GetAccount(suite.ctx, suite.addrs[0])
|
||||
suite.Equal(cs(c("usdx", 105000)), acc0.GetCoins())
|
||||
@ -60,9 +70,14 @@ func (suite *SavingsTestSuite) TestApplySavingsRate() {
|
||||
suite.Equal(cs(c("usdx", 52500)), acc1.GetCoins())
|
||||
acc2 := ak.GetAccount(suite.ctx, suite.addrs[2])
|
||||
suite.Equal(cs(c("usdx", 52500)), acc2.GetCoins())
|
||||
|
||||
sk := suite.app.GetSupplyKeeper()
|
||||
macc := sk.GetModuleAccount(suite.ctx, types.SavingsRateMacc)
|
||||
suite.True(macc.GetCoins().AmountOf("usdx").IsZero())
|
||||
|
||||
expectedPostSavingsRateDistAmount := preSavingsRateDistAmount.Add(sdk.NewInt(suite.amountToDistribute))
|
||||
postSavingsRateDistAmount := suite.keeper.GetSavingsRateDistributed(suite.ctx)
|
||||
suite.True(expectedPostSavingsRateDistAmount.Equal(postSavingsRateDistAmount))
|
||||
}
|
||||
|
||||
func (suite *SavingsTestSuite) TestGetSetPreviousDistributionTime() {
|
||||
@ -76,7 +91,21 @@ func (suite *SavingsTestSuite) TestGetSetPreviousDistributionTime() {
|
||||
pdt, f := suite.keeper.GetPreviousSavingsDistribution(suite.ctx)
|
||||
suite.True(f)
|
||||
suite.Equal(now, pdt)
|
||||
}
|
||||
|
||||
func (suite *SavingsTestSuite) TestGetSetSavingsRateDistributed() {
|
||||
// Savings rate dist set to 0 when the default genesis is used
|
||||
preSavingsRateDistAmount := suite.keeper.GetSavingsRateDistributed(suite.ctx)
|
||||
suite.True(preSavingsRateDistAmount.Equal(types.DefaultSavingsRateDistributed))
|
||||
|
||||
// Adding new dist amount to existing dist so default genesis value can be updated in the future
|
||||
amountToDistribute := sdk.NewInt(9876543210)
|
||||
newTotalDistributed := preSavingsRateDistAmount.Add(amountToDistribute)
|
||||
|
||||
suite.NotPanics(func() { suite.keeper.SetSavingsRateDistributed(suite.ctx, newTotalDistributed) })
|
||||
|
||||
postSavingsRateDistAmount := suite.keeper.GetSavingsRateDistributed(suite.ctx)
|
||||
suite.Equal(newTotalDistributed, postSavingsRateDistAmount)
|
||||
}
|
||||
|
||||
func TestSavingsTestSuite(t *testing.T) {
|
||||
|
@ -121,6 +121,7 @@ func NewAugmentedCDP(cdp CDP, collateralValue sdk.Coin, collateralizationRatio s
|
||||
CDP: CDP{
|
||||
ID: cdp.ID,
|
||||
Owner: cdp.Owner,
|
||||
Type: cdp.Type,
|
||||
Collateral: cdp.Collateral,
|
||||
Principal: cdp.Principal,
|
||||
AccumulatedFees: cdp.AccumulatedFees,
|
||||
@ -146,7 +147,7 @@ func (augCDP AugmentedCDP) String() string {
|
||||
Collateralization ratio: %s`,
|
||||
augCDP.Owner,
|
||||
augCDP.ID,
|
||||
augCDP.Collateral.Denom,
|
||||
augCDP.Type,
|
||||
augCDP.Collateral,
|
||||
augCDP.CollateralValue,
|
||||
augCDP.Principal,
|
||||
|
@ -17,10 +17,12 @@ type GenesisState struct {
|
||||
DebtDenom string `json:"debt_denom" yaml:"debt_denom"`
|
||||
GovDenom string `json:"gov_denom" yaml:"gov_denom"`
|
||||
PreviousDistributionTime time.Time `json:"previous_distribution_time" yaml:"previous_distribution_time"`
|
||||
SavingsRateDistributed sdk.Int `json:"savings_rate_distributed" yaml:"savings_rate_distributed"`
|
||||
}
|
||||
|
||||
// NewGenesisState returns a new genesis state
|
||||
func NewGenesisState(params Params, cdps CDPs, deposits Deposits, startingCdpID uint64, debtDenom, govDenom string, previousDistTime time.Time) GenesisState {
|
||||
func NewGenesisState(params Params, cdps CDPs, deposits Deposits, startingCdpID uint64,
|
||||
debtDenom, govDenom string, previousDistTime time.Time, savingsRateDist sdk.Int) GenesisState {
|
||||
return GenesisState{
|
||||
Params: params,
|
||||
CDPs: cdps,
|
||||
@ -29,6 +31,7 @@ func NewGenesisState(params Params, cdps CDPs, deposits Deposits, startingCdpID
|
||||
DebtDenom: debtDenom,
|
||||
GovDenom: govDenom,
|
||||
PreviousDistributionTime: previousDistTime,
|
||||
SavingsRateDistributed: savingsRateDist,
|
||||
}
|
||||
}
|
||||
|
||||
@ -42,6 +45,7 @@ func DefaultGenesisState() GenesisState {
|
||||
DefaultDebtDenom,
|
||||
DefaultGovDenom,
|
||||
DefaultPreviousDistributionTime,
|
||||
DefaultSavingsRateDistributed,
|
||||
)
|
||||
}
|
||||
|
||||
@ -65,6 +69,10 @@ func (gs GenesisState) Validate() error {
|
||||
return fmt.Errorf("previous distribution time not set")
|
||||
}
|
||||
|
||||
if err := validateSavingsRateDistributed(gs.SavingsRateDistributed); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := sdk.ValidateDenom(gs.DebtDenom); err != nil {
|
||||
return fmt.Errorf(fmt.Sprintf("debt denom invalid: %v", err))
|
||||
}
|
||||
@ -76,6 +84,19 @@ func (gs GenesisState) Validate() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func validateSavingsRateDistributed(i interface{}) error {
|
||||
savingsRateDist, ok := i.(sdk.Int)
|
||||
if !ok {
|
||||
return fmt.Errorf("invalid parameter type: %T", i)
|
||||
}
|
||||
|
||||
if savingsRateDist.IsNegative() {
|
||||
return fmt.Errorf("savings rate distributed should not be negative: %s", savingsRateDist)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Equal checks whether two gov GenesisState structs are equivalent
|
||||
func (gs GenesisState) Equal(gs2 GenesisState) bool {
|
||||
b1 := ModuleCdc.MustMarshalBinaryBare(gs)
|
||||
|
@ -47,6 +47,7 @@ var sep = []byte(":")
|
||||
// - 0x07<denom>:feeRate
|
||||
// - 0x08:previousDistributionTime
|
||||
// - 0x09<marketID>:downTime
|
||||
// - 0x10:totalDistributed
|
||||
|
||||
// KVStore key prefixes
|
||||
var (
|
||||
@ -60,6 +61,7 @@ var (
|
||||
PrincipalKeyPrefix = []byte{0x07}
|
||||
PreviousDistributionTimeKey = []byte{0x08}
|
||||
PricefeedStatusKeyPrefix = []byte{0x09}
|
||||
SavingsRateDistributedKey = []byte{0x10}
|
||||
)
|
||||
|
||||
// GetCdpIDBytes returns the byte representation of the cdpID
|
||||
|
@ -76,7 +76,8 @@ func (msg MsgCreateCDP) String() string {
|
||||
Sender: %s
|
||||
Collateral: %s
|
||||
Principal: %s
|
||||
`, msg.Sender, msg.Collateral, msg.Principal)
|
||||
Collateral Type: %s
|
||||
`, msg.Sender, msg.Collateral, msg.Principal, msg.CollateralType)
|
||||
}
|
||||
|
||||
// MsgDeposit deposit collateral to an existing cdp.
|
||||
|
@ -14,19 +14,20 @@ import (
|
||||
|
||||
// Parameter keys
|
||||
var (
|
||||
KeyGlobalDebtLimit = []byte("GlobalDebtLimit")
|
||||
KeyCollateralParams = []byte("CollateralParams")
|
||||
KeyDebtParam = []byte("DebtParam")
|
||||
KeyDistributionFrequency = []byte("DistributionFrequency")
|
||||
KeyCircuitBreaker = []byte("CircuitBreaker")
|
||||
KeyDebtThreshold = []byte("DebtThreshold")
|
||||
KeyDebtLot = []byte("DebtLot")
|
||||
KeySurplusThreshold = []byte("SurplusThreshold")
|
||||
KeySurplusLot = []byte("SurplusLot")
|
||||
DefaultGlobalDebt = sdk.NewCoin(DefaultStableDenom, sdk.ZeroInt())
|
||||
DefaultCircuitBreaker = false
|
||||
DefaultCollateralParams = CollateralParams{}
|
||||
DefaultDebtParam = DebtParam{
|
||||
KeyGlobalDebtLimit = []byte("GlobalDebtLimit")
|
||||
KeyCollateralParams = []byte("CollateralParams")
|
||||
KeyDebtParam = []byte("DebtParam")
|
||||
KeyDistributionFrequency = []byte("DistributionFrequency")
|
||||
KeyCircuitBreaker = []byte("CircuitBreaker")
|
||||
KeyDebtThreshold = []byte("DebtThreshold")
|
||||
KeyDebtLot = []byte("DebtLot")
|
||||
KeySurplusThreshold = []byte("SurplusThreshold")
|
||||
KeySurplusLot = []byte("SurplusLot")
|
||||
KeySavingsRateDistributed = []byte("SavingsRateDistributed")
|
||||
DefaultGlobalDebt = sdk.NewCoin(DefaultStableDenom, sdk.ZeroInt())
|
||||
DefaultCircuitBreaker = false
|
||||
DefaultCollateralParams = CollateralParams{}
|
||||
DefaultDebtParam = DebtParam{
|
||||
Denom: "usdx",
|
||||
ReferenceAsset: "usd",
|
||||
ConversionFactor: sdk.NewInt(6),
|
||||
@ -43,6 +44,7 @@ var (
|
||||
DefaultDebtLot = sdk.NewInt(10000000000)
|
||||
DefaultPreviousDistributionTime = tmtime.Canonical(time.Unix(0, 0))
|
||||
DefaultSavingsDistributionFrequency = time.Hour * 12
|
||||
DefaultSavingsRateDistributed = sdk.NewInt(0)
|
||||
minCollateralPrefix = 0
|
||||
maxCollateralPrefix = 255
|
||||
stabilityFeeMax = sdk.MustNewDecFromStr("1.000000051034942716") // 500% APR
|
||||
|
@ -7,28 +7,18 @@ import (
|
||||
// Querier routes for the cdp module
|
||||
const (
|
||||
QueryGetCdp = "cdp"
|
||||
QueryGetCdpDeposits = "deposits"
|
||||
QueryGetCdps = "cdps"
|
||||
QueryGetCdpsByCollateralization = "ratio"
|
||||
QueryGetCdpDeposits = "deposits"
|
||||
QueryGetCdpsByCollateralization = "ratio" // legacy query, maintained for REST API
|
||||
QueryGetCdpsByCollateralType = "collateralType" // legacy query, maintained for REST API
|
||||
QueryGetParams = "params"
|
||||
QueryGetAccounts = "accounts"
|
||||
QueryGetSavingsRateDistributed = "savings-rate-dist"
|
||||
RestOwner = "owner"
|
||||
RestCollateralType = "collateral-type"
|
||||
RestRatio = "ratio"
|
||||
)
|
||||
|
||||
// QueryCdpsParams params for query /cdp/cdps
|
||||
type QueryCdpsParams struct {
|
||||
CollateralType string // get CDPs with this collateral type
|
||||
}
|
||||
|
||||
// NewQueryCdpsParams returns QueryCdpsParams
|
||||
func NewQueryCdpsParams(collateralType string) QueryCdpsParams {
|
||||
return QueryCdpsParams{
|
||||
CollateralType: collateralType,
|
||||
}
|
||||
}
|
||||
|
||||
// QueryCdpParams params for query /cdp/cdp
|
||||
type QueryCdpParams struct {
|
||||
CollateralType string // get CDPs with this collateral type
|
||||
@ -43,6 +33,28 @@ func NewQueryCdpParams(owner sdk.AccAddress, collateralType string) QueryCdpPara
|
||||
}
|
||||
}
|
||||
|
||||
// QueryCdpsParams is the params for a filtered CDP query
|
||||
type QueryCdpsParams struct {
|
||||
Page int `json:"page" yaml:"page"`
|
||||
Limit int `json:"limit" yaml:"limit"`
|
||||
CollateralType string `json:"collateral_type" yaml:"collateral_type"`
|
||||
Owner sdk.AccAddress `json:"owner" yaml:"owner"`
|
||||
ID uint64 `json:"id" yaml:"id"`
|
||||
Ratio sdk.Dec `json:"ratio" yaml:"ratio"`
|
||||
}
|
||||
|
||||
// NewQueryCdpsParams creates a new QueryCdpsParams
|
||||
func NewQueryCdpsParams(page, limit int, collateralType string, owner sdk.AccAddress, id uint64, ratio sdk.Dec) QueryCdpsParams {
|
||||
return QueryCdpsParams{
|
||||
Page: page,
|
||||
Limit: limit,
|
||||
CollateralType: collateralType,
|
||||
Owner: owner,
|
||||
ID: id,
|
||||
Ratio: ratio,
|
||||
}
|
||||
}
|
||||
|
||||
// QueryCdpDeposits params for query /cdp/deposits
|
||||
type QueryCdpDeposits struct {
|
||||
CollateralType string // get CDPs with this collateral type
|
||||
@ -57,6 +69,18 @@ func NewQueryCdpDeposits(owner sdk.AccAddress, collateralType string) QueryCdpDe
|
||||
}
|
||||
}
|
||||
|
||||
// QueryCdpsByCollateralTypeParams params for query /cdp/cdps/{denom}
|
||||
type QueryCdpsByCollateralTypeParams struct {
|
||||
CollateralType string // get CDPs with this collateral type
|
||||
}
|
||||
|
||||
// NewQueryCdpsByCollateralTypeParams returns QueryCdpsByCollateralTypeParams
|
||||
func NewQueryCdpsByCollateralTypeParams(collateralType string) QueryCdpsByCollateralTypeParams {
|
||||
return QueryCdpsByCollateralTypeParams{
|
||||
CollateralType: collateralType,
|
||||
}
|
||||
}
|
||||
|
||||
// QueryCdpsByRatioParams params for query /cdp/cdps/ratio
|
||||
type QueryCdpsByRatioParams struct {
|
||||
CollateralType string
|
||||
|
Loading…
Reference in New Issue
Block a user