From fd5c69e61ca9a828fb29bb27c6105c77bee6f0de Mon Sep 17 00:00:00 2001 From: toteki <63419657+toteki@users.noreply.github.com> Date: Thu, 29 Jun 2023 16:28:42 +0100 Subject: [PATCH 1/5] feat: autofill empty denoms in MsgLeveragedLiquidate --- CHANGELOG.md | 1 + x/leverage/keeper/keeper.go | 15 +++++++++++++ x/leverage/keeper/msg_server_test.go | 32 ++++++++++++++++++---------- 3 files changed, 37 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 09c4a518ab..ac77ef645a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -48,6 +48,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ ### Features +- [21XX](https://github.com/umee-network/umee/pull/21XX) Allow `MsgLeveragedLiquidate` to auto-select repay and reward denoms if request fields left blank. - [2114](https://github.com/umee-network/umee/pull/2114) Add borrow factor to `x/leverage` - [2102](https://github.com/umee-network/umee/pull/2102) and [2106](https://github.com/umee-network/umee/pull/2106) Add `MsgLeveragedLiquidate` to `x/leverage` - [2085](https://github.com/umee-network/umee/pull/2085) Add `inspect` query to leverage module, which msut be enabled on a node by running with `-l` liquidator query flag. diff --git a/x/leverage/keeper/keeper.go b/x/leverage/keeper/keeper.go index b11563e5c2..19de4d66fe 100644 --- a/x/leverage/keeper/keeper.go +++ b/x/leverage/keeper/keeper.go @@ -372,6 +372,21 @@ func (k Keeper) Liquidate( func (k Keeper) LeveragedLiquidate( ctx sdk.Context, liquidatorAddr, borrowerAddr sdk.AccAddress, repayDenom, rewardDenom string, ) (repaid sdk.Coin, reward sdk.Coin, err error) { + // If the message did not specify repay or reward denoms, select one arbitrarily (first in + // denom alphabetical order) from borrower position. Then proceed normally with the transaction. + if repayDenom == "" { + borrowed := k.GetBorrowerBorrows(ctx, borrowerAddr) + if !borrowed.IsZero() { + repayDenom = borrowed[0].Denom + } + } + if rewardDenom == "" { + collateral := k.GetBorrowerCollateral(ctx, borrowerAddr) + if !collateral.IsZero() { + rewardDenom = types.ToTokenDenom(collateral[0].Denom) + } + } + if err := k.validateAcceptedDenom(ctx, repayDenom); err != nil { return sdk.Coin{}, sdk.Coin{}, err } diff --git a/x/leverage/keeper/msg_server_test.go b/x/leverage/keeper/msg_server_test.go index 859e73995a..62931a5b46 100644 --- a/x/leverage/keeper/msg_server_test.go +++ b/x/leverage/keeper/msg_server_test.go @@ -2226,11 +2226,11 @@ func (s *IntegrationTestSuite) TestMsgLeveragedLiquidate() { coin.New("u/"+atomDenom, 3_527933), nil, }, { - "close factor < 1", + "close factor < 1 with auto-selected repay and reward denoms", liquidator, closeBorrower, - umeeDenom, - umeeDenom, + "", + "", coin.New(umeeDenom, 8_150541), coin.New("u/"+umeeDenom, 8_965596), nil, @@ -2248,7 +2248,22 @@ func (s *IntegrationTestSuite) TestMsgLeveragedLiquidate() { _, err := srv.LeveragedLiquidate(ctx, msg) require.ErrorIs(err, tc.err, tc.msg) } else { - baseRewardDenom := types.ToTokenDenom(tc.expectedReward.Denom) + // borrower initial state + biBalance := app.BankKeeper.GetAllBalances(ctx, tc.borrower) + biCollateral := app.LeverageKeeper.GetBorrowerCollateral(ctx, tc.borrower) + biBorrowed := app.LeverageKeeper.GetBorrowerBorrows(ctx, tc.borrower) + + // adjust test case in empty-input scenarios, while preserving the msg + if msg.RepayDenom == "" { + if !biBorrowed.IsZero() { + tc.repayDenom = biBorrowed[0].Denom + } + } + if msg.RewardDenom == "" { + if !biCollateral.IsZero() { + tc.rewardDenom = types.ToTokenDenom(biCollateral[0].Denom) + } + } // initial state (borrowed denom) biUTokenSupply := app.LeverageKeeper.GetAllUTokenSupply(ctx) @@ -2256,12 +2271,7 @@ func (s *IntegrationTestSuite) TestMsgLeveragedLiquidate() { // initial state (liquidated denom) liUTokenSupply := app.LeverageKeeper.GetAllUTokenSupply(ctx) - liExchangeRate := app.LeverageKeeper.DeriveExchangeRate(ctx, baseRewardDenom) - - // borrower initial state - biBalance := app.BankKeeper.GetAllBalances(ctx, tc.borrower) - biCollateral := app.LeverageKeeper.GetBorrowerCollateral(ctx, tc.borrower) - biBorrowed := app.LeverageKeeper.GetBorrowerBorrows(ctx, tc.borrower) + liExchangeRate := app.LeverageKeeper.DeriveExchangeRate(ctx, tc.rewardDenom) // liquidator initial state liBalance := app.BankKeeper.GetAllBalances(ctx, tc.liquidator) @@ -2276,7 +2286,7 @@ func (s *IntegrationTestSuite) TestMsgLeveragedLiquidate() { // final state (liquidated denom) lfUTokenSupply := app.LeverageKeeper.GetAllUTokenSupply(ctx) - lfExchangeRate := app.LeverageKeeper.DeriveExchangeRate(ctx, baseRewardDenom) + lfExchangeRate := app.LeverageKeeper.DeriveExchangeRate(ctx, tc.rewardDenom) // borrower final state bfBalance := app.BankKeeper.GetAllBalances(ctx, tc.borrower) From cd48d0424c74e5855cc4925ef4776ac187eff6ba Mon Sep 17 00:00:00 2001 From: toteki <63419657+toteki@users.noreply.github.com> Date: Thu, 29 Jun 2023 16:29:22 +0100 Subject: [PATCH 2/5] cl++ --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ac77ef645a..94ca20625b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -48,7 +48,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ ### Features -- [21XX](https://github.com/umee-network/umee/pull/21XX) Allow `MsgLeveragedLiquidate` to auto-select repay and reward denoms if request fields left blank. +- [2121](https://github.com/umee-network/umee/pull/2121) Allow `MsgLeveragedLiquidate` to auto-select repay and reward denoms if request fields left blank. - [2114](https://github.com/umee-network/umee/pull/2114) Add borrow factor to `x/leverage` - [2102](https://github.com/umee-network/umee/pull/2102) and [2106](https://github.com/umee-network/umee/pull/2106) Add `MsgLeveragedLiquidate` to `x/leverage` - [2085](https://github.com/umee-network/umee/pull/2085) Add `inspect` query to leverage module, which msut be enabled on a node by running with `-l` liquidator query flag. From c29eaf348ef403585378391657b2e59af2b21638 Mon Sep 17 00:00:00 2001 From: toteki <63419657+toteki@users.noreply.github.com> Date: Thu, 29 Jun 2023 22:03:36 +0100 Subject: [PATCH 3/5] update proto comments --- proto/umee/leverage/v1/tx.proto | 4 +++- x/leverage/types/tx.pb.go | 8 ++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/proto/umee/leverage/v1/tx.proto b/proto/umee/leverage/v1/tx.proto index a4e62a0dfd..2019ee8a57 100644 --- a/proto/umee/leverage/v1/tx.proto +++ b/proto/umee/leverage/v1/tx.proto @@ -55,7 +55,9 @@ service Msg { // this initial borrow to exceed the liquidator's borrow limit as long as it is healthy by the end // of the transaction. Repay amount is calculated automatically, so the liquidator only specifies // repay and reward token denoms. For safety, the liquidator cannot exceed 80% of their borrow limit when - // executing this transaction, instead of the regular 100%. + // executing this transaction, instead of the regular 100%. Also allows repayment and reward denoms to + // be left blank - if not specified, the module will automatically select the first (alphabetically by denom) + // borrow and/or collateral on the target account and the proceed normally. rpc LeveragedLiquidate(MsgLeveragedLiquidate) returns (MsgLeveragedLiquidateResponse); // SupplyCollateral combines the Supply and Collateralize actions. diff --git a/x/leverage/types/tx.pb.go b/x/leverage/types/tx.pb.go index 962699b6f2..2cb9394199 100644 --- a/x/leverage/types/tx.pb.go +++ b/x/leverage/types/tx.pb.go @@ -1303,7 +1303,9 @@ type MsgClient interface { // this initial borrow to exceed the liquidator's borrow limit as long as it is healthy by the end // of the transaction. Repay amount is calculated automatically, so the liquidator only specifies // repay and reward token denoms. For safety, the liquidator cannot exceed 80% of their borrow limit when - // executing this transaction, instead of the regular 100%. + // executing this transaction, instead of the regular 100%. Also allows repayment and reward denoms to + // be left blank - if not specified, the module will automatically select the first (alphabetically by denom) + // borrow and/or collateral on the target account and the proceed normally. LeveragedLiquidate(ctx context.Context, in *MsgLeveragedLiquidate, opts ...grpc.CallOption) (*MsgLeveragedLiquidateResponse, error) // SupplyCollateral combines the Supply and Collateralize actions. SupplyCollateral(ctx context.Context, in *MsgSupplyCollateral, opts ...grpc.CallOption) (*MsgSupplyCollateralResponse, error) @@ -1462,7 +1464,9 @@ type MsgServer interface { // this initial borrow to exceed the liquidator's borrow limit as long as it is healthy by the end // of the transaction. Repay amount is calculated automatically, so the liquidator only specifies // repay and reward token denoms. For safety, the liquidator cannot exceed 80% of their borrow limit when - // executing this transaction, instead of the regular 100%. + // executing this transaction, instead of the regular 100%. Also allows repayment and reward denoms to + // be left blank - if not specified, the module will automatically select the first (alphabetically by denom) + // borrow and/or collateral on the target account and the proceed normally. LeveragedLiquidate(context.Context, *MsgLeveragedLiquidate) (*MsgLeveragedLiquidateResponse, error) // SupplyCollateral combines the Supply and Collateralize actions. SupplyCollateral(context.Context, *MsgSupplyCollateral) (*MsgSupplyCollateralResponse, error) From 7f05dc7bb14d959fd3cb91e56ff2bc3405f78330 Mon Sep 17 00:00:00 2001 From: toteki <63419657+toteki@users.noreply.github.com> Date: Thu, 29 Jun 2023 22:05:00 +0100 Subject: [PATCH 4/5] update CLI --- x/leverage/client/cli/tx.go | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/x/leverage/client/cli/tx.go b/x/leverage/client/cli/tx.go index 4eeb43767a..12c2acb0ee 100644 --- a/x/leverage/client/cli/tx.go +++ b/x/leverage/client/cli/tx.go @@ -322,7 +322,7 @@ $ umeed tx leverage liquidate %s 50000000uumee u/uumee --from mykey`, func GetCmdLeveragedLiquidate() *cobra.Command { cmd := &cobra.Command{ Use: "lev-liquidate [borrower] [repay-denom] [reward-denom]", - Args: cobra.ExactArgs(3), + Args: cobra.RangeArgs(1, 3), Short: "Liquidates by moving borrower debt to the liquidator and immediately collateralizes the reward.", Long: strings.TrimSpace( fmt.Sprintf(` @@ -349,8 +349,14 @@ $ umeed tx leverage lev-liquidate %s uumee uumee --from mykey`, return err } - repayDenom := args[1] - rewardDenom := args[2] + var repayDenom, rewardDenom string + if len(args) > 1 { + repayDenom = args[1] + } + + if len(args) > 1 { + rewardDenom = args[2] + } msg := types.NewMsgLeveragedLiquidate(clientCtx.GetFromAddress(), borrowerAddr, repayDenom, rewardDenom) if err = msg.ValidateBasic(); err != nil { From 2c1880d3232f4638942b513a2fe6abf03b7b3c25 Mon Sep 17 00:00:00 2001 From: Adam Moser <63419657+toteki@users.noreply.github.com> Date: Fri, 30 Jun 2023 01:55:21 +0100 Subject: [PATCH 5/5] Update x/leverage/client/cli/tx.go --- x/leverage/client/cli/tx.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/leverage/client/cli/tx.go b/x/leverage/client/cli/tx.go index 12c2acb0ee..d7f6c372a3 100644 --- a/x/leverage/client/cli/tx.go +++ b/x/leverage/client/cli/tx.go @@ -354,7 +354,7 @@ $ umeed tx leverage lev-liquidate %s uumee uumee --from mykey`, repayDenom = args[1] } - if len(args) > 1 { + if len(args) > 2 { rewardDenom = args[2] }