Skip to content

Commit bf04be1

Browse files
philipsu522codchen
andcommitted
Add more validation to order placement (#175)
* Add more validation to order placement * gofumpt * Rm account and contract addr validation * Add fund check * Add nil check * fix lint * Catch all panics in DEX EndBlock (#176) * Catch all panics in DEX EndBlock * update metric key * address comments * Add catch-all for all custom modules (#178) * Refactor `dex` `Endblock` logic per contract (#174) * Refactor dex EndBlock * tests * Refactor `dex` EndBlock logic * fix order pointer Co-authored-by: codchen <[email protected]>
1 parent 02b5e8b commit bf04be1

File tree

3 files changed

+107
-7
lines changed

3 files changed

+107
-7
lines changed

x/dex/keeper/msgserver/msg_server_place_orders.go

+14-4
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package msgserver
33
import (
44
"context"
55
"errors"
6+
"fmt"
67
"math/big"
78

89
conversion "github.com/sei-protocol/sei-chain/utils"
@@ -32,6 +33,9 @@ func (k msgServer) transferFunds(goCtx context.Context, msg *types.MsgPlaceOrder
3233
}
3334

3435
for _, fund := range msg.Funds {
36+
if fund.Amount.IsNil() || fund.IsNegative() {
37+
return errors.New("fund deposits cannot be nil or negative")
38+
}
3539
k.MemState.GetDepositInfo(typesutils.ContractAddress(msg.GetContractAddr())).AddDeposit(dexcache.DepositInfoEntry{
3640
Creator: msg.Creator,
3741
Denom: fund.Denom,
@@ -99,11 +103,17 @@ func (k msgServer) PlaceOrders(goCtx context.Context, msg *types.MsgPlaceOrders)
99103
}
100104

101105
func (k msgServer) validateOrder(order *types.Order) error {
102-
if order.Quantity.IsNil() {
103-
return errors.New("quantity cannot be empty")
106+
if order.Quantity.IsNil() || order.Quantity.IsNegative() {
107+
return fmt.Errorf("invalid order quantity: %s", order.Quantity)
108+
}
109+
if order.Price.IsNil() || order.Price.IsNegative() {
110+
return fmt.Errorf("invalid order price: %s", order.Price)
111+
}
112+
if len(order.AssetDenom) == 0 {
113+
return fmt.Errorf("invalid order, asset denom is empty")
104114
}
105-
if order.Price.IsNil() {
106-
return errors.New("price cannot be empty")
115+
if len(order.PriceDenom) == 0 {
116+
return fmt.Errorf("invalid order, price denom is empty")
107117
}
108118
return nil
109119
}

x/dex/keeper/msgserver/msg_server_place_orders_test.go

+91-2
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,10 @@ import (
1010
"github.com/stretchr/testify/require"
1111
)
1212

13-
const TestCreator = "sei1ewxvf5a9wq9zk5nurtl6m9yfxpnhyp7s7uk5sl"
14-
const TestContract = "sei14hj2tavq8fpesdwxxcu44rty3hh90vhujrvcmstl4zr3txmfvw9sh9m79m"
13+
const (
14+
TestCreator = "sei1ewxvf5a9wq9zk5nurtl6m9yfxpnhyp7s7uk5sl"
15+
TestContract = "sei14hj2tavq8fpesdwxxcu44rty3hh90vhujrvcmstl4zr3txmfvw9sh9m79m"
16+
)
1517

1618
func TestPlaceOrder(t *testing.T) {
1719
msg := &types.MsgPlaceOrders{
@@ -48,6 +50,9 @@ func TestPlaceOrder(t *testing.T) {
4850
require.Equal(t, 2, len(res.OrderIds))
4951
require.Equal(t, uint64(0), res.OrderIds[0])
5052
require.Equal(t, uint64(1), res.OrderIds[1])
53+
// Ensure that contract addr and account is set in the order
54+
require.Equal(t, msg.Orders[0].ContractAddr, TestContract)
55+
require.Equal(t, msg.Orders[0].Account, TestCreator)
5156
}
5257

5358
func TestPlaceInvalidOrder(t *testing.T) {
@@ -56,6 +61,7 @@ func TestPlaceInvalidOrder(t *testing.T) {
5661
keeper.SetTickSizeForPair(ctx, TestContract, keepertest.TestPair, *keepertest.TestPair.Ticksize)
5762
wctx := sdk.WrapSDKContext(ctx)
5863

64+
// Empty quantity
5965
msg := &types.MsgPlaceOrders{
6066
Creator: TestCreator,
6167
ContractAddr: TestContract,
@@ -75,6 +81,7 @@ func TestPlaceInvalidOrder(t *testing.T) {
7581
_, err := server.PlaceOrders(wctx, msg)
7682
require.NotNil(t, err)
7783

84+
// Empty price
7885
msg = &types.MsgPlaceOrders{
7986
Creator: TestCreator,
8087
ContractAddr: TestContract,
@@ -93,4 +100,86 @@ func TestPlaceInvalidOrder(t *testing.T) {
93100
server = msgserver.NewMsgServerImpl(*keeper, nil)
94101
_, err = server.PlaceOrders(wctx, msg)
95102
require.NotNil(t, err)
103+
104+
// Negative quantity
105+
msg = &types.MsgPlaceOrders{
106+
Creator: TestCreator,
107+
ContractAddr: TestContract,
108+
Orders: []*types.Order{
109+
{
110+
Price: sdk.MustNewDecFromStr("10"),
111+
Quantity: sdk.MustNewDecFromStr("-1"),
112+
Data: "",
113+
PositionDirection: types.PositionDirection_LONG,
114+
OrderType: types.OrderType_LIMIT,
115+
PriceDenom: keepertest.TestPriceDenom,
116+
AssetDenom: keepertest.TestAssetDenom,
117+
},
118+
},
119+
}
120+
server = msgserver.NewMsgServerImpl(*keeper, nil)
121+
_, err = server.PlaceOrders(wctx, msg)
122+
require.NotNil(t, err)
123+
124+
// Negative price
125+
msg = &types.MsgPlaceOrders{
126+
Creator: TestCreator,
127+
ContractAddr: TestContract,
128+
Orders: []*types.Order{
129+
{
130+
Price: sdk.MustNewDecFromStr("-1"),
131+
Quantity: sdk.MustNewDecFromStr("10"),
132+
Data: "",
133+
PositionDirection: types.PositionDirection_LONG,
134+
OrderType: types.OrderType_LIMIT,
135+
PriceDenom: keepertest.TestPriceDenom,
136+
AssetDenom: keepertest.TestAssetDenom,
137+
ContractAddr: TestContract,
138+
Account: "testaccount",
139+
},
140+
},
141+
}
142+
server = msgserver.NewMsgServerImpl(*keeper, nil)
143+
_, err = server.PlaceOrders(wctx, msg)
144+
require.NotNil(t, err)
145+
146+
// Missing contract
147+
msg = &types.MsgPlaceOrders{
148+
Creator: TestCreator,
149+
ContractAddr: TestContract,
150+
Orders: []*types.Order{
151+
{
152+
Price: sdk.MustNewDecFromStr("-1"),
153+
Quantity: sdk.MustNewDecFromStr("10"),
154+
Data: "",
155+
PositionDirection: types.PositionDirection_LONG,
156+
OrderType: types.OrderType_LIMIT,
157+
PriceDenom: keepertest.TestPriceDenom,
158+
AssetDenom: keepertest.TestAssetDenom,
159+
},
160+
},
161+
}
162+
server = msgserver.NewMsgServerImpl(*keeper, nil)
163+
_, err = server.PlaceOrders(wctx, msg)
164+
require.NotNil(t, err)
165+
166+
// Missing account
167+
msg = &types.MsgPlaceOrders{
168+
Creator: TestCreator,
169+
ContractAddr: TestContract,
170+
Orders: []*types.Order{
171+
{
172+
Price: sdk.MustNewDecFromStr("-1"),
173+
Quantity: sdk.MustNewDecFromStr("10"),
174+
Data: "",
175+
PositionDirection: types.PositionDirection_LONG,
176+
OrderType: types.OrderType_LIMIT,
177+
PriceDenom: keepertest.TestPriceDenom,
178+
AssetDenom: keepertest.TestAssetDenom,
179+
},
180+
},
181+
}
182+
server = msgserver.NewMsgServerImpl(*keeper, nil)
183+
_, err = server.PlaceOrders(wctx, msg)
184+
require.NotNil(t, err)
96185
}

x/dex/module_test.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -336,7 +336,8 @@ func TestEndBlockPanicHandling(t *testing.T) {
336336
dexkeeper.SetContract(ctx, &types.ContractInfo{CodeId: 123, ContractAddr: contractAddr.String(), NeedHook: true, NeedOrderMatching: true})
337337
dexkeeper.AddRegisteredPair(ctx, contractAddr.String(), pair)
338338
dexkeeper.MemState.GetBlockOrders(utils.ContractAddress(contractAddr.String()), utils.GetPairString(&pair)).AddOrder(
339-
types.Order{
339+
&types.Order{
340+
340341
Id: 1,
341342
Account: testAccount.String(),
342343
ContractAddr: contractAddr.String(),

0 commit comments

Comments
 (0)