Skip to content

Commit

Permalink
feat: add special asset pairs
Browse files Browse the repository at this point in the history
  • Loading branch information
toteki committed Jul 17, 2023
1 parent 9a68e7f commit 2f1b8bd
Show file tree
Hide file tree
Showing 25 changed files with 2,010 additions and 312 deletions.
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.
string collateral = 1;

// Borrow is the denomination of the borrowed base token.
string borrow = 2;

// 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.
string collateral_weight = 3 [
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
(gogoproto.nullable) = false,
(gogoproto.moretags) = "yaml:\"collateral_weight\""
];
}
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)
returns (QuerySpecialAssetPairsResponse) {
option (google.api.http).get = "/umee/leverage/v1/special_asset_pairs";
}

// 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.
rpc GovUpdateSpecialAssetPairs(MsgGovUpdateSpecialAssetPairs) returns (MsgGovUpdateSpecialAssetPairsResponse);
}

// 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;
// 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,
Short: "Query for all currently registered special asset pairs",
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)
}

// 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
}
}
}

return &types.MsgGovUpdateSpecialAssetPairsResponse{}, nil
}
Loading

0 comments on commit 2f1b8bd

Please sign in to comment.