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

refactor: remove client interface for liquidate msg #1164

Merged
merged 2 commits into from
Feb 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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 CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Improvements

* [#1164](https://github.com/NibiruChain/nibiru/pull/1164) - refactor: remove client interface for liquidate msg
* [#1156](https://github.com/NibiruChain/nibiru/pull/1156) - refactor: remove lockup & incentivation module
* [#1134](https://github.com/NibiruChain/nibiru/pull/1134) - refactor: remove panics from vpool and spillovers from the perp module. It's now impossible to call functions in x/perp that would panic in vpool.
* [#1127](https://github.com/NibiruChain/nibiru/pull/1127) - refactor: remove unnecessary panics from x/dex and x/stablecoin
Expand Down
20 changes: 0 additions & 20 deletions proto/perp/v1/tx.proto
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,6 @@ service Msg {
option (google.api.http).post = "/nibiru/perp/add_margin";
}

/* Liquidate is a transaction that allows the caller to fully or partially
liquidate an existing position. */
rpc Liquidate(MsgLiquidate) returns (MsgLiquidateResponse) {
option (google.api.http).post = "/nibiru/perp/liquidate";
}

rpc MultiLiquidate(MsgMultiLiquidate) returns (MsgMultiLiquidateResponse) {
option (google.api.http).post = "/nibiru/perp/multiliquidate";
}
Expand Down Expand Up @@ -94,20 +88,6 @@ message MsgAddMarginResponse {

// -------------------------- Liquidate --------------------------

message MsgLiquidate {
// Sender is the liquidator address
string sender = 1;

// TokenPair is the identifier for the position's virtual pool
string pair = 2 [
(gogoproto.customtype) = "github.com/NibiruChain/nibiru/x/common.AssetPair",
(gogoproto.nullable) = false
];

// Trader is the address of the owner of the position
string trader = 3;
}

message MsgLiquidateResponse {
cosmos.base.v1beta1.Coin fee_to_liquidator = 1 [(gogoproto.nullable) = false];
cosmos.base.v1beta1.Coin fee_to_perp_ecosystem_fund = 2 [(gogoproto.nullable) = false];
Expand Down
52 changes: 0 additions & 52 deletions x/perp/client/cli/cli_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -436,58 +436,6 @@ func (s *IntegrationTestSuite) TestX_AddMargin() {
}
}

func (s *IntegrationTestSuite) TestLiquidate() {
s.T().Log("liquidate a position that does not exist")
_, err := testutilcli.ExecTx(s.network, cli.LiquidateCmd(), s.users[4], []string{
asset.Registry.Pair(denoms.ETH, denoms.NUSD).String(),
s.users[1].String(),
})
s.Contains(err.Error(), collections.ErrNotFound.Error())

s.T().Log("opening a position with user 1....")
txResp, err := testutilcli.ExecTx(s.network, cli.OpenPositionCmd(), s.users[1], []string{
"buy",
asset.Registry.Pair(denoms.ETH, denoms.NUSD).String(),
"15", // Leverage
"90000", // Quote asset amount
"0",
})
s.NoError(err)
s.EqualValues(abcitypes.CodeTypeOK, txResp.Code)

s.T().Log("liquidate a position that is above maintenance margin mario")
_, err = testutilcli.ExecTx(s.network, cli.LiquidateCmd(), s.users[4], []string{
asset.Registry.Pair(denoms.ETH, denoms.NUSD).String(),
s.users[1].String(),
})
s.Contains(err.Error(), "margin ratio is too healthy to liquidate")

s.T().Log("opening a position with user 2...")
txResp, err = testutilcli.ExecTx(s.network, cli.OpenPositionCmd(), s.users[2], []string{
"sell",
asset.Registry.Pair(denoms.ETH, denoms.NUSD).String(),
"15", // Leverage
"45000000", // Quote asset amount
"0",
})
s.NoError(err)
s.EqualValues(abcitypes.CodeTypeOK, txResp.Code)

s.T().Log("wait 10 blocks")
height, err := s.network.LatestHeight()
s.NoError(err)
_, err = s.network.WaitForHeight(height + 10)
s.NoError(err)

s.T().Log("liquidating user 1...")
txResp, err = testutilcli.ExecTx(s.network, cli.LiquidateCmd(), s.users[4], []string{
asset.Registry.Pair(denoms.ETH, denoms.NUSD).String(),
s.users[1].String(),
})
s.NoError(err)
s.EqualValues(abcitypes.CodeTypeOK, txResp.Code)
}

func (s *IntegrationTestSuite) TestDonateToEcosystemFund() {
s.T().Logf("donate to ecosystem fund")
out, err := testutilcli.ExecTx(s.network, cli.DonateToEcosystemFundCmd(), sdk.MustAccAddressFromBech32("nibi1w89pf5yq8ntjg89048qmtaz929fdxup0a57d8m"), []string{"100unusd"})
Expand Down
45 changes: 0 additions & 45 deletions x/perp/client/cli/tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ func GetTxCmd() *cobra.Command {
txCmd.AddCommand(
RemoveMarginCmd(),
AddMarginCmd(),
LiquidateCmd(),
OpenPositionCmd(),
ClosePositionCmd(),
DonateToEcosystemFundCmd(),
Expand Down Expand Up @@ -219,50 +218,6 @@ func AddMarginCmd() *cobra.Command {
return cmd
}

func LiquidateCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "liquidate [vpool] [trader]",
Short: "liquidates the position of 'trader' on 'vpool' if possible",
Long: strings.TrimSpace(
fmt.Sprintf(`
$ %s tx perp liquidate osmo:nusd nibi1zaavvzxez0elundtn32qnk9lkm8kmcsz44g7xl
`, version.AppName),
),
Args: cobra.ExactArgs(2),
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx, err := client.GetClientTxContext(cmd)
if err != nil {
return err
}

traderAddr, err := sdk.AccAddressFromBech32(args[1])
if err != nil {
return err
}

pair, err := common.TryNewAssetPair(args[0])
if err != nil {
return err
}

msg := &types.MsgLiquidate{
Sender: clientCtx.GetFromAddress().String(),
Pair: pair,
Trader: traderAddr.String(),
}
if err = msg.ValidateBasic(); err != nil {
return err
}

return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg)
},
}

flags.AddTxFlagsToCmd(cmd)

return cmd
}

func DonateToEcosystemFundCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "donate-ef [amount]",
Expand Down
3 changes: 0 additions & 3 deletions x/perp/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,6 @@ func NewHandler(k keeper.Keeper) sdk.Handler {
case *types.MsgOpenPosition:
res, err := msgServer.OpenPosition(sdk.WrapSDKContext(ctx), msg)
return sdk.WrapServiceResult(ctx, res, err)
case *types.MsgLiquidate:
res, err := msgServer.Liquidate(sdk.WrapSDKContext(ctx), msg)
return sdk.WrapServiceResult(ctx, res, err)
case *types.MsgClosePosition:
res, err := msgServer.ClosePosition(sdk.WrapSDKContext(ctx), msg)
return sdk.WrapServiceResult(ctx, res, err)
Expand Down
19 changes: 0 additions & 19 deletions x/perp/keeper/msg_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,25 +91,6 @@ func (m msgServer) ClosePosition(goCtx context.Context, position *types.MsgClose
}, nil
}

func (m msgServer) Liquidate(goCtx context.Context, msg *types.MsgLiquidate,
) (*types.MsgLiquidateResponse, error) {
ctx := sdk.UnwrapSDKContext(goCtx)

liquidatorAddr := sdk.MustAccAddressFromBech32(msg.Sender)

traderAddr := sdk.MustAccAddressFromBech32(msg.Trader)

feeToLiquidator, feeToFund, err := m.k.Liquidate(ctx, liquidatorAddr, msg.Pair, traderAddr)
if err != nil {
return nil, err
}

return &types.MsgLiquidateResponse{
FeeToLiquidator: feeToLiquidator,
FeeToPerpEcosystemFund: feeToFund,
}, nil
}

func (m msgServer) MultiLiquidate(goCtx context.Context, req *types.MsgMultiLiquidate) (*types.MsgMultiLiquidateResponse, error) {
positions := make([]MultiLiquidationRequest, len(req.Liquidations))
for i, pos := range req.Liquidations {
Expand Down
82 changes: 0 additions & 82 deletions x/perp/keeper/msg_server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -424,88 +424,6 @@ func TestMsgServerClosePosition(t *testing.T) {
}
}

func TestMsgServerLiquidate(t *testing.T) {
tests := []struct {
name string

pair common.AssetPair
liquidator string
trader string

expectedErr error
}{
{
name: "success",
pair: asset.Registry.Pair(denoms.BTC, denoms.NUSD),
liquidator: testutil.AccAddress().String(),
trader: testutil.AccAddress().String(),
expectedErr: nil,
},
}

for _, tc := range tests {
tc := tc
t.Run(tc.name, func(t *testing.T) {
app, ctx := nibisimapp.NewTestNibiruAppAndContext(true)
ctx = ctx.WithBlockTime(time.Now())
setLiquidator(ctx, app.PerpKeeper, tc.liquidator)
msgServer := keeper.NewMsgServerImpl(app.PerpKeeper)

t.Log("create vpool")
assert.NoError(t, app.VpoolKeeper.CreatePool(
/* ctx */ ctx,
/* pair */ asset.Registry.Pair(denoms.BTC, denoms.NUSD),
/* quoteAssetReserve */ sdk.NewDec(1*common.Precision),
/* baseAssetReserve */ sdk.NewDec(1*common.Precision),
vpooltypes.VpoolConfig{
TradeLimitRatio: sdk.OneDec(),
FluctuationLimitRatio: sdk.OneDec(),
MaxOracleSpreadRatio: sdk.OneDec(),
MaintenanceMarginRatio: sdk.MustNewDecFromStr("0.0625"),
MaxLeverage: sdk.MustNewDecFromStr("15"),
},
))
setPairMetadata(app.PerpKeeper, ctx, types.PairMetadata{
Pair: asset.Registry.Pair(denoms.BTC, denoms.NUSD),
LatestCumulativePremiumFraction: sdk.ZeroDec(),
})
ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 1).WithBlockTime(time.Now().Add(time.Minute))

traderAddr, err := sdk.AccAddressFromBech32(tc.trader)
if err == nil {
t.Log("set oracle price")
app.OracleKeeper.SetPrice(ctx, asset.Registry.Pair(denoms.BTC, denoms.NUSD), sdk.OneDec())

t.Log("create position")
setPosition(app.PerpKeeper, ctx, types.Position{
TraderAddress: traderAddr.String(),
Pair: tc.pair,
Size_: sdk.OneDec(),
Margin: sdk.OneDec(),
OpenNotional: sdk.NewDec(2), // new spot price is 1, so position can be liquidated
LatestCumulativePremiumFraction: sdk.ZeroDec(),
BlockNumber: 1,
})
require.NoError(t, simapp.FundModuleAccount(app.BankKeeper, ctx, types.VaultModuleAccount, sdk.NewCoins(sdk.NewInt64Coin(tc.pair.QuoteDenom(), 1))))
}

resp, err := msgServer.Liquidate(sdk.WrapSDKContext(ctx), &types.MsgLiquidate{
Sender: tc.liquidator,
Pair: tc.pair,
Trader: tc.trader,
})

if tc.expectedErr != nil {
require.ErrorContains(t, err, tc.expectedErr.Error())
require.Nil(t, resp)
} else {
require.NoError(t, err)
require.NotNil(t, resp)
}
})
}
}

func setLiquidator(ctx sdk.Context, perpKeeper keeper.Keeper, liquidator string) {
p := perpKeeper.GetParams(ctx)
p.WhitelistedLiquidators = []string{liquidator}
Expand Down
2 changes: 0 additions & 2 deletions x/perp/types/codec.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import (
func RegisterCodec(cdc *codec.LegacyAmino) {
cdc.RegisterConcrete(&MsgRemoveMargin{}, "perp/remove_margin", nil)
cdc.RegisterConcrete(&MsgAddMargin{}, "perp/add_margin", nil)
cdc.RegisterConcrete(&MsgLiquidate{}, "perp/liquidate", nil)
cdc.RegisterConcrete(&MsgClosePosition{}, "perp/close_position", nil)
}

Expand All @@ -20,7 +19,6 @@ func RegisterInterfaces(registry cdctypes.InterfaceRegistry) {
/* implementations */
&MsgRemoveMargin{},
&MsgAddMargin{},
&MsgLiquidate{},
&MsgOpenPosition{},
&MsgClosePosition{},
&MsgMultiLiquidate{},
Expand Down
31 changes: 0 additions & 31 deletions x/perp/types/msgs.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import (

var _ sdk.Msg = &MsgRemoveMargin{}
var _ sdk.Msg = &MsgAddMargin{}
var _ sdk.Msg = &MsgLiquidate{}
var _ sdk.Msg = &MsgOpenPosition{}
var _ sdk.Msg = &MsgClosePosition{}
var _ sdk.Msg = &MsgMultiLiquidate{}
Expand Down Expand Up @@ -130,36 +129,6 @@ func (m *MsgOpenPosition) GetSigners() []sdk.AccAddress {
return []sdk.AccAddress{signer}
}

// MsgLiquidate

func (m MsgLiquidate) Route() string { return RouterKey }
func (m MsgLiquidate) Type() string { return "liquidate_msg" }

func (m MsgLiquidate) ValidateBasic() (err error) {
if _, err = sdk.AccAddressFromBech32(m.Sender); err != nil {
return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid sender address (%s)", err)
}
if _, err = sdk.AccAddressFromBech32(m.Trader); err != nil {
return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid trader address (%s)", err)
}
if err := m.Pair.Validate(); err != nil {
return err
}
return nil
}

func (m MsgLiquidate) GetSignBytes() []byte {
return sdk.MustSortJSON(ModuleCdc.MustMarshalJSON(&m))
}

func (m MsgLiquidate) GetSigners() []sdk.AccAddress {
signer, err := sdk.AccAddressFromBech32(m.Sender)
if err != nil {
panic(err)
}
return []sdk.AccAddress{signer}
}

// MsgMultiLiquidate

func (m *MsgMultiLiquidate) ValidateBasic() error {
Expand Down
Loading