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 symbol name to the x/uibc QueryAllOutflowsResponse #2374

Merged
merged 16 commits into from
Jan 2, 2024
Merged
14 changes: 6 additions & 8 deletions proto/umee/uibc/v1/query.proto
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
syntax = "proto3";
package umee.uibc.v1;

import "google/api/annotations.proto";
import "gogoproto/gogo.proto";
import "cosmos/base/v1beta1/coin.proto";
import "cosmos_proto/cosmos.proto";
import "umee/uibc/v1/quota.proto";
import "gogoproto/gogo.proto";
import "google/api/annotations.proto";
import "google/protobuf/timestamp.proto";
import "cosmos/base/v1beta1/coin.proto";
import "umee/uibc/v1/quota.proto";
import "umee/uibc/v1/uibc.proto";

option go_package = "github.com/umee-network/umee/v6/x/uibc";

Expand Down Expand Up @@ -102,8 +103,5 @@ message QueryAllOutflows {}

// QueryOutflowResponse defines response type of Query/Outflow
message QueryAllOutflowsResponse {
repeated cosmos.base.v1beta1.DecCoin outflows = 1 [
(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.DecCoins",
(gogoproto.nullable) = false
];
repeated DecCoinSymbol outflows = 1 [(gogoproto.nullable) = false];
}
11 changes: 11 additions & 0 deletions proto/umee/uibc/v1/uibc.proto
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,14 @@ message ICS20Memo {
// messages is a list of `sdk.Msg`s that will be executed when handling ICS20 transfer.
repeated google.protobuf.Any messages = 1;
}

// DecCoinSymbol extends the Cosmos SDK DecCoin type and adds symbol name.
message DecCoinSymbol {
string denom = 1;
string amount = 2
[(cosmos_proto.scalar) = "cosmos.Dec",
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
(gogoproto.nullable) = false];
// token symbol name
string symbol = 3;
}
10 changes: 10 additions & 0 deletions util/genmap/genmap.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,13 @@ func Pick[K comparable, V any](m map[K]V, keys []K) map[K]V {
}
return picked
}

func MapToSlice[K comparable, V any](m map[K]V) []V {
ls := make([]V, len(m))
i := 0
for _, o := range m {
ls[i] = o
i++
}
return ls
}
15 changes: 15 additions & 0 deletions util/genmap/genmap_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package genmap

import (
"sort"
"testing"

"gotest.tools/v3/assert"
Expand Down Expand Up @@ -29,3 +30,17 @@ func TestPick(t *testing.T) {
m2 = Pick(m, []string{"other"})
assert.DeepEqual(t, map[string]int{}, m2)
}

func TestMapToSlice(t *testing.T) {
m := map[string]int{
"one": 1, "two": 2, "thirty": 30,
}
ls := MapToSlice(m)
sort.Ints(ls)
assert.DeepEqual(t, []int{1, 2, 30}, ls)

m = map[string]int{}
ls = MapToSlice(m)
assert.DeepEqual(t, []int{}, ls)

}
83 changes: 41 additions & 42 deletions x/leverage/keeper/grpc_query.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ func (q Querier) Params(
}

ctx := sdk.UnwrapSDKContext(goCtx)
params := q.Keeper.GetParams(ctx)
params := q.GetParams(ctx)

return &types.QueryParamsResponse{Params: params}, nil
}
Expand All @@ -48,13 +48,13 @@ func (q Querier) RegisteredTokens(

var tokens []types.Token
if len(req.BaseDenom) != 0 {
token, err := q.Keeper.GetTokenSettings(ctx, req.BaseDenom)
token, err := q.GetTokenSettings(ctx, req.BaseDenom)
if err != nil {
return nil, err
}
tokens = append(tokens, token)
} else {
tokens = q.Keeper.GetAllRegisteredTokens(ctx)
tokens = q.GetAllRegisteredTokens(ctx)
}

return &types.QueryRegisteredTokensResponse{
Expand All @@ -74,10 +74,10 @@ func (q Querier) SpecialAssets(
var pairs []types.SpecialAssetPair
if req.Denom == "" {
// all pairs
pairs = q.Keeper.GetAllSpecialAssetPairs(ctx)
pairs = q.GetAllSpecialAssetPairs(ctx)
} else {
// only pairs affecting one asset
pairs = q.Keeper.GetSpecialAssetPairs(ctx, req.Denom)
pairs = q.GetSpecialAssetPairs(ctx, req.Denom)
}

return &types.QuerySpecialAssetsResponse{
Expand All @@ -97,25 +97,24 @@ func (q Querier) MarketSummary(
}

ctx := sdk.UnwrapSDKContext(goCtx)

token, err := q.Keeper.GetTokenSettings(ctx, req.Denom)
token, err := q.GetTokenSettings(ctx, req.Denom)
if err != nil {
return nil, err
}

rate := q.Keeper.DeriveExchangeRate(ctx, req.Denom)
supplyAPY := q.Keeper.DeriveSupplyAPY(ctx, req.Denom)
borrowAPY := q.Keeper.DeriveBorrowAPY(ctx, req.Denom)
rate := q.DeriveExchangeRate(ctx, req.Denom)
supplyAPY := q.DeriveSupplyAPY(ctx, req.Denom)
borrowAPY := q.DeriveBorrowAPY(ctx, req.Denom)

supplied, _ := q.Keeper.GetTotalSupply(ctx, req.Denom)
balance := q.Keeper.ModuleBalance(ctx, req.Denom).Amount
reserved := q.Keeper.GetReserves(ctx, req.Denom).Amount
borrowed := q.Keeper.GetTotalBorrowed(ctx, req.Denom)
liquidity := q.Keeper.AvailableLiquidity(ctx, req.Denom)
supplied, _ := q.GetTotalSupply(ctx, req.Denom)
balance := q.ModuleBalance(ctx, req.Denom).Amount
reserved := q.GetReserves(ctx, req.Denom).Amount
borrowed := q.GetTotalBorrowed(ctx, req.Denom)
liquidity := q.AvailableLiquidity(ctx, req.Denom)

uDenom := coin.ToUTokenDenom(req.Denom)
uSupply := q.Keeper.GetUTokenSupply(ctx, uDenom)
uCollateral := q.Keeper.GetTotalCollateral(ctx, uDenom)
uSupply := q.GetUTokenSupply(ctx, uDenom)
uCollateral := q.GetTotalCollateral(ctx, uDenom)

// maxBorrow is based on MaxSupplyUtilization
maxBorrow := token.MaxSupplyUtilization.MulInt(supplied.Amount).TruncateInt()
Expand All @@ -135,7 +134,7 @@ func (q Querier) MarketSummary(
availableWithdraw = sdk.MaxInt(availableWithdraw, sdk.ZeroInt())

// availableCollateralize respects both MaxCollateralShare and MinCollateralLiquidity
maxCollateral, _ := q.Keeper.maxCollateralFromShare(ctx, uDenom)
maxCollateral, _ := q.maxCollateralFromShare(ctx, uDenom)
if token.MinCollateralLiquidity.IsPositive() {
maxCollateralFromLiquidity := toDec(liquidity).Quo(token.MinCollateralLiquidity).TruncateInt()
maxCollateral = sdk.MinInt(maxCollateral, maxCollateralFromLiquidity)
Expand Down Expand Up @@ -165,13 +164,13 @@ func (q Querier) MarketSummary(

// Oracle price in response will be nil if the oracle module has no price at all, but will instead
// show the most recent price if one existed.
oraclePrice, _, oracleErr := q.Keeper.TokenPrice(ctx, req.Denom, types.PriceModeQuery)
oraclePrice, _, oracleErr := q.TokenPrice(ctx, req.Denom, types.PriceModeQuery)
if oracleErr == nil {
resp.OraclePrice = &oraclePrice
} else {
resp.Errors += oracleErr.Error()
}
historicPrice, _, historicErr := q.Keeper.TokenPrice(ctx, req.Denom, types.PriceModeHistoric)
historicPrice, _, historicErr := q.TokenPrice(ctx, req.Denom, types.PriceModeHistoric)
if historicErr == nil {
resp.OracleHistoricPrice = &historicPrice
} else {
Expand Down Expand Up @@ -199,12 +198,12 @@ func (q Querier) AccountBalances(
return nil, err
}

supplied, err := q.Keeper.GetAllSupplied(ctx, addr)
supplied, err := q.GetAllSupplied(ctx, addr)
if err != nil {
return nil, err
}
collateral := q.Keeper.GetBorrowerCollateral(ctx, addr)
borrowed := q.Keeper.GetBorrowerBorrows(ctx, addr)
collateral := q.GetBorrowerCollateral(ctx, addr)
borrowed := q.GetBorrowerBorrows(ctx, addr)

return &types.QueryAccountBalancesResponse{
Supplied: supplied,
Expand All @@ -231,38 +230,38 @@ func (q Querier) AccountSummary(
return nil, err
}

supplied, err := q.Keeper.GetAllSupplied(ctx, addr)
supplied, err := q.GetAllSupplied(ctx, addr)
if err != nil {
return nil, err
}
collateral := q.Keeper.GetBorrowerCollateral(ctx, addr)
borrowed := q.Keeper.GetBorrowerBorrows(ctx, addr)
collateral := q.GetBorrowerCollateral(ctx, addr)
borrowed := q.GetBorrowerBorrows(ctx, addr)

// the following price calculations use the most recent prices if spot prices are missing
lastSuppliedValue, err := q.Keeper.VisibleTokenValue(ctx, supplied, types.PriceModeQuery)
lastSuppliedValue, err := q.VisibleTokenValue(ctx, supplied, types.PriceModeQuery)
if err != nil {
return nil, err
}
lastBorrowedValue, err := q.Keeper.VisibleTokenValue(ctx, borrowed, types.PriceModeQuery)
lastBorrowedValue, err := q.VisibleTokenValue(ctx, borrowed, types.PriceModeQuery)
if err != nil {
return nil, err
}
lastCollateralValue, err := q.Keeper.VisibleCollateralValue(ctx, collateral, types.PriceModeQuery)
lastCollateralValue, err := q.VisibleCollateralValue(ctx, collateral, types.PriceModeQuery)
if err != nil {
return nil, err
}

// these use leverage-like prices: the lower of spot or historic price for supplied tokens and higher for borrowed.
// unlike transactions, this query will use expired prices instead of skipping them.
suppliedValue, err := q.Keeper.VisibleTokenValue(ctx, supplied, types.PriceModeQueryLow)
suppliedValue, err := q.VisibleTokenValue(ctx, supplied, types.PriceModeQueryLow)
if err != nil {
return nil, err
}
collateralValue, err := q.Keeper.VisibleCollateralValue(ctx, collateral, types.PriceModeQueryLow)
collateralValue, err := q.VisibleCollateralValue(ctx, collateral, types.PriceModeQueryLow)
if err != nil {
return nil, err
}
borrowedValue, err := q.Keeper.VisibleTokenValue(ctx, borrowed, types.PriceModeQueryHigh)
borrowedValue, err := q.VisibleTokenValue(ctx, borrowed, types.PriceModeQueryHigh)
if err != nil {
return nil, err
}
Expand All @@ -281,7 +280,7 @@ func (q Querier) AccountSummary(
// and the higher of spot or historic prices for each borrowed token
// skips collateral tokens with missing prices, but errors on borrow tokens missing prices
// (for oracle errors only the relevant response fields will be left nil)
ap, err := q.Keeper.GetAccountPosition(ctx, addr, false)
ap, err := q.GetAccountPosition(ctx, addr, false)
if nonOracleError(err) {
return nil, err
}
Expand All @@ -294,7 +293,7 @@ func (q Querier) AccountSummary(
// liquidation threshold shown here as it is used in leverage logic: using spot prices.
// skips borrowed tokens with missing prices, but errors on collateral missing prices
// (for oracle errors only the relevant response fields will be left nil)
ap, err = q.Keeper.GetAccountPosition(ctx, addr, true)
ap, err = q.GetAccountPosition(ctx, addr, true)
if nonOracleError(err) {
return nil, err
}
Expand All @@ -315,13 +314,13 @@ func (q Querier) LiquidationTargets(
return nil, status.Error(codes.InvalidArgument, "empty request")
}

if !q.Keeper.liquidatorQueryEnabled {
if !q.liquidatorQueryEnabled {
return nil, types.ErrNotLiquidatorNode
}

ctx := sdk.UnwrapSDKContext(goCtx)

targets, err := q.Keeper.GetEligibleLiquidationTargets(ctx)
targets, err := q.GetEligibleLiquidationTargets(ctx)
if err != nil {
return nil, err
}
Expand All @@ -343,7 +342,7 @@ func (q Querier) BadDebts(
}

ctx := sdk.UnwrapSDKContext(goCtx)
targets := q.Keeper.getAllBadDebts(ctx)
targets := q.getAllBadDebts(ctx)

return &types.QueryBadDebtsResponse{Targets: targets}, nil
}
Expand Down Expand Up @@ -373,7 +372,7 @@ func (q Querier) MaxWithdraw(
denoms = []string{req.Denom}
} else {
// Denom not specified
for _, t := range q.Keeper.GetAllRegisteredTokens(ctx) {
for _, t := range q.GetAllRegisteredTokens(ctx) {
if !t.Blacklist {
denoms = append(denoms, t.BaseDenom)
}
Expand All @@ -386,9 +385,9 @@ func (q Querier) MaxWithdraw(
// will be nil and the resulting value will be what
// can safely be withdrawn even with missing prices.
// On non-nil error here, max withdraw is zero.
uToken, _, err := q.Keeper.userMaxWithdraw(ctx, addr, denom)
uToken, _, err := q.userMaxWithdraw(ctx, addr, denom)
if err == nil && uToken.IsPositive() {
token, err := q.Keeper.ToToken(ctx, uToken)
token, err := q.ToToken(ctx, uToken)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -433,7 +432,7 @@ func (q Querier) MaxBorrow(
denoms = []string{req.Denom}
} else {
// Denom not specified
for _, t := range q.Keeper.GetAllRegisteredTokens(ctx) {
for _, t := range q.GetAllRegisteredTokens(ctx) {
if !t.Blacklist {
denoms = append(denoms, t.BaseDenom)
}
Expand All @@ -446,7 +445,7 @@ func (q Querier) MaxBorrow(
// will be nil and the resulting value will be what
// can safely be borrowed even with missing prices.
// On non-nil error here, max borrow is zero.
maxBorrow, err := q.Keeper.userMaxBorrow(ctx, addr, denom)
maxBorrow, err := q.userMaxBorrow(ctx, addr, denom)
if err == nil && maxBorrow.IsPositive() {
maxTokens = maxTokens.Add(maxBorrow)
}
Expand Down
2 changes: 1 addition & 1 deletion x/metoken/mocks/keepers.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions x/uibc/expected_keepers.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ type BankKeeper interface {

type Leverage interface {
GetTokenSettings(ctx sdk.Context, baseDenom string) (ltypes.Token, error)
GetAllRegisteredTokens(ctx sdk.Context) []ltypes.Token
ToToken(ctx sdk.Context, uToken sdk.Coin) (sdk.Coin, error)
DeriveExchangeRate(ctx sdk.Context, denom string) sdk.Dec
}
Expand Down
14 changes: 14 additions & 0 deletions x/uibc/mocks/keepers.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading