mirror of
				https://github.com/0glabs/0g-chain.git
				synced 2025-11-04 14:57:27 +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