Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add MarketSummary query #894

Merged
merged 5 commits into from
May 13, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
### Features

- [860](https://github.com/umee-network/umee/pull/860) Add IBC upgrade and upgrade-client gov proposals.
- [894](https://github.com/umee-network/umee/pull/894) Add MarketSummary query

### Improvements

Expand Down
32 changes: 32 additions & 0 deletions proto/umee/leverage/v1/query.proto
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,11 @@ service Query {
rpc LiquidationTargets(QueryLiquidationTargetsRequest) returns (QueryLiquidationTargetsResponse) {
option (google.api.http).get = "/umee/leverage/v1/liquidation_targets";
}

// MarketSummary queries a base asset's current borrowing and lending conditions.
rpc MarketSummary(QueryMarketSummaryRequest) returns (QueryMarketSummaryResponse) {
option (google.api.http).get = "/umee/leverage/v1/market_summary";
}
}

// QueryRegisteredTokens defines the request structure for the RegisteredTokens
Expand Down Expand Up @@ -356,3 +361,30 @@ message QueryLiquidationTargetsRequest {}
message QueryLiquidationTargetsResponse {
repeated string targets = 1;
}

// QueryMarketSummaryRequest defines the request structure for the
// MarketSummary gRPC service handler.
message QueryMarketSummaryRequest {
string denom = 1;
}

// QueryMarketSummaryResponse defines the response structure for the
// MarketSummary gRPC service handler.
message QueryMarketSummaryResponse {
string symbol_denom = 1;
uint32 exponent = 2;
string oracle_price = 3
[(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", (gogoproto.nullable) = true];
Comment on lines +376 to +377
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note how nullable is true here - if oracle is down, this field will be null but the query will work.

string uToken_exchange_rate = 4
[(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", (gogoproto.nullable) = false];
string lend_APY = 5
[(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", (gogoproto.nullable) = false];
string borrow_APY = 6
[(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", (gogoproto.nullable) = false];
string market_size = 7
[(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", (gogoproto.nullable) = false];
Comment on lines +384 to +385
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note market_size (tokens) not market_size_usd here. See discussion question in PR description

string available_borrow = 8
[(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", (gogoproto.nullable) = false];
string reserved = 9
[(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", (gogoproto.nullable) = false];
}
42 changes: 42 additions & 0 deletions x/leverage/keeper/grpc_query.go
Original file line number Diff line number Diff line change
Expand Up @@ -558,3 +558,45 @@ func (q Querier) LiquidationTargets(

return &types.QueryLiquidationTargetsResponse{Targets: stringTargets}, nil
}

func (q Querier) MarketSummary(
goCtx context.Context,
req *types.QueryMarketSummaryRequest,
) (*types.QueryMarketSummaryResponse, error) {
if req == nil {
return nil, status.Error(codes.InvalidArgument, "empty request")
}
if req.Denom == "" {
return nil, status.Error(codes.InvalidArgument, "invalid denom")
}

ctx := sdk.UnwrapSDKContext(goCtx)

token, err := q.Keeper.GetRegisteredToken(ctx, req.Denom)
if err != nil {
return nil, status.Error(codes.InvalidArgument, "not accepted Token denom")
}
rate := q.Keeper.DeriveExchangeRate(ctx, req.Denom)
lendAPY := q.Keeper.DeriveLendAPY(ctx, req.Denom)
borrowAPY := q.Keeper.DeriveBorrowAPY(ctx, req.Denom)
marketSizeCoin, _ := q.Keeper.GetTotalLoaned(ctx, req.Denom)
availableBorrow := q.Keeper.GetAvailableToBorrow(ctx, req.Denom)
reserved := q.Keeper.GetReserveAmount(ctx, req.Denom)

resp := types.QueryMarketSummaryResponse{
SymbolDenom: token.SymbolDenom,
Exponent: token.Exponent,
UTokenExchangeRate: rate,
Lend_APY: lendAPY,
Borrow_APY: borrowAPY,
MarketSize: marketSizeCoin.Amount,
AvailableBorrow: availableBorrow,
Reserved: reserved,
}

if oraclePrice, oracleErr := q.Keeper.TokenPrice(ctx, req.Denom); oracleErr == nil {
resp.OraclePrice = &oraclePrice
}

return &resp, nil
}
1 change: 1 addition & 0 deletions x/leverage/spec/03_queries.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ Queries on accepted asset types:
- **Exchange Rate** queries the [uToken Exchange Rate](01_concepts.md#uToken-Exchange-Rate) of a given uToken denomination.
- **Market Size** queries the [Market Size](01_concepts.md#Market-Size) of a specified denomination.
- **Token Market Size** queries the [Market Size](01_concepts.md#Market-Size) of a specified denomination, but denominated in base tokens instead of USD. This amounts to _total loaned by all lenders + interest accrued._
- **Market Summary** combines several asset-specifying queries for more efficient frontend access.

Queries on account addresses:
- **Borrowed** queries for the amount of a given token denomination borrowed by a user. If a denomination is not supplied, the total for each borrowed token is returned.
Expand Down
Loading