From 2872cda890c64fe923296d6c0038b606b65168ac Mon Sep 17 00:00:00 2001
From: wwestgarth <william@vega.xyz>
Date: Wed, 17 Jul 2024 11:08:37 +0100
Subject: [PATCH] fix: populate all fields to prevent 0 div panic

---
 datanode/service/market_depth_amm.go      |  6 +++--
 datanode/service/market_depth_amm_test.go | 27 +++++++++++++++++++++++
 2 files changed, 31 insertions(+), 2 deletions(-)

diff --git a/datanode/service/market_depth_amm.go b/datanode/service/market_depth_amm.go
index b0a92b7344..949f696fec 100644
--- a/datanode/service/market_depth_amm.go
+++ b/datanode/service/market_depth_amm.go
@@ -518,15 +518,16 @@ func definitionFromEntity(ent entities.AMMPool, position int64, priceFactor num.
 
 	assetHigh, _ := num.UintFromDecimal(high.ToDecimal().Mul(priceFactor))
 	assetBase, _ := num.UintFromDecimal(base.ToDecimal().Mul(priceFactor))
-	assetlow, _ := num.UintFromDecimal(low.ToDecimal().Mul(priceFactor))
+	assetLow, _ := num.UintFromDecimal(low.ToDecimal().Mul(priceFactor))
 
 	return &ammDefn{
 		position: num.DecimalFromInt64(position),
 		lower: &curve{
 			low:       low,
 			high:      base,
-			assetLow:  assetlow,
+			assetLow:  assetLow,
 			assetHigh: assetBase,
+			sqrtLow:   num.UintOne().Sqrt(assetLow),
 			sqrtHigh:  num.UintOne().Sqrt(assetBase),
 			isLower:   true,
 			l:         ent.LowerVirtualLiquidity,
@@ -537,6 +538,7 @@ func definitionFromEntity(ent entities.AMMPool, position int64, priceFactor num.
 			high:      high,
 			assetLow:  assetBase,
 			assetHigh: assetHigh,
+			sqrtLow:   num.UintOne().Sqrt(assetBase),
 			sqrtHigh:  num.UintOne().Sqrt(assetHigh),
 			l:         ent.UpperVirtualLiquidity,
 			pv:        ent.UpperTheoreticalPosition,
diff --git a/datanode/service/market_depth_amm_test.go b/datanode/service/market_depth_amm_test.go
index bbf96e8b61..3b3bc0df64 100644
--- a/datanode/service/market_depth_amm_test.go
+++ b/datanode/service/market_depth_amm_test.go
@@ -250,6 +250,33 @@ func TestAMMSmallBounds(t *testing.T) {
 	assert.Equal(t, 0, int(mds.service.GetVolumeAtPrice(marketID, types.SideSell, 2002)))
 }
 
+func TestEstimatedStepOverAMMBound(t *testing.T) {
+	ctx := context.Background()
+	mds := getServiceWithConfig(t,
+		service.MarketDepthConfig{
+			AmmFullExpansionPercentage: 5,
+			AmmEstimatedStepPercentage: 7.6, // make this a werid number so our estimated steps are not nice multiplies of 10
+			AmmMaxEstimatedSteps:       5,
+		},
+	)
+	defer mds.ctrl.Finish()
+
+	marketID := vgcrypto.RandomHash()
+	ensureLiveOrders(t, mds, marketID)
+	ensureDecimalPlaces(t, mds)
+	mds.pos.EXPECT().GetByMarketAndParty(gomock.Any(), gomock.Any(), gomock.Any()).Return(entities.Position{OpenVolume: 0}, nil)
+	mds.marketData.EXPECT().GetMarketDataByID(gomock.Any(), gomock.Any()).Times(1).Return(entities.MarketData{MidPrice: num.DecimalFromInt64(2000)}, nil)
+
+	// data node is starting from network history, initialise market-depth based on whats aleady there
+	ensureAMMs(t, mds, marketID)
+	mds.service.Initialise(ctx)
+
+	assert.Equal(t, "1999", mds.service.GetBestBidPrice(marketID).String())
+	assert.Equal(t, "2001", mds.service.GetBestAskPrice(marketID).String())
+	assert.Equal(t, 3, int(mds.service.GetVolumeAtPrice(marketID, types.SideBuy, 1999)))
+	assert.Equal(t, 3, int(mds.service.GetVolumeAtPrice(marketID, types.SideSell, 2001)))
+}
+
 func ensureLiveOrders(t *testing.T, mds *MDS, marketID string) {
 	t.Helper()
 	mds.orders.EXPECT().GetLiveOrders(gomock.Any()).Return([]entities.Order{