From 79db31a4e730f05a8b4cf737db1ac038af599ce9 Mon Sep 17 00:00:00 2001 From: sr33j Date: Mon, 23 Sep 2024 16:28:37 -0400 Subject: [PATCH] add check for invalid skew factor (#2249) --- protocol/x/vault/types/errors.go | 5 ++++ protocol/x/vault/types/params.go | 9 +++++++ protocol/x/vault/types/params_test.go | 37 +++++++++++++++++++++++++++ 3 files changed, 51 insertions(+) diff --git a/protocol/x/vault/types/errors.go b/protocol/x/vault/types/errors.go index 4b4d541dec..3374cd11fd 100644 --- a/protocol/x/vault/types/errors.go +++ b/protocol/x/vault/types/errors.go @@ -155,4 +155,9 @@ var ( 30, "Shares must be positive", ) + ErrInvalidSkewFactor = errorsmod.Register( + ModuleName, + 31, + "Skew factor times order_size_pct must be less than 2 to avoid skewing over the spread", + ) ) diff --git a/protocol/x/vault/types/params.go b/protocol/x/vault/types/params.go index 4236d981d1..578f7030cb 100644 --- a/protocol/x/vault/types/params.go +++ b/protocol/x/vault/types/params.go @@ -2,6 +2,7 @@ package types import ( "math" + "math/big" "github.com/dydxprotocol/v4-chain/protocol/dtypes" "github.com/dydxprotocol/v4-chain/protocol/lib" @@ -42,6 +43,14 @@ func (p QuotingParams) Validate() error { if p.ActivationThresholdQuoteQuantums.Sign() < 0 { return ErrInvalidActivationThresholdQuoteQuantums } + // Skew factor times order_size_pct must be less than 2 to avoid skewing over the spread + skewFactor := new(big.Int).SetUint64(uint64(p.SkewFactorPpm)) + orderSizePct := new(big.Int).SetUint64(uint64(p.OrderSizePctPpm)) + skewFactorOrderSizePctProduct := new(big.Int).Mul(skewFactor, orderSizePct) + skewFactorOrderSizePctProductThreshold := big.NewInt(2_000_000 * 1_000_000) + if skewFactorOrderSizePctProduct.Cmp(skewFactorOrderSizePctProductThreshold) >= 0 { + return ErrInvalidSkewFactor + } return nil } diff --git a/protocol/x/vault/types/params_test.go b/protocol/x/vault/types/params_test.go index 9705241f61..4d72dd9d5f 100644 --- a/protocol/x/vault/types/params_test.go +++ b/protocol/x/vault/types/params_test.go @@ -1,6 +1,7 @@ package types_test import ( + "math" "testing" "github.com/dydxprotocol/v4-chain/protocol/dtypes" @@ -80,6 +81,42 @@ func TestValidateQuotingParams(t *testing.T) { }, expectedErr: types.ErrInvalidActivationThresholdQuoteQuantums, }, + "Failure - SkewFactorPpm is high. Product of SkewFactorPpm and OrderSizePctPpm is above threshold.": { + params: types.QuotingParams{ + Layers: 2, + SpreadMinPpm: 3_000, + SpreadBufferPpm: 1_500, + SkewFactorPpm: 20_000_000, + OrderSizePctPpm: 100_000, + OrderExpirationSeconds: 5, + ActivationThresholdQuoteQuantums: dtypes.NewInt(1), + }, + expectedErr: types.ErrInvalidSkewFactor, + }, + "Failure - OrderSizePctPpm is high. Product of SkewFactorPpm and OrderSizePctPpm is above threshold.": { + params: types.QuotingParams{ + Layers: 2, + SpreadMinPpm: 3_000, + SpreadBufferPpm: 1_500, + SkewFactorPpm: 2_000_000, + OrderSizePctPpm: 1_000_000, + OrderExpirationSeconds: 5, + ActivationThresholdQuoteQuantums: dtypes.NewInt(1), + }, + expectedErr: types.ErrInvalidSkewFactor, + }, + "Failure - Both OrderSizePctPpm and SkewFactorPpm are MaxUint32. The product is above the threshold.": { + params: types.QuotingParams{ + Layers: 2, + SpreadMinPpm: 3_000, + SpreadBufferPpm: 1_500, + SkewFactorPpm: math.MaxUint32, + OrderSizePctPpm: math.MaxUint32, + OrderExpirationSeconds: 5, + ActivationThresholdQuoteQuantums: dtypes.NewInt(1), + }, + expectedErr: types.ErrInvalidSkewFactor, + }, } for name, tc := range tests {