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 special asset pairs #2150

Merged
merged 47 commits into from
Aug 1, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
2f1b8bd
feat: add special asset pairs
toteki Jul 17, 2023
cb484f9
Update proto/umee/leverage/v1/leverage.proto
toteki Jul 17, 2023
02b5edf
Merge branch 'main' into adam/special
toteki Jul 18, 2023
07acee1
Merge branch 'main' into adam/special
toteki Jul 20, 2023
9f0f9fe
Merge branch 'main' into adam/special
toteki Jul 21, 2023
286fa0e
line length lint
toteki Jul 21, 2023
e05b997
Merge branch 'main' into adam/special
toteki Jul 21, 2023
5eb3d88
Merge branch 'main' into adam/special
toteki Jul 21, 2023
ea72c67
Update x/leverage/keeper/token.go
toteki Jul 21, 2023
545ee88
Update x/leverage/keeper/token.go
toteki Jul 21, 2023
b3270a8
Update proto/umee/leverage/v1/leverage.proto
toteki Jul 21, 2023
d1819fa
Update proto/umee/leverage/v1/leverage.proto
toteki Jul 21, 2023
73c4b30
Merge branch 'main' into adam/special
toteki Jul 21, 2023
5b7b02d
make proto-all
toteki Jul 21, 2023
55f8153
make proto-all
toteki Jul 21, 2023
97efc7f
fix
toteki Jul 21, 2023
48a9900
Merge branch 'main' into adam/special
toteki Jul 25, 2023
c9c0cdb
remove title + description
toteki Jul 25, 2023
5817edd
group legacy msg interface
toteki Jul 25, 2023
153037e
proposal.go
toteki Jul 25, 2023
c3d39b2
legacy++
toteki Jul 25, 2023
9a22f72
special asset sets in gov message
toteki Jul 26, 2023
11ffd99
pair deletion logic
toteki Jul 26, 2023
5e08485
can query for specific asset
toteki Jul 26, 2023
004a5d5
Update proto/umee/leverage/v1/tx.proto
toteki Jul 26, 2023
0c3440d
make proto-all
toteki Jul 26, 2023
f8cb27f
changelog
toteki Jul 26, 2023
19d5a06
Merge branch 'main' into adam/special
toteki Jul 27, 2023
206c769
lint
toteki Jul 27, 2023
b9b522c
Update proto/umee/leverage/v1/tx.proto
toteki Jul 28, 2023
0075b58
Update proto/umee/leverage/v1/tx.proto
toteki Jul 28, 2023
53b7e4f
proto changes
toteki Jul 28, 2023
7944aae
collateral weight zero deletes sets ad pairs
toteki Jul 28, 2023
fcda085
fix CLI
toteki Jul 28, 2023
ef36cda
test++
toteki Jul 28, 2023
0e46e1a
combine validate functions in genesis
toteki Jul 28, 2023
6f75ab6
Merge branch 'main' into adam/special
toteki Jul 28, 2023
daa5e0a
fix
toteki Jul 28, 2023
f83ab08
fix
toteki Jul 28, 2023
78cd2e7
proto changes
toteki Jul 30, 2023
e48b35c
fix names
toteki Jul 30, 2023
8804ed4
fix names
toteki Jul 30, 2023
31402c5
validation allows empty pairs if sets present instead
toteki Jul 30, 2023
03dcd74
optional arg doc
toteki Jul 30, 2023
cbd2178
Add liquidation threshold to pairs
toteki Jul 30, 2023
39a9994
revert proposal.go
toteki Jul 30, 2023
5e2e948
change stringer
toteki Jul 30, 2023
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 proto/umee/leverage/v1/genesis.proto
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ message GenesisState {
(gogoproto.nullable) = false,
(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"
];
repeated SpecialAssetPair special_pairs = 10 [(gogoproto.nullable) = false];
}

// AdjustedBorrow is a borrow struct used in the leverage module's genesis
Expand Down
22 changes: 22 additions & 0 deletions proto/umee/leverage/v1/leverage.proto
Original file line number Diff line number Diff line change
Expand Up @@ -249,3 +249,25 @@ message Token {
(gogoproto.moretags) = "yaml:\"historic_medians\""
];
}

// SpecialAssetPair defines a special (increased) CollateralWeight used when a specified Collateral is used
// to collateralize a specified Borrow. This association is one-way (so it does not work in reverse).
message SpecialAssetPair {
option (gogoproto.equal) = true;

// Collateral is the denomination of the collateral base token.
toteki marked this conversation as resolved.
Show resolved Hide resolved
string collateral = 1;

// Borrow is the denomination of the borrowed base token.
toteki marked this conversation as resolved.
Show resolved Hide resolved
string borrow = 2;
toteki marked this conversation as resolved.
Show resolved Hide resolved

// Collateral Weight defines what portion of the total value of the asset
// can contribute to a users borrowing power. For special asset pairs, this
// also overrides the borrowed asset's collateral weight when eveluating borrow
// factor.
toteki marked this conversation as resolved.
Show resolved Hide resolved
string collateral_weight = 3 [
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
(gogoproto.nullable) = false,
(gogoproto.moretags) = "yaml:\"collateral_weight\""
toteki marked this conversation as resolved.
Show resolved Hide resolved
];
}
17 changes: 17 additions & 0 deletions proto/umee/leverage/v1/query.proto
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@ service Query {
option (google.api.http).get = "/umee/leverage/v1/registered_tokens";
}

// SpecialAssetPairs queries for all special asset pairs.
rpc SpecialAssetPairs(QuerySpecialAssetPairs)
toteki marked this conversation as resolved.
Show resolved Hide resolved
returns (QuerySpecialAssetPairsResponse) {
option (google.api.http).get = "/umee/leverage/v1/special_asset_pairs";
toteki marked this conversation as resolved.
Show resolved Hide resolved
toteki marked this conversation as resolved.
Show resolved Hide resolved
}

// MarketSummary queries a base asset's current borrowing and supplying conditions.
rpc MarketSummary(QueryMarketSummary)
returns (QueryMarketSummaryResponse) {
Expand Down Expand Up @@ -100,6 +106,17 @@ message QueryRegisteredTokensResponse {
repeated Token registry = 1 [(gogoproto.nullable) = false];
}

// QuerySpecialAssetPairs defines the request structure for the SpecialAssetPairs
// gRPC service handler.
message QuerySpecialAssetPairs {
}

// QuerySpecialAssetPairsResponse defines the response structure for the
// SpecialAssetPairs gRPC service handler.
message QuerySpecialAssetPairsResponse {
repeated SpecialAssetPair pairs = 1 [(gogoproto.nullable) = false];
}

// QueryMarketSummary defines the request structure for the MarketSummary gRPC service handler.
message QueryMarketSummary {
string denom = 1;
Expand Down
24 changes: 24 additions & 0 deletions proto/umee/leverage/v1/tx.proto
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,11 @@ service Msg {
// GovUpdateRegistry adds new tokens to the token registry or
// updates existing tokens with new settings.
rpc GovUpdateRegistry(MsgGovUpdateRegistry) returns (MsgGovUpdateRegistryResponse);

// GovUpdateSpecialAssetPairs adds, updates, or removes special asset pairs. Note that a special asset
// pair can be removed by setting its special collateral weight to the collateral weight of the base
// asset.
toteki marked this conversation as resolved.
Show resolved Hide resolved
rpc GovUpdateSpecialAssetPairs(MsgGovUpdateSpecialAssetPairs) returns (MsgGovUpdateSpecialAssetPairsResponse);
toteki marked this conversation as resolved.
Show resolved Hide resolved
}

// MsgSupply represents a user's request to supply assets to the module.
Expand Down Expand Up @@ -264,3 +269,22 @@ message MsgGovUpdateRegistry {

// MsgGovUpdateRegistryResponse defines the Msg/GovUpdateRegistry response type.
message MsgGovUpdateRegistryResponse {}

// MsgGovUpdateSpecialAssetPairs defines the Msg/GovUpdateSpecialAssetPairs request type.
message MsgGovUpdateSpecialAssetPairs {
option (gogoproto.equal) = true;
option (gogoproto.goproto_getters) = false;
option (gogoproto.goproto_stringer) = false;
option (cosmos.msg.v1.signer) = "authority";

// authority is the address of the governance account.
string authority = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"];
string title = 2;
string description = 3;
toteki marked this conversation as resolved.
Show resolved Hide resolved
// pairs are new or updated special asset pairs. Updating a special asset pair's
// collateral weight to match that of its base asset deletes it indead.
repeated SpecialAssetPair pairs = 4 [(gogoproto.nullable) = false];
}

// MsgGovUpdateSpecialAssetPairsResponse defines the Msg/GovUpdateSpecialAssetPairs response type.
message MsgGovUpdateSpecialAssetPairsResponse {}
134 changes: 134 additions & 0 deletions swagger/swagger.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1281,6 +1281,77 @@ paths:
type: string
tags:
- Query
/umee/leverage/v1/special_asset_pairs:
get:
summary: SpecialAssetPairs queries for all special asset pairs.
operationId: SpecialAssetPairs
responses:
'200':
description: A successful response.
schema:
type: object
properties:
pairs:
type: array
items:
type: object
properties:
collateral:
type: string
description: >-
Collateral is the denomination of the collateral base
token.
borrow:
type: string
description: Borrow is the denomination of the borrowed base token.
collateral_weight:
type: string
description: >-
Collateral Weight defines what portion of the total
value of the asset

can contribute to a users borrowing power. For special
asset pairs, this

also overrides the borrowed asset's collateral weight
when eveluating borrow

factor.
description: >-
SpecialAssetPair defines a special (increased)
CollateralWeight used when a specified Collateral is used

to collateralize a specified Borrow. This association is
one-way (so it does not work in reverse).
description: >-
QuerySpecialAssetPairsResponse defines the response structure for
the

SpecialAssetPairs gRPC service handler.
default:
description: An unexpected error response.
schema:
type: object
properties:
error:
type: string
code:
type: integer
format: int32
message:
type: string
details:
type: array
items:
type: object
properties:
type_url:
type: string
value:
type: string
format: byte
tags:
- Query
/umee/historacle/v1/avg_price/{denom}:
get:
summary: QueryAvgPrice returns avg price of a given denom (required).
Expand Down Expand Up @@ -4484,6 +4555,42 @@ definitions:
description: |-
QueryRegisteredTokensResponse defines the response structure for the
RegisteredTokens gRPC service handler.
umee.leverage.v1.QuerySpecialAssetPairsResponse:
type: object
properties:
pairs:
type: array
items:
type: object
properties:
collateral:
type: string
description: Collateral is the denomination of the collateral base token.
borrow:
type: string
description: Borrow is the denomination of the borrowed base token.
collateral_weight:
type: string
description: >-
Collateral Weight defines what portion of the total value of the
asset

can contribute to a users borrowing power. For special asset
pairs, this

also overrides the borrowed asset's collateral weight when
eveluating borrow

factor.
description: >-
SpecialAssetPair defines a special (increased) CollateralWeight used
when a specified Collateral is used

to collateralize a specified Borrow. This association is one-way (so
it does not work in reverse).
description: |-
QuerySpecialAssetPairsResponse defines the response structure for the
SpecialAssetPairs gRPC service handler.
umee.leverage.v1.RiskInfo:
type: object
properties:
Expand All @@ -4502,6 +4609,33 @@ definitions:
description: >-
RiskInfo defines a borrower's account health without requiring sdk.Dec
formatting.
umee.leverage.v1.SpecialAssetPair:
type: object
properties:
collateral:
type: string
description: Collateral is the denomination of the collateral base token.
borrow:
type: string
description: Borrow is the denomination of the borrowed base token.
collateral_weight:
type: string
description: >-
Collateral Weight defines what portion of the total value of the asset

can contribute to a users borrowing power. For special asset pairs,
this

also overrides the borrowed asset's collateral weight when eveluating
borrow

factor.
description: >-
SpecialAssetPair defines a special (increased) CollateralWeight used when
a specified Collateral is used

to collateralize a specified Borrow. This association is one-way (so it
does not work in reverse).
umee.leverage.v1.Token:
type: object
properties:
Expand Down
26 changes: 26 additions & 0 deletions x/leverage/client/cli/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ func GetQueryCmd() *cobra.Command {
cmd.AddCommand(
GetCmdQueryParams(),
GetCmdQueryRegisteredTokens(),
GetCmdQuerySpecialAssetPairs(),
GetCmdQueryMarketSummary(),
GetCmdQueryAccountBalances(),
GetCmdQueryAccountSummary(),
Expand Down Expand Up @@ -95,6 +96,31 @@ func GetCmdQueryRegisteredTokens() *cobra.Command {
return cmd
}

// GetCmdQuerySpecialAssetPairs creates a Cobra command to query for all
// the special asset pairs in the x/leverage module.
func GetCmdQuerySpecialAssetPairs() *cobra.Command {
cmd := &cobra.Command{
Use: "special-pairs",
Args: cobra.NoArgs,
toteki marked this conversation as resolved.
Show resolved Hide resolved
Short: "Query for all currently registered special asset pairs",
toteki marked this conversation as resolved.
Show resolved Hide resolved
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx, err := client.GetClientQueryContext(cmd)
if err != nil {
return err
}

queryClient := types.NewQueryClient(clientCtx)
req := &types.QuerySpecialAssetPairs{}
resp, err := queryClient.SpecialAssetPairs(cmd.Context(), req)
return cli.PrintOrErr(resp, err, clientCtx)
},
}

flags.AddQueryFlagsToCmd(cmd)

return cmd
}

// GetCmdQueryMarketSummary creates a Cobra command to query for the
// Market Summary of a specific token.
func GetCmdQueryMarketSummary() *cobra.Command {
Expand Down
10 changes: 10 additions & 0 deletions x/leverage/client/tests/tests.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,16 @@ func (s *IntegrationTests) TestLeverageScenario() {
},
ErrMsg: "",
},
{
Name: "query special asset pairs",
Command: cli.GetCmdQuerySpecialAssetPairs(),
Args: []string{},
Response: &types.QuerySpecialAssetPairsResponse{},
ExpectedResponse: &types.QuerySpecialAssetPairsResponse{
Pairs: []types.SpecialAssetPair{},
},
ErrMsg: "",
},
{
Name: "query registered token info by base_denom",
Command: cli.GetCmdQueryRegisteredTokens(),
Expand Down
5 changes: 5 additions & 0 deletions x/leverage/keeper/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ func (k Keeper) InitGenesis(ctx sdk.Context, genState types.GenesisState) {
for _, rate := range genState.InterestScalars {
util.Panic(k.setInterestScalar(ctx, rate.Denom, rate.Scalar))
}

for _, pair := range genState.SpecialPairs {
util.Panic(k.SetSpecialAssetPair(ctx, pair))
}
}

// ExportGenesis returns the x/leverage module's exported genesis state.
Expand All @@ -57,6 +61,7 @@ func (k Keeper) ExportGenesis(ctx sdk.Context) *types.GenesisState {
k.getAllBadDebts(ctx),
k.getAllInterestScalars(ctx),
k.GetAllUTokenSupply(ctx),
k.GetAllSpecialAssetPairs(ctx),
)
}

Expand Down
16 changes: 16 additions & 0 deletions x/leverage/keeper/grpc_query.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,22 @@ func (q Querier) RegisteredTokens(
}, nil
}

func (q Querier) SpecialAssetPairs(
goCtx context.Context,
req *types.QuerySpecialAssetPairs,
) (*types.QuerySpecialAssetPairsResponse, error) {
if req == nil {
return nil, status.Error(codes.InvalidArgument, "empty request")
}

ctx := sdk.UnwrapSDKContext(goCtx)
pairs := q.Keeper.GetAllSpecialAssetPairs(ctx)

return &types.QuerySpecialAssetPairsResponse{
Pairs: pairs,
}, nil
}

func (q Querier) MarketSummary(
goCtx context.Context,
req *types.QueryMarketSummary,
Expand Down
6 changes: 6 additions & 0 deletions x/leverage/keeper/iter.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,12 @@ func (k Keeper) GetAllRegisteredTokens(ctx sdk.Context) []types.Token {
return store.MustLoadAll[*types.Token](ctx.KVStore(k.storeKey), types.KeyPrefixRegisteredToken)
}

// GetAllSpecialAssetPairs returns all the special asset pairs from the x/leverage
// module's KVStore.
func (k Keeper) GetAllSpecialAssetPairs(ctx sdk.Context) []types.SpecialAssetPair {
return store.MustLoadAll[*types.SpecialAssetPair](ctx.KVStore(k.storeKey), types.KeyPrefixSpecialAssetPair)
}
toteki marked this conversation as resolved.
Show resolved Hide resolved

// GetBorrowerBorrows returns an sdk.Coins object containing all open borrows
// associated with an address.
func (k Keeper) GetBorrowerBorrows(ctx sdk.Context, borrowerAddr sdk.AccAddress) sdk.Coins {
Expand Down
27 changes: 27 additions & 0 deletions x/leverage/keeper/msg_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -569,3 +569,30 @@ func (s msgServer) GovUpdateRegistry(

return &types.MsgGovUpdateRegistryResponse{}, nil
}

// GovUpdateSpecialAssetPairs adds, updates, or deletes special asset pairs.
func (s msgServer) GovUpdateSpecialAssetPairs(
goCtx context.Context,
msg *types.MsgGovUpdateSpecialAssetPairs,
) (*types.MsgGovUpdateSpecialAssetPairsResponse, error) {
ctx := sdk.UnwrapSDKContext(goCtx)

for _, pair := range msg.Pairs {
token, err := s.keeper.GetTokenSettings(ctx, pair.Collateral)
if err != nil {
return nil, err
}

if pair.CollateralWeight.Equal(token.CollateralWeight) {
// setting a special collateral weight equal to regular collateral weight deletes
// the special pair instead, since no special weight is needed in that case
s.keeper.DeleteSpecialAssetPair(ctx, pair.Collateral, pair.Borrow)
} else {
if err := s.keeper.SetSpecialAssetPair(ctx, pair); err != nil {
return nil, err
}
}
}
toteki marked this conversation as resolved.
Show resolved Hide resolved

return &types.MsgGovUpdateSpecialAssetPairsResponse{}, nil
}
Loading