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

fix!: leverage.MaxBorrow return zero instead of failing when there is no more to borrow #1694

Merged
merged 21 commits into from
Jan 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
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
5 changes: 3 additions & 2 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/
### API Breaking

- [1683](https://github.com/umee-network/umee/pull/1683) MaxWithdraw query now returns `sdk.Coins`, not `sdk.Coin` and will be empty (not zero coin) when returning a zero amount. Denom field in query is now optional.
- [1694](https://github.com/umee-network/umee/pull/1694) `MsgMaxWithdraw`, `MsgMaxBorrow` and `MsgRepay` won't return errors if there is nothing to withdraw, borrow or repay respectively. Leverage `ErrMaxWithdrawZero` and `ErrMaxBorrowZero` has been removed.

### Fixes

Expand All @@ -66,9 +67,9 @@ Ref: https://keepachangelog.com/en/1.0.0/
- [1685](https://github.com/umee-network/umee/pull/1685) Add medians param to Token registry.
- [1683](https://github.com/umee-network/umee/pull/1683) Add MaxBorrow query and allow returning all denoms from MaxWithdraw.
- [1690](https://github.com/umee-network/umee/pull/1690) Add MaxBorrow message type.
- [1711](https://github.com/umee-network/umee/pull/1711) Add historic pricing information to leverage MarketSummary query
- [1715](https://github.com/umee-network/umee/pull/1715) Reverted.
- [1711](https://github.com/umee-network/umee/pull/1711) Add historic pricing information to leverage MarketSummary query.
- [1723](https://github.com/umee-network/umee/pull/1723) Compute borrow limits using the lower of either spot or historic price for each collateral token, and the higher of said prices for borrowed tokens. Remove extra spot/historic only fields in account summary.
- [1694](https://github.com/umee-network/umee/pull/1694) Add new sdkutil package to enhance common Cosmos SDK functionality. Here, the `ZeroCoin` helper function.
toteki marked this conversation as resolved.
Show resolved Hide resolved

## [v3.3.0](https://github.com/umee-network/umee/releases/tag/v3.3.0) - 2022-12-20

Expand Down
2 changes: 2 additions & 0 deletions proto/umee/leverage/v1/leverage.proto
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,8 @@ message Token {
// borrow positions under both current and historic prices. The default value of
// zero for this field causes current price to be used in those calculations
// for the affected Token.
// The time span covered by the historic median will be:
// oracle.Params.median_stamp_period * oracle.Params.historic_stamp_period * historic_medians.
uint32 historic_medians = 19 [
(gogoproto.moretags) = "yaml:\"historic_medians\""
];
Expand Down
2 changes: 2 additions & 0 deletions proto/umee/leverage/v1/tx.proto
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ service Msg {

// MaxWithdraw moves previously supplied tokens from the module back to the user balance in
// exchange for burning uTokens. It automatically calculates the maximum valid amount to withdraw.
// Zero is returned if no more tokens can be withdrawn.
rpc MaxWithdraw(MsgMaxWithdraw) returns (MsgMaxWithdrawResponse);

// Collateralize enables selected uTokens as collateral, which moves them to the module.
Expand All @@ -37,6 +38,7 @@ service Msg {
rpc Borrow(MsgBorrow) returns (MsgBorrowResponse);

// MaxBorrow allows a user to borrow the maximum amount of tokens their collateral will allow.
// Zero is returned if no more can be borrowed.
rpc MaxBorrow(MsgMaxBorrow) returns (MsgMaxBorrowResponse);

// Repay allows a user to repay previously borrowed tokens and interest.
Expand Down
9 changes: 9 additions & 0 deletions swagger/swagger.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1016,6 +1016,9 @@ paths:
those calculations

for the affected Token.

The time span covered by the historic median will be:
oracle.Params.median_stamp_period * oracle.Params.historic_stamp_period * historic_medians.
description: >-
Token defines a token, along with its metadata and
parameters, in the Umee
Expand Down Expand Up @@ -2588,6 +2591,9 @@ definitions:
calculations

for the affected Token.

The time span covered by the historic median will be:
oracle.Params.median_stamp_period * oracle.Params.historic_stamp_period * historic_medians.
description: >-
Token defines a token, along with its metadata and parameters, in
the Umee
Expand Down Expand Up @@ -2793,6 +2799,9 @@ definitions:
calculations

for the affected Token.

The time span covered by the historic median will be:
oracle.Params.median_stamp_period * oracle.Params.historic_stamp_period * historic_medians.
description: >-
Token defines a token, along with its metadata and parameters, in the Umee

Expand Down
18 changes: 18 additions & 0 deletions util/sdkutil/coin.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package sdkutil

import (
sdk "github.com/cosmos/cosmos-sdk/types"
)

// ZeroCoin returns new coin with zero amount
func ZeroCoin(denom string) sdk.Coin {
return sdk.NewInt64Coin(denom, 0)
}

// Normalize transform nil coins to empty list
func NormalizeCoins(cs sdk.Coins) sdk.Coins {
if cs == nil {
return sdk.Coins{}
}
return cs
}
3 changes: 3 additions & 0 deletions x/leverage/client/cli/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,9 @@ func GetCmdQueryMaxWithdraw() *cobra.Command {
if len(args) > 1 {
req.Denom = args[1]
}
if err := req.ValidateBasic(); err != nil {
return err
}
resp, err := queryClient.MaxWithdraw(cmd.Context(), req)
return cli.PrintOrErr(resp, err, clientCtx)
},
Expand Down
6 changes: 2 additions & 4 deletions x/leverage/keeper/grpc_query.go
Original file line number Diff line number Diff line change
Expand Up @@ -288,12 +288,10 @@ func (q Querier) MaxWithdraw(
if req == nil {
return nil, status.Error(codes.InvalidArgument, "empty request")
}
if req.Address == "" {
return nil, status.Error(codes.InvalidArgument, "empty address")
if err := req.ValidateBasic(); err != nil {
return nil, err
}

ctx := sdk.UnwrapSDKContext(goCtx)

addr, err := sdk.AccAddressFromBech32(req.Address)
if err != nil {
return nil, err
Expand Down
4 changes: 3 additions & 1 deletion x/leverage/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
paramtypes "github.com/cosmos/cosmos-sdk/x/params/types"
"github.com/tendermint/tendermint/libs/log"

"github.com/umee-network/umee/v4/util/sdkutil"
"github.com/umee-network/umee/v4/x/leverage/types"
)

Expand Down Expand Up @@ -215,7 +216,8 @@ func (k Keeper) Repay(ctx sdk.Context, borrowerAddr sdk.AccAddress, payment sdk.
// determine amount of selected denom currently owed
owed := k.GetBorrow(ctx, borrowerAddr, payment.Denom)
if owed.IsZero() {
return sdk.Coin{}, types.ErrDenomNotBorrowed.Wrap(payment.Denom)
// no need to repay - everything is all right
return sdkutil.ZeroCoin(payment.Denom), nil
}

// prevent overpaying
Expand Down
4 changes: 0 additions & 4 deletions x/leverage/keeper/limits.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,7 @@ import (
// maxWithdraw calculates the maximum amount of uTokens an account can currently withdraw.
// input denom should be a base token.
func (k *Keeper) maxWithdraw(ctx sdk.Context, addr sdk.AccAddress, denom string) (sdk.Coin, error) {
if types.HasUTokenPrefix(denom) {
return sdk.Coin{}, types.ErrUToken
}
uDenom := types.ToUTokenDenom(denom)

toteki marked this conversation as resolved.
Show resolved Hide resolved
availableTokens := sdk.NewCoin(denom, k.AvailableLiquidity(ctx, denom))
availableUTokens, err := k.ExchangeToken(ctx, availableTokens)
if err != nil {
Expand Down
13 changes: 10 additions & 3 deletions x/leverage/keeper/msg_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (

sdk "github.com/cosmos/cosmos-sdk/types"

"github.com/umee-network/umee/v4/util/sdkutil"
"github.com/umee-network/umee/v4/x/leverage/types"
)

Expand Down Expand Up @@ -98,14 +99,21 @@ func (s msgServer) MaxWithdraw(
if err != nil {
return nil, err
}
if types.HasUTokenPrefix(msg.Denom) {
return nil, types.ErrUToken
}
if _, err = s.keeper.GetTokenSettings(ctx, msg.Denom); err != nil {
return nil, err
}

uToken, err := s.keeper.maxWithdraw(ctx, supplierAddr, msg.Denom)
if err != nil {
return nil, err
}

if uToken.IsZero() {
return nil, types.ErrMaxWithdrawZero
zeroCoin := sdkutil.ZeroCoin(msg.Denom)
return &types.MsgMaxWithdrawResponse{Withdrawn: uToken, Received: zeroCoin}, nil
toteki marked this conversation as resolved.
Show resolved Hide resolved
}

received, err := s.keeper.Withdraw(ctx, supplierAddr, uToken)
Expand Down Expand Up @@ -329,7 +337,7 @@ func (s msgServer) MaxBorrow(
return nil, err
}
if maxBorrow.IsZero() {
return nil, types.ErrMaxBorrowZero
return &types.MsgMaxBorrowResponse{Borrowed: sdkutil.ZeroCoin(msg.Denom)}, nil
}

if err := s.keeper.Borrow(ctx, borrowerAddr, maxBorrow); err != nil {
Expand Down Expand Up @@ -371,7 +379,6 @@ func (s msgServer) Repay(
msg *types.MsgRepay,
) (*types.MsgRepayResponse, error) {
ctx := sdk.UnwrapSDKContext(goCtx)

borrowerAddr, err := sdk.AccAddressFromBech32(msg.Borrower)
if err != nil {
return nil, err
Expand Down
Loading