mirror of
https://github.com/0glabs/0g-chain.git
synced 2024-12-26 08:15:19 +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'
|
$ref: '#/definitions/CoinCollateral'
|
||||||
principal:
|
principal:
|
||||||
$ref: '#/definitions/CoinPrincipal'
|
$ref: '#/definitions/CoinPrincipal'
|
||||||
|
collateral_type:
|
||||||
|
$ref: '#/definitions/CollateralType'
|
||||||
responses:
|
responses:
|
||||||
200:
|
200:
|
||||||
description: Tx was successfully generated
|
description: Tx was successfully generated
|
||||||
@ -419,7 +421,7 @@
|
|||||||
description: Invalid request
|
description: Invalid request
|
||||||
500:
|
500:
|
||||||
description: Server internal error
|
description: Server internal error
|
||||||
/cdp/{owner}/{denom}/deposits:
|
/cdp/{owner}/{collateral-type}/deposits:
|
||||||
post:
|
post:
|
||||||
summary: Create a deposit to cdp transaction
|
summary: Create a deposit to cdp transaction
|
||||||
tags:
|
tags:
|
||||||
@ -436,11 +438,11 @@
|
|||||||
type: string
|
type: string
|
||||||
x-example: kava1ffv7nhd3z6sych2qpqkk03ec6hzkmufy0r2s4c
|
x-example: kava1ffv7nhd3z6sych2qpqkk03ec6hzkmufy0r2s4c
|
||||||
- in: path
|
- in: path
|
||||||
name: denom
|
name: collateral_type
|
||||||
description: Collateral denom
|
description: Collateral type
|
||||||
required: true
|
required: true
|
||||||
type: string
|
type: string
|
||||||
x-example: xrp
|
x-example: xrp-a
|
||||||
- description: deposit cdp post parameters
|
- description: deposit cdp post parameters
|
||||||
name: post_deposit_req
|
name: post_deposit_req
|
||||||
in: body
|
in: body
|
||||||
@ -456,6 +458,8 @@
|
|||||||
$ref: '#/definitions/Address'
|
$ref: '#/definitions/Address'
|
||||||
collateral:
|
collateral:
|
||||||
$ref: '#/definitions/CoinCollateral'
|
$ref: '#/definitions/CoinCollateral'
|
||||||
|
collateral_type:
|
||||||
|
$ref: '#/definitions/CollateralType'
|
||||||
responses:
|
responses:
|
||||||
200:
|
200:
|
||||||
description: Tx was successfully generated
|
description: Tx was successfully generated
|
||||||
@ -465,7 +469,7 @@
|
|||||||
description: Invalid request
|
description: Invalid request
|
||||||
500:
|
500:
|
||||||
description: Server internal error
|
description: Server internal error
|
||||||
/cdp/{owner}/{denom}/withdraw:
|
/cdp/{owner}/{collateral-type}/withdraw:
|
||||||
post:
|
post:
|
||||||
summary: create a withdraw collateral transaction
|
summary: create a withdraw collateral transaction
|
||||||
tags:
|
tags:
|
||||||
@ -482,11 +486,11 @@
|
|||||||
type: string
|
type: string
|
||||||
x-example: kava1ffv7nhd3z6sych2qpqkk03ec6hzkmufy0r2s4c
|
x-example: kava1ffv7nhd3z6sych2qpqkk03ec6hzkmufy0r2s4c
|
||||||
- in: path
|
- in: path
|
||||||
name: denom
|
name: collateral_type
|
||||||
description: Collateral denom
|
description: Collateral type
|
||||||
required: true
|
required: true
|
||||||
type: string
|
type: string
|
||||||
x-example: xrp
|
x-example: xrp-a
|
||||||
- description: withdraw cdp post parameters
|
- description: withdraw cdp post parameters
|
||||||
name: post_withdraw_req
|
name: post_withdraw_req
|
||||||
in: body
|
in: body
|
||||||
@ -502,6 +506,8 @@
|
|||||||
$ref: '#/definitions/Address'
|
$ref: '#/definitions/Address'
|
||||||
collateral:
|
collateral:
|
||||||
$ref: '#/definitions/CoinCollateral'
|
$ref: '#/definitions/CoinCollateral'
|
||||||
|
collateral_type:
|
||||||
|
$ref: '#/definitions/CollateralType'
|
||||||
responses:
|
responses:
|
||||||
200:
|
200:
|
||||||
description: Tx was successfully generated
|
description: Tx was successfully generated
|
||||||
@ -511,7 +517,7 @@
|
|||||||
description: Invalid request
|
description: Invalid request
|
||||||
500:
|
500:
|
||||||
description: Server internal error
|
description: Server internal error
|
||||||
/cdp/{owner}/{denom}/draw:
|
/cdp/{owner}/{collateral-type}/draw:
|
||||||
post:
|
post:
|
||||||
summary: Create a draw debt transaction
|
summary: Create a draw debt transaction
|
||||||
tags:
|
tags:
|
||||||
@ -528,11 +534,11 @@
|
|||||||
type: string
|
type: string
|
||||||
x-example: kava1ffv7nhd3z6sych2qpqkk03ec6hzkmufy0r2s4c
|
x-example: kava1ffv7nhd3z6sych2qpqkk03ec6hzkmufy0r2s4c
|
||||||
- in: path
|
- in: path
|
||||||
name: denom
|
name: collateral_type
|
||||||
description: Collateral denom
|
description: Collateral type
|
||||||
required: true
|
required: true
|
||||||
type: string
|
type: string
|
||||||
x-example: xrp
|
x-example: xrp-a
|
||||||
- description: draw cdp post parameters
|
- description: draw cdp post parameters
|
||||||
name: post_draw_req
|
name: post_draw_req
|
||||||
in: body
|
in: body
|
||||||
@ -546,6 +552,8 @@
|
|||||||
$ref: '#/definitions/Address'
|
$ref: '#/definitions/Address'
|
||||||
principal:
|
principal:
|
||||||
$ref: '#/definitions/CoinPrincipal'
|
$ref: '#/definitions/CoinPrincipal'
|
||||||
|
collateral_type:
|
||||||
|
$ref: '#/definitions/CollateralType'
|
||||||
responses:
|
responses:
|
||||||
200:
|
200:
|
||||||
description: Tx was successfully generated
|
description: Tx was successfully generated
|
||||||
@ -555,7 +563,7 @@
|
|||||||
description: Invalid request
|
description: Invalid request
|
||||||
500:
|
500:
|
||||||
description: Server internal error
|
description: Server internal error
|
||||||
/cdp/{owner}/{denom}/repay:
|
/cdp/{owner}/{collateral-type}/repay:
|
||||||
post:
|
post:
|
||||||
summary: Repay debt from a CDP
|
summary: Repay debt from a CDP
|
||||||
tags:
|
tags:
|
||||||
@ -572,11 +580,11 @@
|
|||||||
type: string
|
type: string
|
||||||
x-example: kava1ffv7nhd3z6sych2qpqkk03ec6hzkmufy0r2s4c
|
x-example: kava1ffv7nhd3z6sych2qpqkk03ec6hzkmufy0r2s4c
|
||||||
- in: path
|
- in: path
|
||||||
name: denom
|
name: collateral_type
|
||||||
description: Collateral denom
|
description: Collateral type
|
||||||
required: true
|
required: true
|
||||||
type: string
|
type: string
|
||||||
x-example: xrp
|
x-example: xrp-a
|
||||||
- description: repay cdp post parameters
|
- description: repay cdp post parameters
|
||||||
name: post_repay_req
|
name: post_repay_req
|
||||||
in: body
|
in: body
|
||||||
@ -590,6 +598,8 @@
|
|||||||
$ref: '#/definitions/Address'
|
$ref: '#/definitions/Address'
|
||||||
payment:
|
payment:
|
||||||
$ref: '#/definitions/CoinPrincipal'
|
$ref: '#/definitions/CoinPrincipal'
|
||||||
|
collateral_type:
|
||||||
|
$ref: '#/definitions/CollateralType'
|
||||||
responses:
|
responses:
|
||||||
200:
|
200:
|
||||||
description: Tx was successfully generated
|
description: Tx was successfully generated
|
||||||
@ -640,7 +650,6 @@
|
|||||||
type: number
|
type: number
|
||||||
500:
|
500:
|
||||||
description: Server internal error
|
description: Server internal error
|
||||||
|
|
||||||
/cdp/parameters:
|
/cdp/parameters:
|
||||||
get:
|
get:
|
||||||
summary: Get the parameters of the cdp module
|
summary: Get the parameters of the cdp module
|
||||||
@ -669,17 +678,26 @@
|
|||||||
surplus_auction_threshold:
|
surplus_auction_threshold:
|
||||||
type: string
|
type: string
|
||||||
example: '1000000000'
|
example: '1000000000'
|
||||||
|
surplus_auction_lot:
|
||||||
|
type: string
|
||||||
|
example: '10000000'
|
||||||
debt_auction_threshold:
|
debt_auction_threshold:
|
||||||
type: string
|
type: string
|
||||||
example: '1000000000'
|
example: '1000000000'
|
||||||
|
surplus_auction_lot:
|
||||||
|
type: string
|
||||||
|
example: '10000000'
|
||||||
|
savings_distribution_frequency:
|
||||||
|
type: string
|
||||||
|
example: '60000000'
|
||||||
circuit_breaker:
|
circuit_breaker:
|
||||||
type: boolean
|
type: boolean
|
||||||
example: false
|
example: false
|
||||||
500:
|
500:
|
||||||
description: Server internal error
|
description: Server internal error
|
||||||
/cdp/cdps/cdp/{owner}/{denom}:
|
/cdp/cdps/cdp/{owner}/{collateral-type}:
|
||||||
get:
|
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:
|
tags:
|
||||||
- CDP
|
- CDP
|
||||||
produces:
|
produces:
|
||||||
@ -692,11 +710,11 @@
|
|||||||
type: string
|
type: string
|
||||||
x-example: kava1ffv7nhd3z6sych2qpqkk03ec6hzkmufy0r2s4c
|
x-example: kava1ffv7nhd3z6sych2qpqkk03ec6hzkmufy0r2s4c
|
||||||
- in: path
|
- in: path
|
||||||
name: denom
|
name: type
|
||||||
description: Collateral denom
|
description: Collateral type
|
||||||
required: true
|
required: true
|
||||||
type: string
|
type: string
|
||||||
x-example: xrp
|
x-example: xrp-a
|
||||||
responses:
|
responses:
|
||||||
200:
|
200:
|
||||||
description: CDP associated with owner
|
description: CDP associated with owner
|
||||||
@ -704,23 +722,23 @@
|
|||||||
$ref: '#/definitions/CdpResponse'
|
$ref: '#/definitions/CdpResponse'
|
||||||
500:
|
500:
|
||||||
description: Server internal error
|
description: Server internal error
|
||||||
/cdp/cdps/denom/{denom}:
|
/cdp/cdps/denom/{collateral-type}:
|
||||||
get:
|
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:
|
tags:
|
||||||
- CDP
|
- CDP
|
||||||
produces:
|
produces:
|
||||||
- application/json
|
- application/json
|
||||||
parameters:
|
parameters:
|
||||||
- in: path
|
- in: path
|
||||||
name: denom
|
name: type
|
||||||
description: Collateral denom
|
description: Collateral Type
|
||||||
required: true
|
required: true
|
||||||
type: string
|
type: string
|
||||||
x-example: xrp
|
x-example: xrp-a
|
||||||
responses:
|
responses:
|
||||||
200:
|
200:
|
||||||
description: All CDPs with the input collateral denom
|
description: All CDPs with the input collateral type
|
||||||
schema:
|
schema:
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
@ -734,20 +752,20 @@
|
|||||||
$ref: '#/definitions/CdpResponse'
|
$ref: '#/definitions/CdpResponse'
|
||||||
500:
|
500:
|
||||||
description: Server internal error
|
description: Server internal error
|
||||||
/cdp/cdps/ratio/{denom}/{ratio}:
|
/cdp/cdps/ratio/{collateral-type}/{ratio}:
|
||||||
get:
|
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:
|
tags:
|
||||||
- CDP
|
- CDP
|
||||||
produces:
|
produces:
|
||||||
- application/json
|
- application/json
|
||||||
parameters:
|
parameters:
|
||||||
- in: path
|
- in: path
|
||||||
name: denom
|
name: type
|
||||||
description: Collateral denom
|
description: Collateral type
|
||||||
required: true
|
required: true
|
||||||
type: string
|
type: string
|
||||||
x-example: xrp
|
x-example: xrp-a
|
||||||
- in: path
|
- in: path
|
||||||
name: ratio
|
name: ratio
|
||||||
description: Collateralization ratio
|
description: Collateralization ratio
|
||||||
@ -756,7 +774,7 @@
|
|||||||
x-example: "2.0"
|
x-example: "2.0"
|
||||||
responses:
|
responses:
|
||||||
200:
|
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:
|
schema:
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
@ -770,9 +788,9 @@
|
|||||||
$ref: '#/definitions/CdpResponse'
|
$ref: '#/definitions/CdpResponse'
|
||||||
500:
|
500:
|
||||||
description: Server internal error
|
description: Server internal error
|
||||||
/cdp/cdps/cdp/deposits/{owner}/{denom}:
|
/cdp/cdps/cdp/deposits/{owner}/{collateral-type}:
|
||||||
get:
|
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:
|
tags:
|
||||||
- CDP
|
- CDP
|
||||||
produces:
|
produces:
|
||||||
@ -785,11 +803,11 @@
|
|||||||
type: string
|
type: string
|
||||||
x-example: kava1ffv7nhd3z6sych2qpqkk03ec6hzkmufy0r2s4c
|
x-example: kava1ffv7nhd3z6sych2qpqkk03ec6hzkmufy0r2s4c
|
||||||
- in: path
|
- in: path
|
||||||
name: denom
|
name: type
|
||||||
description: Collateral denom
|
description: Collateral type
|
||||||
required: true
|
required: true
|
||||||
type: string
|
type: string
|
||||||
x-example: xrp
|
x-example: xrp-a
|
||||||
responses:
|
responses:
|
||||||
200:
|
200:
|
||||||
description: Deposits associated with the cdp
|
description: Deposits associated with the cdp
|
||||||
@ -805,6 +823,73 @@
|
|||||||
$ref: '#/definitions/CdpDepositResponse'
|
$ref: '#/definitions/CdpDepositResponse'
|
||||||
500:
|
500:
|
||||||
description: Server internal error
|
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:
|
/bep3/swap/create:
|
||||||
post:
|
post:
|
||||||
summary: Generate a create atomic swap transaction
|
summary: Generate a create atomic swap transaction
|
||||||
@ -1273,7 +1358,7 @@
|
|||||||
$ref: '#/definitions/BaseReq'
|
$ref: '#/definitions/BaseReq'
|
||||||
owner:
|
owner:
|
||||||
$ref: '#/definitions/Address'
|
$ref: '#/definitions/Address'
|
||||||
denom:
|
type:
|
||||||
type: string
|
type: string
|
||||||
example: bnb
|
example: bnb
|
||||||
responses:
|
responses:
|
||||||
@ -1285,9 +1370,9 @@
|
|||||||
description: Invalid request
|
description: Invalid request
|
||||||
500:
|
500:
|
||||||
description: Internal server error
|
description: Internal server error
|
||||||
/incentive/claims/{owner}/{denom}:
|
/incentive/claims/{owner}/{collateral-type}:
|
||||||
get:
|
get:
|
||||||
summary: Get outstanding claims for the input owner and denom
|
summary: Get outstanding claims for the input owner and collateral type
|
||||||
tags:
|
tags:
|
||||||
- Incentive
|
- Incentive
|
||||||
produces:
|
produces:
|
||||||
@ -1299,11 +1384,11 @@
|
|||||||
type: string
|
type: string
|
||||||
x-example: kava1ffv7nhd3z6sych2qpqkk03ec6hzkmufy0r2s4c
|
x-example: kava1ffv7nhd3z6sych2qpqkk03ec6hzkmufy0r2s4c
|
||||||
- in: path
|
- in: path
|
||||||
name: denom
|
name: type
|
||||||
description: Collateral denom
|
description: Collateral type
|
||||||
required: true
|
required: true
|
||||||
type: string
|
type: string
|
||||||
x-example: bnb
|
x-example: bnb-a
|
||||||
responses:
|
responses:
|
||||||
200:
|
200:
|
||||||
description: USDX Incentive Claims
|
description: USDX Incentive Claims
|
||||||
@ -3457,6 +3542,9 @@
|
|||||||
amount:
|
amount:
|
||||||
type: string
|
type: string
|
||||||
example: '555555'
|
example: '555555'
|
||||||
|
CollateralType:
|
||||||
|
type: string
|
||||||
|
example: xrp-a
|
||||||
CoinCollateral:
|
CoinCollateral:
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
@ -3904,6 +3992,9 @@
|
|||||||
example: kava1q53rwutgpzx7szcrgzqguxyccjpzt9j4cyctn9
|
example: kava1q53rwutgpzx7szcrgzqguxyccjpzt9j4cyctn9
|
||||||
collateral:
|
collateral:
|
||||||
$ref: '#/definitions/CoinCollateral'
|
$ref: '#/definitions/CoinCollateral'
|
||||||
|
type:
|
||||||
|
type: string
|
||||||
|
example: "xrp-a"
|
||||||
principal:
|
principal:
|
||||||
$ref: '#/definitions/CoinPrincipal'
|
$ref: '#/definitions/CoinPrincipal'
|
||||||
accumulated_fees:
|
accumulated_fees:
|
||||||
@ -3987,6 +4078,15 @@
|
|||||||
bid_duration:
|
bid_duration:
|
||||||
type: string
|
type: string
|
||||||
example: 600000000000
|
example: 600000000000
|
||||||
|
increment_surplus:
|
||||||
|
type: string
|
||||||
|
example: "0.05"
|
||||||
|
increment_debt:
|
||||||
|
type: string
|
||||||
|
example: "0.05"
|
||||||
|
increment_collateral:
|
||||||
|
type: string
|
||||||
|
example: "0.05"
|
||||||
AuctionResponse:
|
AuctionResponse:
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
|
@ -22,6 +22,7 @@ const (
|
|||||||
flagType = "type"
|
flagType = "type"
|
||||||
flagDenom = "denom"
|
flagDenom = "denom"
|
||||||
flagPhase = "phase"
|
flagPhase = "phase"
|
||||||
|
flagOwner = "owner"
|
||||||
)
|
)
|
||||||
|
|
||||||
// GetQueryCmd returns the cli query commands for this module
|
// 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:
|
Long: strings.TrimSpace(`Query for all paginated auctions that match optional filters:
|
||||||
Example:
|
Example:
|
||||||
$ kvcli q auction auctions --type=(collateral|surplus|debt)
|
$ kvcli q auction auctions --type=(collateral|surplus|debt)
|
||||||
|
$ kvcli q auction auctions --owner=kava1hatdq32u5x4wnxrtv5wzjzmq49sxgjgsj0mffm
|
||||||
$ kvcli q auction auctions --denom=bnb
|
$ kvcli q auction auctions --denom=bnb
|
||||||
$ kvcli q auction auctions --phase=(forward|reverse)
|
$ kvcli q auction auctions --phase=(forward|reverse)
|
||||||
$ kvcli q auction auctions --page=2 --limit=100
|
$ 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 {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
strType := viper.GetString(flagType)
|
strType := viper.GetString(flagType)
|
||||||
|
strOwner := viper.GetString(flagOwner)
|
||||||
strDenom := viper.GetString(flagDenom)
|
strDenom := viper.GetString(flagDenom)
|
||||||
strPhase := viper.GetString(flagPhase)
|
strPhase := viper.GetString(flagPhase)
|
||||||
page := viper.GetInt(flags.FlagPage)
|
page := viper.GetInt(flags.FlagPage)
|
||||||
@ -91,11 +94,12 @@ $ kvcli q auction auctions --page=2 --limit=100
|
|||||||
|
|
||||||
var (
|
var (
|
||||||
auctionType string
|
auctionType string
|
||||||
|
auctionOwner sdk.AccAddress
|
||||||
auctionDenom string
|
auctionDenom string
|
||||||
auctionPhase string
|
auctionPhase string
|
||||||
)
|
)
|
||||||
|
|
||||||
params := types.NewQueryAllAuctionParams(page, limit, auctionType, auctionDenom, auctionPhase)
|
params := types.NewQueryAllAuctionParams(page, limit, auctionType, auctionDenom, auctionPhase, auctionOwner)
|
||||||
|
|
||||||
if len(strType) != 0 {
|
if len(strType) != 0 {
|
||||||
auctionType = strings.ToLower(strings.TrimSpace(strType))
|
auctionType = strings.ToLower(strings.TrimSpace(strType))
|
||||||
@ -107,6 +111,18 @@ $ kvcli q auction auctions --page=2 --limit=100
|
|||||||
params.Type = auctionType
|
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 {
|
if len(strDenom) != 0 {
|
||||||
auctionDenom := strings.TrimSpace(strDenom)
|
auctionDenom := strings.TrimSpace(strDenom)
|
||||||
err := sdk.ValidateDenom(auctionDenom)
|
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.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().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(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(flagDenom, "", "(optional) filter by auction denom")
|
||||||
cmd.Flags().String(flagPhase, "", "(optional) filter by collateral auction phase, phase: forward/reverse")
|
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 auctionType string
|
||||||
|
var auctionOwner sdk.AccAddress
|
||||||
var auctionDenom string
|
var auctionDenom string
|
||||||
var auctionPhase 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 {
|
if x := r.URL.Query().Get(RestDenom); len(x) != 0 {
|
||||||
auctionDenom = strings.TrimSpace(x)
|
auctionDenom = strings.TrimSpace(x)
|
||||||
err := sdk.ValidateDenom(auctionDenom)
|
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)
|
bz, err := cliCtx.Codec.MarshalJSON(params)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error())
|
rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error())
|
||||||
|
@ -12,6 +12,7 @@ import (
|
|||||||
// nolint
|
// nolint
|
||||||
const (
|
const (
|
||||||
RestType = "type"
|
RestType = "type"
|
||||||
|
RestOwner = "owner"
|
||||||
RestDenom = "denom"
|
RestDenom = "denom"
|
||||||
RestPhase = "phase"
|
RestPhase = "phase"
|
||||||
)
|
)
|
||||||
|
@ -1,12 +1,11 @@
|
|||||||
package keeper
|
package keeper
|
||||||
|
|
||||||
import (
|
import (
|
||||||
abci "github.com/tendermint/tendermint/abci/types"
|
|
||||||
|
|
||||||
"github.com/cosmos/cosmos-sdk/client"
|
"github.com/cosmos/cosmos-sdk/client"
|
||||||
"github.com/cosmos/cosmos-sdk/codec"
|
"github.com/cosmos/cosmos-sdk/codec"
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
||||||
|
abci "github.com/tendermint/tendermint/abci/types"
|
||||||
|
|
||||||
"github.com/kava-labs/kava/x/auction/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))
|
filteredAuctions := make(types.Auctions, 0, len(auctions))
|
||||||
|
|
||||||
for _, auc := range auctions {
|
for _, auc := range auctions {
|
||||||
matchType, matchDenom, matchPhase := true, true, true
|
matchType, matchOwner, matchDenom, matchPhase := true, true, true, true
|
||||||
|
|
||||||
// match auction type (if supplied)
|
// match auction type (if supplied)
|
||||||
if len(params.Type) > 0 {
|
if len(params.Type) > 0 {
|
||||||
matchType = auc.GetType() == params.Type
|
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)
|
// match auction denom (if supplied)
|
||||||
if len(params.Denom) > 0 {
|
if len(params.Denom) > 0 {
|
||||||
matchDenom = auc.GetBid().Denom == params.Denom || auc.GetLot().Denom == params.Denom
|
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
|
matchPhase = auc.GetPhase() == params.Phase
|
||||||
}
|
}
|
||||||
|
|
||||||
if matchType && matchDenom && matchPhase {
|
if matchType && matchOwner && matchDenom && matchPhase {
|
||||||
filteredAuctions = append(filteredAuctions, auc)
|
filteredAuctions = append(filteredAuctions, auc)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -41,7 +41,7 @@ func (suite *QuerierTestSuite) SetupTest() {
|
|||||||
tApp := app.NewTestApp()
|
tApp := app.NewTestApp()
|
||||||
ctx := tApp.NewContext(true, abci.Header{Height: 1, Time: tmtime.Now()})
|
ctx := tApp.NewContext(true, abci.Header{Height: 1, Time: tmtime.Now()})
|
||||||
|
|
||||||
_, addrs := app.GeneratePrivKeyAddressPairs(1)
|
_, addrs := app.GeneratePrivKeyAddressPairs(10)
|
||||||
buyer := addrs[0]
|
buyer := addrs[0]
|
||||||
modName := cdp.LiquidatorMacc
|
modName := cdp.LiquidatorMacc
|
||||||
|
|
||||||
@ -64,8 +64,16 @@ func (suite *QuerierTestSuite) SetupTest() {
|
|||||||
// Populate with auctions
|
// Populate with auctions
|
||||||
randSrc := rand.New(rand.NewSource(int64(1234)))
|
randSrc := rand.New(rand.NewSource(int64(1234)))
|
||||||
for j := 0; j < TestAuctionCount; j++ {
|
for j := 0; j < TestAuctionCount; j++ {
|
||||||
lotAmount := simulation.RandIntBetween(randSrc, 10, 100)
|
var id uint64
|
||||||
id, err := suite.keeper.StartSurplusAuction(suite.ctx, modName, c("token1", int64(lotAmount)), "token2")
|
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)
|
suite.NoError(err)
|
||||||
|
|
||||||
auc, found := suite.keeper.GetAuction(suite.ctx, id)
|
auc, found := suite.keeper.GetAuction(suite.ctx, id)
|
||||||
@ -108,7 +116,7 @@ func (suite *QuerierTestSuite) TestQueryAuctions() {
|
|||||||
query := abci.RequestQuery{
|
query := abci.RequestQuery{
|
||||||
Path: strings.Join([]string{custom, types.QuerierRoute, types.QueryGetAuctions}, "/"),
|
Path: strings.Join([]string{custom, types.QuerierRoute, types.QueryGetAuctions}, "/"),
|
||||||
Data: types.ModuleCdc.MustMarshalJSON(
|
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
|
return ForwardAuctionPhase
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetLotReturns returns a collateral auction's lot owners
|
||||||
|
func (a CollateralAuction) GetLotReturns() WeightedAddresses {
|
||||||
|
return a.LotReturns
|
||||||
|
}
|
||||||
|
|
||||||
// Validate validates the CollateralAuction fields values.
|
// Validate validates the CollateralAuction fields values.
|
||||||
func (a CollateralAuction) Validate() error {
|
func (a CollateralAuction) Validate() error {
|
||||||
if !a.CorrespondingDebt.IsValid() {
|
if !a.CorrespondingDebt.IsValid() {
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
package types
|
package types
|
||||||
|
|
||||||
|
import (
|
||||||
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// QueryGetAuction is the query path for querying one auction
|
// QueryGetAuction is the query path for querying one auction
|
||||||
QueryGetAuction = "auction"
|
QueryGetAuction = "auction"
|
||||||
@ -28,16 +32,18 @@ type QueryAllAuctionParams struct {
|
|||||||
Page int `json:"page" yaml:"page"`
|
Page int `json:"page" yaml:"page"`
|
||||||
Limit int `json:"limit" yaml:"limit"`
|
Limit int `json:"limit" yaml:"limit"`
|
||||||
Type string `json:"type" yaml:"type"`
|
Type string `json:"type" yaml:"type"`
|
||||||
|
Owner sdk.AccAddress `json:"owner" yaml:"owner"`
|
||||||
Denom string `json:"denom" yaml:"denom"`
|
Denom string `json:"denom" yaml:"denom"`
|
||||||
Phase string `json:"phase" yaml:"phase"`
|
Phase string `json:"phase" yaml:"phase"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewQueryAllAuctionParams creates a new QueryAllAuctionParams
|
// 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{
|
return QueryAllAuctionParams{
|
||||||
Page: page,
|
Page: page,
|
||||||
Limit: limit,
|
Limit: limit,
|
||||||
Type: aucType,
|
Type: aucType,
|
||||||
|
Owner: aucOwner,
|
||||||
Denom: aucDenom,
|
Denom: aucDenom,
|
||||||
Phase: aucPhase,
|
Phase: aucPhase,
|
||||||
}
|
}
|
||||||
|
@ -137,7 +137,9 @@ var (
|
|||||||
DefaultDebtLot = types.DefaultDebtLot
|
DefaultDebtLot = types.DefaultDebtLot
|
||||||
DefaultPreviousDistributionTime = types.DefaultPreviousDistributionTime
|
DefaultPreviousDistributionTime = types.DefaultPreviousDistributionTime
|
||||||
DefaultSavingsDistributionFrequency = types.DefaultSavingsDistributionFrequency
|
DefaultSavingsDistributionFrequency = types.DefaultSavingsDistributionFrequency
|
||||||
|
DefaultSavingsRateDistributed = types.DefaultSavingsRateDistributed
|
||||||
MaxSortableDec = types.MaxSortableDec
|
MaxSortableDec = types.MaxSortableDec
|
||||||
|
SavingsRateDistributedKey = types.SavingsRateDistributedKey
|
||||||
)
|
)
|
||||||
|
|
||||||
type (
|
type (
|
||||||
|
@ -2,9 +2,11 @@ package cli
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
"github.com/spf13/viper"
|
||||||
|
|
||||||
"github.com/cosmos/cosmos-sdk/client/context"
|
"github.com/cosmos/cosmos-sdk/client/context"
|
||||||
"github.com/cosmos/cosmos-sdk/client/flags"
|
"github.com/cosmos/cosmos-sdk/client/flags"
|
||||||
@ -16,6 +18,14 @@ import (
|
|||||||
"github.com/kava-labs/kava/x/cdp/types"
|
"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
|
// GetQueryCmd returns the cli query commands for this module
|
||||||
func GetQueryCmd(queryRoute string, cdc *codec.Codec) *cobra.Command {
|
func GetQueryCmd(queryRoute string, cdc *codec.Codec) *cobra.Command {
|
||||||
// Group nameservice queries under a subcommand
|
// Group nameservice queries under a subcommand
|
||||||
@ -26,11 +36,11 @@ func GetQueryCmd(queryRoute string, cdc *codec.Codec) *cobra.Command {
|
|||||||
|
|
||||||
cdpQueryCmd.AddCommand(flags.GetCommands(
|
cdpQueryCmd.AddCommand(flags.GetCommands(
|
||||||
QueryCdpCmd(queryRoute, cdc),
|
QueryCdpCmd(queryRoute, cdc),
|
||||||
QueryCdpsByCollateralTypeCmd(queryRoute, cdc),
|
QueryGetCdpsCmd(queryRoute, cdc),
|
||||||
QueryCdpsByCollateralTypeAndRatioCmd(queryRoute, cdc),
|
|
||||||
QueryCdpDepositsCmd(queryRoute, cdc),
|
QueryCdpDepositsCmd(queryRoute, cdc),
|
||||||
QueryParamsCmd(queryRoute, cdc),
|
QueryParamsCmd(queryRoute, cdc),
|
||||||
QueryGetAccounts(queryRoute, cdc),
|
QueryGetAccounts(queryRoute, cdc),
|
||||||
|
QueryGetSavingsRateDistributed(queryRoute, cdc),
|
||||||
)...)
|
)...)
|
||||||
|
|
||||||
return cdpQueryCmd
|
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
|
// QueryGetCdpsCmd queries the cdps in the store
|
||||||
func QueryCdpsByCollateralTypeCmd(queryRoute string, cdc *codec.Codec) *cobra.Command {
|
func QueryGetCdpsCmd(queryRoute string, cdc *codec.Codec) *cobra.Command {
|
||||||
return &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
Use: "cdps [collateral-type]",
|
Use: "cdps",
|
||||||
Short: "query CDPs by collateral",
|
Short: "query cdps with optional filters",
|
||||||
Long: strings.TrimSpace(
|
Long: strings.TrimSpace(`Query for all paginated cdps that match optional filters:
|
||||||
fmt.Sprintf(`List all CDPs collateralized with the specified asset.
|
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
$ %s query %s cdps atom-a
|
$ kvcli q cdp cdps --collateral-type=bnb
|
||||||
`, version.ClientName, types.ModuleName)),
|
$ kvcli q cdp cdps --owner=kava1hatdq32u5x4wnxrtv5wzjzmq49sxgjgsj0mffm
|
||||||
Args: cobra.ExactArgs(1),
|
$ 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 {
|
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
|
var (
|
||||||
bz, err := cdc.MarshalJSON(types.QueryCdpsParams{CollateralType: args[0]})
|
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 {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cliCtx := context.NewCLIContext().WithCodec(cdc)
|
||||||
|
|
||||||
// Query
|
// Query
|
||||||
route := fmt.Sprintf("custom/%s/%s", queryRoute, types.QueryGetCdps)
|
res, height, err := cliCtx.QueryWithData(fmt.Sprintf("custom/%s/%s", queryRoute, types.QueryGetCdps), bz)
|
||||||
res, _, err := cliCtx.QueryWithData(route, bz)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Decode and print results
|
// Decode and print results
|
||||||
var cdps types.AugmentedCDPs
|
var matchingCDPs types.AugmentedCDPs
|
||||||
cdc.MustUnmarshalJSON(res, &cdps)
|
cdc.MustUnmarshalJSON(res, &matchingCDPs)
|
||||||
return cliCtx.PrintOutput(cdps)
|
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
|
cmd.Flags().Int(flags.FlagPage, 1, "pagination page of CDPs to to query for")
|
||||||
// that are under the specified collateral ratio
|
cmd.Flags().Int(flags.FlagLimit, 100, "pagination limit of CDPs to query for")
|
||||||
func QueryCdpsByCollateralTypeAndRatioCmd(queryRoute string, cdc *codec.Codec) *cobra.Command {
|
cmd.Flags().String(flagCollateralType, "", "(optional) filter by CDP collateral type")
|
||||||
return &cobra.Command{
|
cmd.Flags().String(flagOwner, "", "(optional) filter by CDP owner")
|
||||||
Use: "cdps-by-ratio [collateral-type] [collateralization-ratio]",
|
cmd.Flags().String(flagID, "", "(optional) filter by CDP ID")
|
||||||
Short: "get cdps under a collateralization ratio",
|
cmd.Flags().String(flagRatio, "", "(optional) filter by CDP collateralization ratio threshold")
|
||||||
Long: strings.TrimSpace(
|
|
||||||
fmt.Sprintf(`List all CDPs under a specified collateralization ratio.
|
|
||||||
Collateralization ratio is: collateral * price / debt.
|
|
||||||
|
|
||||||
Example:
|
return cmd
|
||||||
$ %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)
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// QueryCdpDepositsCmd returns the command handler for querying the deposits of a particular cdp
|
// 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{
|
return &cobra.Command{
|
||||||
Use: "params",
|
Use: "params",
|
||||||
Short: "get the cdp module parameters",
|
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,
|
Args: cobra.NoArgs,
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
cliCtx := context.NewCLIContext().WithCodec(cdc)
|
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 {
|
func QueryGetAccounts(queryRoute string, cdc *codec.Codec) *cobra.Command {
|
||||||
return &cobra.Command{
|
return &cobra.Command{
|
||||||
Use: "accounts",
|
Use: "accounts",
|
||||||
Short: "Get module accounts",
|
Short: "get module accounts",
|
||||||
Long: "Get cdp module account addresses",
|
Long: "get cdp module account addresses",
|
||||||
Args: cobra.NoArgs,
|
Args: cobra.NoArgs,
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
cliCtx := context.NewCLIContext().WithCodec(cdc)
|
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 (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/cosmos/cosmos-sdk/client/context"
|
"github.com/cosmos/cosmos-sdk/client/context"
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
@ -16,9 +18,11 @@ import (
|
|||||||
func registerQueryRoutes(cliCtx context.CLIContext, r *mux.Router) {
|
func registerQueryRoutes(cliCtx context.CLIContext, r *mux.Router) {
|
||||||
r.HandleFunc("/cdp/accounts", getAccountsHandlerFn(cliCtx)).Methods("GET")
|
r.HandleFunc("/cdp/accounts", getAccountsHandlerFn(cliCtx)).Methods("GET")
|
||||||
r.HandleFunc("/cdp/parameters", getParamsHandlerFn(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/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"), 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/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")
|
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) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
cliCtx, ok := rest.ParseQueryHeightOrReturnBadRequest(w, cliCtx, r)
|
cliCtx, ok := rest.ParseQueryHeightOrReturnBadRequest(w, cliCtx, r)
|
||||||
if !ok {
|
if !ok {
|
||||||
@ -68,7 +72,7 @@ func queryCdpsHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
|
|||||||
vars := mux.Vars(r)
|
vars := mux.Vars(r)
|
||||||
collateralType := vars[types.RestCollateralType]
|
collateralType := vars[types.RestCollateralType]
|
||||||
|
|
||||||
params := types.NewQueryCdpsParams(collateralType)
|
params := types.NewQueryCdpsByCollateralTypeParams(collateralType)
|
||||||
|
|
||||||
bz, err := cliCtx.Codec.MarshalJSON(params)
|
bz, err := cliCtx.Codec.MarshalJSON(params)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -76,7 +80,7 @@ func queryCdpsHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
|
|||||||
return
|
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 {
|
if err != nil {
|
||||||
rest.WriteErrorResponse(w, http.StatusNotFound, err.Error())
|
rest.WriteErrorResponse(w, http.StatusNotFound, err.Error())
|
||||||
return
|
return
|
||||||
@ -193,3 +197,91 @@ func getAccountsHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
|
|||||||
rest.PostProcessResponse(w, cliCtx, res)
|
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"
|
"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
|
// RegisterRoutes - Central function to define routes that get registered by the main application
|
||||||
func RegisterRoutes(cliCtx context.CLIContext, r *mux.Router) {
|
func RegisterRoutes(cliCtx context.CLIContext, r *mux.Router) {
|
||||||
registerQueryRoutes(cliCtx, r)
|
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}/withdraw", postWithdrawHandlerFn(cliCtx)).Methods("POST")
|
||||||
r.HandleFunc("/cdp/{owner}/{collateralType}/draw", postDrawHandlerFn(cliCtx)).Methods("POST")
|
r.HandleFunc("/cdp/{owner}/{collateralType}/draw", postDrawHandlerFn(cliCtx)).Methods("POST")
|
||||||
r.HandleFunc("/cdp/{owner}/{collateralType}/repay", postRepayHandlerFn(cliCtx)).Methods("POST")
|
r.HandleFunc("/cdp/{owner}/{collateralType}/repay", postRepayHandlerFn(cliCtx)).Methods("POST")
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func postCdpHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
|
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 {
|
for _, d := range gs.Deposits {
|
||||||
k.SetDeposit(ctx, d)
|
k.SetDeposit(ctx, d)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
k.SetSavingsRateDistributed(ctx, gs.SavingsRateDistributed)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ExportGenesis export genesis state for cdp module
|
// ExportGenesis export genesis state for cdp module
|
||||||
@ -108,11 +110,12 @@ func ExportGenesis(ctx sdk.Context, k Keeper) GenesisState {
|
|||||||
cdpID := k.GetNextCdpID(ctx)
|
cdpID := k.GetNextCdpID(ctx)
|
||||||
debtDenom := k.GetDebtDenom(ctx)
|
debtDenom := k.GetDebtDenom(ctx)
|
||||||
govDenom := k.GetGovDenom(ctx)
|
govDenom := k.GetGovDenom(ctx)
|
||||||
|
savingsRateDist := k.GetSavingsRateDistributed(ctx)
|
||||||
|
|
||||||
previousDistributionTime, found := k.GetPreviousSavingsDistribution(ctx)
|
previousDistributionTime, found := k.GetPreviousSavingsDistribution(ctx)
|
||||||
if !found {
|
if !found {
|
||||||
previousDistributionTime = DefaultPreviousDistributionTime
|
previousDistributionTime = DefaultPreviousDistributionTime
|
||||||
}
|
}
|
||||||
|
|
||||||
return NewGenesisState(params, cdps, deposits, cdpID, debtDenom, govDenom, previousDistributionTime)
|
return NewGenesisState(params, cdps, deposits, cdpID, debtDenom, govDenom, previousDistributionTime, savingsRateDist)
|
||||||
}
|
}
|
||||||
|
@ -29,6 +29,7 @@ func (suite *GenesisTestSuite) TestInvalidGenState() {
|
|||||||
debtDenom string
|
debtDenom string
|
||||||
govDenom string
|
govDenom string
|
||||||
prevDistTime time.Time
|
prevDistTime time.Time
|
||||||
|
savingsRateDist sdk.Int
|
||||||
}
|
}
|
||||||
type errArgs struct {
|
type errArgs struct {
|
||||||
expectPass bool
|
expectPass bool
|
||||||
@ -53,6 +54,7 @@ func (suite *GenesisTestSuite) TestInvalidGenState() {
|
|||||||
debtDenom: "",
|
debtDenom: "",
|
||||||
govDenom: cdp.DefaultGovDenom,
|
govDenom: cdp.DefaultGovDenom,
|
||||||
prevDistTime: cdp.DefaultPreviousDistributionTime,
|
prevDistTime: cdp.DefaultPreviousDistributionTime,
|
||||||
|
savingsRateDist: cdp.DefaultSavingsRateDistributed,
|
||||||
},
|
},
|
||||||
errArgs: errArgs{
|
errArgs: errArgs{
|
||||||
expectPass: false,
|
expectPass: false,
|
||||||
@ -68,6 +70,7 @@ func (suite *GenesisTestSuite) TestInvalidGenState() {
|
|||||||
debtDenom: cdp.DefaultDebtDenom,
|
debtDenom: cdp.DefaultDebtDenom,
|
||||||
govDenom: "",
|
govDenom: "",
|
||||||
prevDistTime: cdp.DefaultPreviousDistributionTime,
|
prevDistTime: cdp.DefaultPreviousDistributionTime,
|
||||||
|
savingsRateDist: cdp.DefaultSavingsRateDistributed,
|
||||||
},
|
},
|
||||||
errArgs: errArgs{
|
errArgs: errArgs{
|
||||||
expectPass: false,
|
expectPass: false,
|
||||||
@ -83,21 +86,40 @@ func (suite *GenesisTestSuite) TestInvalidGenState() {
|
|||||||
debtDenom: cdp.DefaultDebtDenom,
|
debtDenom: cdp.DefaultDebtDenom,
|
||||||
govDenom: cdp.DefaultGovDenom,
|
govDenom: cdp.DefaultGovDenom,
|
||||||
prevDistTime: time.Time{},
|
prevDistTime: time.Time{},
|
||||||
|
savingsRateDist: cdp.DefaultSavingsRateDistributed,
|
||||||
},
|
},
|
||||||
errArgs: errArgs{
|
errArgs: errArgs{
|
||||||
expectPass: false,
|
expectPass: false,
|
||||||
contains: "previous distribution time not set",
|
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 {
|
for _, tc := range testCases {
|
||||||
suite.Run(tc.name, func() {
|
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()
|
err := gs.Validate()
|
||||||
if tc.errArgs.expectPass {
|
if tc.errArgs.expectPass {
|
||||||
suite.Require().NoError(err)
|
suite.Require().NoError(err)
|
||||||
} else {
|
} else {
|
||||||
suite.Require().Error(err)
|
suite.Require().Error(err)
|
||||||
|
suite.T().Log(err)
|
||||||
suite.Require().True(strings.Contains(err.Error(), tc.errArgs.contains))
|
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
|
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
|
// GetDebtParam returns the debt param with matching denom
|
||||||
func (k Keeper) GetDebtParam(ctx sdk.Context, denom string) (types.DebtParam, bool) {
|
func (k Keeper) GetDebtParam(ctx sdk.Context, denom string) (types.DebtParam, bool) {
|
||||||
dp := k.GetParams(ctx).DebtParam
|
dp := k.GetParams(ctx).DebtParam
|
||||||
|
@ -3,6 +3,7 @@ package keeper
|
|||||||
import (
|
import (
|
||||||
abci "github.com/tendermint/tendermint/abci/types"
|
abci "github.com/tendermint/tendermint/abci/types"
|
||||||
|
|
||||||
|
"github.com/cosmos/cosmos-sdk/client"
|
||||||
"github.com/cosmos/cosmos-sdk/codec"
|
"github.com/cosmos/cosmos-sdk/codec"
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
||||||
@ -18,15 +19,19 @@ func NewQuerier(keeper Keeper) sdk.Querier {
|
|||||||
case types.QueryGetCdp:
|
case types.QueryGetCdp:
|
||||||
return queryGetCdp(ctx, req, keeper)
|
return queryGetCdp(ctx, req, keeper)
|
||||||
case types.QueryGetCdps:
|
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)
|
return queryGetCdpsByCollateralType(ctx, req, keeper)
|
||||||
case types.QueryGetCdpsByCollateralization:
|
case types.QueryGetCdpsByCollateralization: // legacy, maintained for REST API
|
||||||
return queryGetCdpsByRatio(ctx, req, keeper)
|
return queryGetCdpsByRatio(ctx, req, keeper)
|
||||||
case types.QueryGetParams:
|
case types.QueryGetParams:
|
||||||
return queryGetParams(ctx, req, keeper)
|
return queryGetParams(ctx, req, keeper)
|
||||||
case types.QueryGetCdpDeposits:
|
|
||||||
return queryGetDeposits(ctx, req, keeper)
|
|
||||||
case types.QueryGetAccounts:
|
case types.QueryGetAccounts:
|
||||||
return queryGetAccounts(ctx, req, keeper)
|
return queryGetAccounts(ctx, req, keeper)
|
||||||
|
case types.QueryGetSavingsRateDistributed:
|
||||||
|
return queryGetSavingsRateDistributed(ctx, req, keeper)
|
||||||
default:
|
default:
|
||||||
return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unknown %s query endpoint %s", types.ModuleName, path[0])
|
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)
|
_, valid := keeper.GetCollateralTypePrefix(ctx, requestParams.CollateralType)
|
||||||
if !valid {
|
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)
|
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)
|
_, valid := keeper.GetCollateralTypePrefix(ctx, requestParams.CollateralType)
|
||||||
if !valid {
|
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)
|
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)
|
_, valid := keeper.GetCollateralTypePrefix(ctx, requestParams.CollateralType)
|
||||||
if !valid {
|
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")
|
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
|
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) {
|
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)
|
err := types.ModuleCdc.UnmarshalJSON(req.Data, &requestParams)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error())
|
return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error())
|
||||||
}
|
}
|
||||||
_, valid := keeper.GetCollateralTypePrefix(ctx, requestParams.CollateralType)
|
_, valid := keeper.GetCollateralTypePrefix(ctx, requestParams.CollateralType)
|
||||||
if !valid {
|
if !valid {
|
||||||
return nil, sdkerrors.Wrap(types.ErrCollateralNotSupported, requestParams.CollateralType)
|
return nil, sdkerrors.Wrap(types.ErrInvalidCollateral, requestParams.CollateralType)
|
||||||
}
|
}
|
||||||
|
|
||||||
cdps := keeper.GetAllCdpsByCollateralType(ctx, 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
|
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)
|
ctx := suite.ctx.WithIsCheckTx(false)
|
||||||
query := abci.RequestQuery{
|
query := abci.RequestQuery{
|
||||||
Path: strings.Join([]string{custom, types.QuerierRoute, types.QueryGetCdp}, "/"),
|
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)
|
bz, err := suite.querier(ctx, []string{types.QueryGetCdp}, query)
|
||||||
suite.Nil(err)
|
suite.Nil(err)
|
||||||
@ -156,10 +156,10 @@ func (suite *QuerierTestSuite) TestQueryCdp() {
|
|||||||
func (suite *QuerierTestSuite) TestQueryCdpsByCollateralType() {
|
func (suite *QuerierTestSuite) TestQueryCdpsByCollateralType() {
|
||||||
ctx := suite.ctx.WithIsCheckTx(false)
|
ctx := suite.ctx.WithIsCheckTx(false)
|
||||||
query := abci.RequestQuery{
|
query := abci.RequestQuery{
|
||||||
Path: strings.Join([]string{custom, types.QuerierRoute, types.QueryGetCdps}, "/"),
|
Path: strings.Join([]string{custom, types.QuerierRoute, types.QueryGetCdpsByCollateralType}, "/"),
|
||||||
Data: types.ModuleCdc.MustMarshalJSON(types.NewQueryCdpsParams(suite.cdps[0].Collateral.Denom + "-a")),
|
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.Nil(err)
|
||||||
suite.NotNil(bz)
|
suite.NotNil(bz)
|
||||||
|
|
||||||
@ -168,10 +168,10 @@ func (suite *QuerierTestSuite) TestQueryCdpsByCollateralType() {
|
|||||||
suite.Equal(50, len(c))
|
suite.Equal(50, len(c))
|
||||||
|
|
||||||
query = abci.RequestQuery{
|
query = abci.RequestQuery{
|
||||||
Path: strings.Join([]string{custom, types.QuerierRoute, types.QueryGetCdps}, "/"),
|
Path: strings.Join([]string{custom, types.QuerierRoute, types.QueryGetCdpsByCollateralType}, "/"),
|
||||||
Data: types.ModuleCdc.MustMarshalJSON(types.NewQueryCdpsParams("lol-a")),
|
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)
|
suite.Error(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -265,7 +265,7 @@ func (suite *QuerierTestSuite) TestQueryDeposits() {
|
|||||||
ctx := suite.ctx.WithIsCheckTx(false)
|
ctx := suite.ctx.WithIsCheckTx(false)
|
||||||
query := abci.RequestQuery{
|
query := abci.RequestQuery{
|
||||||
Path: strings.Join([]string{custom, types.QuerierRoute, types.QueryGetCdpDeposits}, "/"),
|
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)
|
bz, err := suite.querier(ctx, []string{types.QueryGetCdpDeposits}, query)
|
||||||
@ -303,6 +303,89 @@ func (suite *QuerierTestSuite) TestQueryAccounts() {
|
|||||||
suite.Require().True(findByName("savings"))
|
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) {
|
func TestQuerierTestSuite(t *testing.T) {
|
||||||
suite.Run(t, new(QuerierTestSuite))
|
suite.Run(t, new(QuerierTestSuite))
|
||||||
}
|
}
|
||||||
|
@ -58,6 +58,11 @@ func (k Keeper) DistributeSavingsRate(ctx sdk.Context, debtDenom string) error {
|
|||||||
return false
|
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))
|
interestCoins := sdk.NewCoins(sdk.NewCoin(debtDenom, interest))
|
||||||
err := k.supplyKeeper.SendCoinsFromModuleToAccount(ctx, types.SavingsRateMacc, acc.GetAddress(), interestCoins)
|
err := k.supplyKeeper.SendCoinsFromModuleToAccount(ctx, types.SavingsRateMacc, acc.GetAddress(), interestCoins)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -22,11 +22,13 @@ type SavingsTestSuite struct {
|
|||||||
app app.TestApp
|
app app.TestApp
|
||||||
ctx sdk.Context
|
ctx sdk.Context
|
||||||
addrs []sdk.AccAddress
|
addrs []sdk.AccAddress
|
||||||
|
amountToDistribute int64
|
||||||
}
|
}
|
||||||
|
|
||||||
func (suite *SavingsTestSuite) SetupTest() {
|
func (suite *SavingsTestSuite) SetupTest() {
|
||||||
tApp := app.NewTestApp()
|
tApp := app.NewTestApp()
|
||||||
ctx := tApp.NewContext(true, abci.Header{Height: 1, Time: tmtime.Now()})
|
ctx := tApp.NewContext(true, abci.Header{Height: 1, Time: tmtime.Now()})
|
||||||
|
|
||||||
_, addrs := app.GeneratePrivKeyAddressPairs(3)
|
_, addrs := app.GeneratePrivKeyAddressPairs(3)
|
||||||
authGS := app.NewAuthGenState(
|
authGS := app.NewAuthGenState(
|
||||||
addrs,
|
addrs,
|
||||||
@ -34,25 +36,33 @@ func (suite *SavingsTestSuite) SetupTest() {
|
|||||||
cs(c("usdx", 100000)), cs(c("usdx", 50000)), cs(c("usdx", 50000)),
|
cs(c("usdx", 100000)), cs(c("usdx", 50000)), cs(c("usdx", 50000)),
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
tApp.InitializeFromGenesisStates(
|
tApp.InitializeFromGenesisStates(
|
||||||
authGS,
|
authGS,
|
||||||
NewPricefeedGenStateMulti(),
|
NewPricefeedGenStateMulti(),
|
||||||
NewCDPGenStateMulti(),
|
NewCDPGenStateMulti(),
|
||||||
)
|
)
|
||||||
|
|
||||||
sk := tApp.GetSupplyKeeper()
|
sk := tApp.GetSupplyKeeper()
|
||||||
macc := sk.GetModuleAccount(ctx, types.SavingsRateMacc)
|
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)
|
suite.NoError(err)
|
||||||
|
|
||||||
keeper := tApp.GetCDPKeeper()
|
keeper := tApp.GetCDPKeeper()
|
||||||
suite.app = tApp
|
suite.app = tApp
|
||||||
suite.keeper = keeper
|
suite.keeper = keeper
|
||||||
suite.ctx = ctx
|
suite.ctx = ctx
|
||||||
suite.addrs = addrs
|
suite.addrs = addrs
|
||||||
|
suite.amountToDistribute = distAmount
|
||||||
}
|
}
|
||||||
|
|
||||||
func (suite *SavingsTestSuite) TestApplySavingsRate() {
|
func (suite *SavingsTestSuite) TestApplySavingsRate() {
|
||||||
|
preSavingsRateDistAmount := suite.keeper.GetSavingsRateDistributed(suite.ctx)
|
||||||
|
|
||||||
err := suite.keeper.DistributeSavingsRate(suite.ctx, "usdx")
|
err := suite.keeper.DistributeSavingsRate(suite.ctx, "usdx")
|
||||||
suite.NoError(err)
|
suite.NoError(err)
|
||||||
|
|
||||||
ak := suite.app.GetAccountKeeper()
|
ak := suite.app.GetAccountKeeper()
|
||||||
acc0 := ak.GetAccount(suite.ctx, suite.addrs[0])
|
acc0 := ak.GetAccount(suite.ctx, suite.addrs[0])
|
||||||
suite.Equal(cs(c("usdx", 105000)), acc0.GetCoins())
|
suite.Equal(cs(c("usdx", 105000)), acc0.GetCoins())
|
||||||
@ -60,9 +70,14 @@ func (suite *SavingsTestSuite) TestApplySavingsRate() {
|
|||||||
suite.Equal(cs(c("usdx", 52500)), acc1.GetCoins())
|
suite.Equal(cs(c("usdx", 52500)), acc1.GetCoins())
|
||||||
acc2 := ak.GetAccount(suite.ctx, suite.addrs[2])
|
acc2 := ak.GetAccount(suite.ctx, suite.addrs[2])
|
||||||
suite.Equal(cs(c("usdx", 52500)), acc2.GetCoins())
|
suite.Equal(cs(c("usdx", 52500)), acc2.GetCoins())
|
||||||
|
|
||||||
sk := suite.app.GetSupplyKeeper()
|
sk := suite.app.GetSupplyKeeper()
|
||||||
macc := sk.GetModuleAccount(suite.ctx, types.SavingsRateMacc)
|
macc := sk.GetModuleAccount(suite.ctx, types.SavingsRateMacc)
|
||||||
suite.True(macc.GetCoins().AmountOf("usdx").IsZero())
|
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() {
|
func (suite *SavingsTestSuite) TestGetSetPreviousDistributionTime() {
|
||||||
@ -76,7 +91,21 @@ func (suite *SavingsTestSuite) TestGetSetPreviousDistributionTime() {
|
|||||||
pdt, f := suite.keeper.GetPreviousSavingsDistribution(suite.ctx)
|
pdt, f := suite.keeper.GetPreviousSavingsDistribution(suite.ctx)
|
||||||
suite.True(f)
|
suite.True(f)
|
||||||
suite.Equal(now, pdt)
|
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) {
|
func TestSavingsTestSuite(t *testing.T) {
|
||||||
|
@ -121,6 +121,7 @@ func NewAugmentedCDP(cdp CDP, collateralValue sdk.Coin, collateralizationRatio s
|
|||||||
CDP: CDP{
|
CDP: CDP{
|
||||||
ID: cdp.ID,
|
ID: cdp.ID,
|
||||||
Owner: cdp.Owner,
|
Owner: cdp.Owner,
|
||||||
|
Type: cdp.Type,
|
||||||
Collateral: cdp.Collateral,
|
Collateral: cdp.Collateral,
|
||||||
Principal: cdp.Principal,
|
Principal: cdp.Principal,
|
||||||
AccumulatedFees: cdp.AccumulatedFees,
|
AccumulatedFees: cdp.AccumulatedFees,
|
||||||
@ -146,7 +147,7 @@ func (augCDP AugmentedCDP) String() string {
|
|||||||
Collateralization ratio: %s`,
|
Collateralization ratio: %s`,
|
||||||
augCDP.Owner,
|
augCDP.Owner,
|
||||||
augCDP.ID,
|
augCDP.ID,
|
||||||
augCDP.Collateral.Denom,
|
augCDP.Type,
|
||||||
augCDP.Collateral,
|
augCDP.Collateral,
|
||||||
augCDP.CollateralValue,
|
augCDP.CollateralValue,
|
||||||
augCDP.Principal,
|
augCDP.Principal,
|
||||||
|
@ -17,10 +17,12 @@ type GenesisState struct {
|
|||||||
DebtDenom string `json:"debt_denom" yaml:"debt_denom"`
|
DebtDenom string `json:"debt_denom" yaml:"debt_denom"`
|
||||||
GovDenom string `json:"gov_denom" yaml:"gov_denom"`
|
GovDenom string `json:"gov_denom" yaml:"gov_denom"`
|
||||||
PreviousDistributionTime time.Time `json:"previous_distribution_time" yaml:"previous_distribution_time"`
|
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
|
// 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{
|
return GenesisState{
|
||||||
Params: params,
|
Params: params,
|
||||||
CDPs: cdps,
|
CDPs: cdps,
|
||||||
@ -29,6 +31,7 @@ func NewGenesisState(params Params, cdps CDPs, deposits Deposits, startingCdpID
|
|||||||
DebtDenom: debtDenom,
|
DebtDenom: debtDenom,
|
||||||
GovDenom: govDenom,
|
GovDenom: govDenom,
|
||||||
PreviousDistributionTime: previousDistTime,
|
PreviousDistributionTime: previousDistTime,
|
||||||
|
SavingsRateDistributed: savingsRateDist,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -42,6 +45,7 @@ func DefaultGenesisState() GenesisState {
|
|||||||
DefaultDebtDenom,
|
DefaultDebtDenom,
|
||||||
DefaultGovDenom,
|
DefaultGovDenom,
|
||||||
DefaultPreviousDistributionTime,
|
DefaultPreviousDistributionTime,
|
||||||
|
DefaultSavingsRateDistributed,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -65,6 +69,10 @@ func (gs GenesisState) Validate() error {
|
|||||||
return fmt.Errorf("previous distribution time not set")
|
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 {
|
if err := sdk.ValidateDenom(gs.DebtDenom); err != nil {
|
||||||
return fmt.Errorf(fmt.Sprintf("debt denom invalid: %v", err))
|
return fmt.Errorf(fmt.Sprintf("debt denom invalid: %v", err))
|
||||||
}
|
}
|
||||||
@ -76,6 +84,19 @@ func (gs GenesisState) Validate() error {
|
|||||||
return nil
|
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
|
// Equal checks whether two gov GenesisState structs are equivalent
|
||||||
func (gs GenesisState) Equal(gs2 GenesisState) bool {
|
func (gs GenesisState) Equal(gs2 GenesisState) bool {
|
||||||
b1 := ModuleCdc.MustMarshalBinaryBare(gs)
|
b1 := ModuleCdc.MustMarshalBinaryBare(gs)
|
||||||
|
@ -47,6 +47,7 @@ var sep = []byte(":")
|
|||||||
// - 0x07<denom>:feeRate
|
// - 0x07<denom>:feeRate
|
||||||
// - 0x08:previousDistributionTime
|
// - 0x08:previousDistributionTime
|
||||||
// - 0x09<marketID>:downTime
|
// - 0x09<marketID>:downTime
|
||||||
|
// - 0x10:totalDistributed
|
||||||
|
|
||||||
// KVStore key prefixes
|
// KVStore key prefixes
|
||||||
var (
|
var (
|
||||||
@ -60,6 +61,7 @@ var (
|
|||||||
PrincipalKeyPrefix = []byte{0x07}
|
PrincipalKeyPrefix = []byte{0x07}
|
||||||
PreviousDistributionTimeKey = []byte{0x08}
|
PreviousDistributionTimeKey = []byte{0x08}
|
||||||
PricefeedStatusKeyPrefix = []byte{0x09}
|
PricefeedStatusKeyPrefix = []byte{0x09}
|
||||||
|
SavingsRateDistributedKey = []byte{0x10}
|
||||||
)
|
)
|
||||||
|
|
||||||
// GetCdpIDBytes returns the byte representation of the cdpID
|
// GetCdpIDBytes returns the byte representation of the cdpID
|
||||||
|
@ -76,7 +76,8 @@ func (msg MsgCreateCDP) String() string {
|
|||||||
Sender: %s
|
Sender: %s
|
||||||
Collateral: %s
|
Collateral: %s
|
||||||
Principal: %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.
|
// MsgDeposit deposit collateral to an existing cdp.
|
||||||
|
@ -23,6 +23,7 @@ var (
|
|||||||
KeyDebtLot = []byte("DebtLot")
|
KeyDebtLot = []byte("DebtLot")
|
||||||
KeySurplusThreshold = []byte("SurplusThreshold")
|
KeySurplusThreshold = []byte("SurplusThreshold")
|
||||||
KeySurplusLot = []byte("SurplusLot")
|
KeySurplusLot = []byte("SurplusLot")
|
||||||
|
KeySavingsRateDistributed = []byte("SavingsRateDistributed")
|
||||||
DefaultGlobalDebt = sdk.NewCoin(DefaultStableDenom, sdk.ZeroInt())
|
DefaultGlobalDebt = sdk.NewCoin(DefaultStableDenom, sdk.ZeroInt())
|
||||||
DefaultCircuitBreaker = false
|
DefaultCircuitBreaker = false
|
||||||
DefaultCollateralParams = CollateralParams{}
|
DefaultCollateralParams = CollateralParams{}
|
||||||
@ -43,6 +44,7 @@ var (
|
|||||||
DefaultDebtLot = sdk.NewInt(10000000000)
|
DefaultDebtLot = sdk.NewInt(10000000000)
|
||||||
DefaultPreviousDistributionTime = tmtime.Canonical(time.Unix(0, 0))
|
DefaultPreviousDistributionTime = tmtime.Canonical(time.Unix(0, 0))
|
||||||
DefaultSavingsDistributionFrequency = time.Hour * 12
|
DefaultSavingsDistributionFrequency = time.Hour * 12
|
||||||
|
DefaultSavingsRateDistributed = sdk.NewInt(0)
|
||||||
minCollateralPrefix = 0
|
minCollateralPrefix = 0
|
||||||
maxCollateralPrefix = 255
|
maxCollateralPrefix = 255
|
||||||
stabilityFeeMax = sdk.MustNewDecFromStr("1.000000051034942716") // 500% APR
|
stabilityFeeMax = sdk.MustNewDecFromStr("1.000000051034942716") // 500% APR
|
||||||
|
@ -7,28 +7,18 @@ import (
|
|||||||
// Querier routes for the cdp module
|
// Querier routes for the cdp module
|
||||||
const (
|
const (
|
||||||
QueryGetCdp = "cdp"
|
QueryGetCdp = "cdp"
|
||||||
QueryGetCdpDeposits = "deposits"
|
|
||||||
QueryGetCdps = "cdps"
|
QueryGetCdps = "cdps"
|
||||||
QueryGetCdpsByCollateralization = "ratio"
|
QueryGetCdpDeposits = "deposits"
|
||||||
|
QueryGetCdpsByCollateralization = "ratio" // legacy query, maintained for REST API
|
||||||
|
QueryGetCdpsByCollateralType = "collateralType" // legacy query, maintained for REST API
|
||||||
QueryGetParams = "params"
|
QueryGetParams = "params"
|
||||||
QueryGetAccounts = "accounts"
|
QueryGetAccounts = "accounts"
|
||||||
|
QueryGetSavingsRateDistributed = "savings-rate-dist"
|
||||||
RestOwner = "owner"
|
RestOwner = "owner"
|
||||||
RestCollateralType = "collateral-type"
|
RestCollateralType = "collateral-type"
|
||||||
RestRatio = "ratio"
|
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
|
// QueryCdpParams params for query /cdp/cdp
|
||||||
type QueryCdpParams struct {
|
type QueryCdpParams struct {
|
||||||
CollateralType string // get CDPs with this collateral type
|
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
|
// QueryCdpDeposits params for query /cdp/deposits
|
||||||
type QueryCdpDeposits struct {
|
type QueryCdpDeposits struct {
|
||||||
CollateralType string // get CDPs with this collateral type
|
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
|
// QueryCdpsByRatioParams params for query /cdp/cdps/ratio
|
||||||
type QueryCdpsByRatioParams struct {
|
type QueryCdpsByRatioParams struct {
|
||||||
CollateralType string
|
CollateralType string
|
||||||
|
Loading…
Reference in New Issue
Block a user