Skip to content

Commit

Permalink
add: expose open position (#435)
Browse files Browse the repository at this point in the history
* add: expose open position

* add: open position cmd

* add: open position cmd

* fix: register msg server

* chore: lint

* fix imports

* fix the imports

* fix: OpenPosition cmd and make it more readable

* make proto to include integers

* fix tests

* add open position requests

* fix linter

Co-authored-by: Agent Smith <[email protected]>
Co-authored-by: AgentSmithMatrix <[email protected]>
Co-authored-by: Walter White <[email protected]>
Co-authored-by: Mat-Cosmos <[email protected]>
  • Loading branch information
5 people authored May 22, 2022
1 parent b81d938 commit 0d45ffb
Show file tree
Hide file tree
Showing 9 changed files with 752 additions and 60 deletions.
23 changes: 23 additions & 0 deletions proto/perp/v1/tx.proto
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ package nibiru.perp.v1;
import "google/api/annotations.proto";
import "cosmos/base/v1beta1/coin.proto";
import "gogoproto/gogo.proto";
import "perp/v1/state.proto";

option go_package="github.com/NibiruChain/nibiru/x/perp/types";

Expand All @@ -18,6 +19,9 @@ service Msg {
rpc AddMargin(MsgAddMargin) returns (MsgAddMarginResponse) {
option (google.api.http).post = "/nibiru/perp/add_margin";
}

rpc OpenPosition(MsgOpenPosition) returns (MsgOpenPositionResponse) {}

}

/* MsgRemoveMargin: Msg to remove margin. */
Expand All @@ -44,4 +48,23 @@ message MsgAddMargin {

message MsgAddMarginResponse {
// MarginOut: tokens transferred back to the trader
}

message MsgOpenPosition {
string sender = 1;
string token_pair = 2;
nibiru.perp.v1.Side side = 3;
string quote_asset_amount = 4 [
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
(gogoproto.nullable) = false];
string leverage = 5 [
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
(gogoproto.nullable) = false];
string base_asset_amount_limit = 6 [
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
(gogoproto.nullable) = false];
}

message MsgOpenPositionResponse {

}
67 changes: 67 additions & 0 deletions x/perp/client/cli/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import (
"fmt"
"strings"

"github.com/NibiruChain/nibiru/x/common"

"github.com/spf13/cobra"

"github.com/cosmos/cosmos-sdk/client"
Expand Down Expand Up @@ -84,11 +86,76 @@ func GetTxCmd() *cobra.Command {
txCmd.AddCommand(
RemoveMarginCmd(),
AddMarginCmd(),
OpenPositionCmd(),
)

return txCmd
}

func OpenPositionCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "open-position [buy/sell] [pair] [leverage] [amount/sdk.Dec] [base asset amount limit/sdk.Dec]",
Short: "Opens a position",
Args: cobra.ExactArgs(5),
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx, err := client.GetClientTxContext(cmd)
if err != nil {
return err
}

txf := tx.NewFactoryCLI(clientCtx, cmd.Flags()).WithTxConfig(clientCtx.TxConfig).WithAccountRetriever(clientCtx.AccountRetriever)

var side types.Side
switch args[0] {
case "buy":
side = types.Side_BUY
case "sell":
side = types.Side_SELL
default:
return fmt.Errorf("invalid side: %s", args[0])
}

_, err = common.NewTokenPairFromStr(args[1])
if err != nil {
return err
}

leverage, err := sdk.NewDecFromStr(args[2])
if err != nil {
return err
}

amount, ok := sdk.NewIntFromString(args[3])
if !ok {
return fmt.Errorf("invalid quote amount: %s", args[3])
}

baseAssetAmountLimit, ok := sdk.NewIntFromString(args[4])
if !ok {
return fmt.Errorf("invalid base amount limit: %s", args[3])
}

msg := &types.MsgOpenPosition{
Sender: clientCtx.GetFromAddress().String(),
TokenPair: args[1],
Side: side,
QuoteAssetAmount: amount,
Leverage: leverage,
BaseAssetAmountLimit: baseAssetAmountLimit,
}

if err := msg.ValidateBasic(); err != nil {
return err
}

return tx.GenerateOrBroadcastTxWithFactory(clientCtx, txf, msg)
},
}

flags.AddTxFlagsToCmd(cmd)
return cmd
}

/*
RemoveMarginCmd is a CLI command that removes margin from a position,
realizing any outstanding funding payments and decreasing the margin ratio.
Expand Down
9 changes: 4 additions & 5 deletions x/perp/keeper/clearing_house.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,12 @@ import (
"fmt"
"time"

"github.com/NibiruChain/nibiru/x/common"
"github.com/NibiruChain/nibiru/x/perp/events"
pooltypes "github.com/NibiruChain/nibiru/x/vpool/types"

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

"github.com/NibiruChain/nibiru/x/common"
"github.com/NibiruChain/nibiru/x/perp/events"
"github.com/NibiruChain/nibiru/x/perp/types"
pooltypes "github.com/NibiruChain/nibiru/x/vpool/types"
)

// TODO test: OpenPosition | https://github.com/NibiruChain/nibiru/issues/299
Expand Down Expand Up @@ -45,7 +44,7 @@ func (k Keeper) OpenPosition(
var positionResp *types.PositionResp
sameSideLong := position.Size_.IsPositive() && side == types.Side_BUY
sameSideShort := position.Size_.IsNegative() && side == types.Side_SELL
var openSideMatchesPosition bool = (sameSideLong || sameSideShort)
var openSideMatchesPosition = sameSideLong || sameSideShort
switch {
case isNewPosition || openSideMatchesPosition:
// increase position case
Expand Down
43 changes: 23 additions & 20 deletions x/perp/keeper/msg_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,45 +3,48 @@ package keeper
import (
"context"

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

"github.com/NibiruChain/nibiru/x/common"
"github.com/NibiruChain/nibiru/x/perp/types"
)

type msgServer struct {
Keeper
k Keeper
}

// NewMsgServerImpl returns an implementation of the MsgServer interface
// for the provided Keeper.
func NewMsgServerImpl(keeper Keeper) types.MsgServer {
return &msgServer{Keeper: keeper}
return &msgServer{k: keeper}
}

var _ types.MsgServer = msgServer{}

/*
Args:
goCtx
Returns
MsgRemoveMarginResponse:
error:
*/
func (k msgServer) MsgRemoveMargin(goCtx context.Context, msg *types.MsgRemoveMargin,
) (*types.MsgRemoveMarginResponse, error) {
removeMarginResponse, err := k.RemoveMargin(goCtx, msg)
func (k msgServer) RemoveMargin(ctx context.Context, margin *types.MsgRemoveMargin) (*types.MsgRemoveMarginResponse, error) {
return k.k.RemoveMargin(ctx, margin)
}

func (k msgServer) AddMargin(ctx context.Context, margin *types.MsgAddMargin) (*types.MsgAddMarginResponse, error) {
return k.k.AddMargin(ctx, margin)
}

func (k msgServer) OpenPosition(ctx context.Context, req *types.MsgOpenPosition) (*types.MsgOpenPositionResponse, error) {
pair, err := common.NewTokenPairFromStr(req.TokenPair)
if err != nil {
return nil, err
panic(err) // must not happen
}

return removeMarginResponse, nil
}
addr, err := sdk.AccAddressFromBech32(req.Sender)
if err != nil {
panic(err) // must not happen
}

func (k msgServer) MsgAddMargin(goCtx context.Context, msg *types.MsgAddMargin,
) (*types.MsgAddMarginResponse, error) {
removeMarginResponse, err := k.AddMargin(goCtx, msg)
sdkCtx := sdk.UnwrapSDKContext(ctx)
err = k.k.OpenPosition(sdkCtx, pair, req.Side, addr, req.QuoteAssetAmount, req.Leverage, req.BaseAssetAmountLimit.ToDec())
if err != nil {
return nil, err
}

return removeMarginResponse, nil
return &types.MsgOpenPositionResponse{}, nil
}
2 changes: 1 addition & 1 deletion x/perp/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ func (am AppModule) LegacyQuerierHandler(legacyQuerierCdc *codec.LegacyAmino) sd
// module-specific GRPC queries.
func (am AppModule) RegisterServices(cfg module.Configurator) {
types.RegisterQueryServer(cfg.QueryServer(), am.keeper)
types.RegisterMsgServer(cfg.MsgServer(), am.keeper)
types.RegisterMsgServer(cfg.MsgServer(), keeper.NewMsgServerImpl(am.keeper))
}

// RegisterInvariants registers the capability module's invariants.
Expand Down
1 change: 1 addition & 0 deletions x/perp/types/codec.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ func RegisterInterfaces(registry cdctypes.InterfaceRegistry) {
/* implementations */
&MsgRemoveMargin{},
&MsgAddMargin{},
&MsgOpenPosition{},
)

msgservice.RegisterMsgServiceDesc(registry, &_Msg_serviceDesc)
Expand Down
37 changes: 37 additions & 0 deletions x/perp/types/msgs.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
package types

import (
"fmt"

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

"github.com/NibiruChain/nibiru/x/common"
)

var _ sdk.Msg = &MsgRemoveMargin{}
var _ sdk.Msg = &MsgAddMargin{}
var _ sdk.Msg = &MsgOpenPosition{}

// MsgRemoveMargin

Expand Down Expand Up @@ -42,3 +47,35 @@ func (m MsgAddMargin) GetSigners() []sdk.AccAddress {
sender, _ := sdk.AccAddressFromBech32(m.Sender)
return []sdk.AccAddress{sender}
}

func (m *MsgOpenPosition) ValidateBasic() error {
if m.Side != Side_SELL && m.Side != Side_BUY {
return fmt.Errorf("invalid side")
}
if _, err := common.NewTokenPairFromStr(m.TokenPair); err != nil {
return err
}
if _, err := sdk.AccAddressFromBech32(m.Sender); err != nil {
return err
}
if !m.Leverage.GT(sdk.ZeroDec()) {
return fmt.Errorf("leverage must always be greater than zero")
}
if !m.BaseAssetAmountLimit.GT(sdk.ZeroInt()) {
return fmt.Errorf("base asset amount limit must always be greater than zero")
}
if m.QuoteAssetAmount.GT(sdk.ZeroInt()) {
return fmt.Errorf("quote asset amount must be always greater than zero")
}

return nil
}

func (m *MsgOpenPosition) GetSigners() []sdk.AccAddress {
addr, err := sdk.AccAddressFromBech32(m.Sender)
if err != nil {
panic(err)
}

return []sdk.AccAddress{addr}
}
Loading

0 comments on commit 0d45ffb

Please sign in to comment.