From c57d1d576df3094c1259a0aa377df698f86ef64e Mon Sep 17 00:00:00 2001 From: wwestgarth Date: Mon, 2 Sep 2024 16:17:47 +0100 Subject: [PATCH] fix: handle one sided amm that reduces to point expansion in orderbookshape --- CHANGELOG.md | 1 + core/execution/amm/shape.go | 10 ++++++---- core/execution/amm/shape_test.go | 34 ++++++++++++++++++++++++++++++++ 3 files changed, 41 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dac145aef4..962e52de66 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -36,6 +36,7 @@ - [11521](https://github.com/vegaprotocol/vega/issues/11521) - Restore `AMM` position factor when loading from a snapshot. - [11526](https://github.com/vegaprotocol/vega/issues/11526) - `EstimateAMMBounds` now respects the market's decimal places. - [11486](https://github.com/vegaprotocol/vega/issues/11486) - `AMMs` can now be submitted on markets with more decimal places than asset decimal places. +- [11635](https://github.com/vegaprotocol/vega/issues/11635) - Handle expansion of one sided `AMMs` that reduce to point expansion when calculating order book shape. - [11561](https://github.com/vegaprotocol/vega/issues/11561) - Failing amends on `AMMs` now restore original properly. - [11583](https://github.com/vegaprotocol/vega/issues/11583) - Remove `AMMs` entirely from engine when market closes. - [11568](https://github.com/vegaprotocol/vega/issues/11568) - order book shape on closing `AMM` no longer panics. diff --git a/core/execution/amm/shape.go b/core/execution/amm/shape.go index 9cfc6fcb07..91196581af 100644 --- a/core/execution/amm/shape.go +++ b/core/execution/amm/shape.go @@ -321,13 +321,15 @@ func (sm *shapeMaker) adjustRegion() bool { return false } - if sm.from.EQ(sm.to) && sm.from.EQ(sm.fairPrice) { - return false - } - // cap the range to the pool's bounds, there will be no orders outside of this from := num.Max(sm.from, lower) to := num.Min(sm.to, upper) + + // expansion is a point region *at* fair-price, there are no orders + if from.EQ(to) && from.EQ(sm.fairPrice) { + return false + } + switch { case sm.from.GT(sm.fairPrice): // if we are expanding entirely in the sell range to calculate the order at price `from` diff --git a/core/execution/amm/shape_test.go b/core/execution/amm/shape_test.go index bd4c381c1d..57e0916f74 100644 --- a/core/execution/amm/shape_test.go +++ b/core/execution/amm/shape_test.go @@ -36,6 +36,7 @@ func TestOrderbookShape(t *testing.T) { t.Run("test orderbook shape boundary order when approx", testOrderbookShapeBoundaryOrder) t.Run("test orderbook shape region not divisible by tick", testOrderbookSubTick) t.Run("test orderbook shape closing pool close to base", testClosingCloseToBase) + t.Run("test orderbook shape point expansion at fair price", testPointExpansionAtFairPrice) } func testOrderbookShapeZeroPosition(t *testing.T) { @@ -416,3 +417,36 @@ func testClosingCloseToBase(t *testing.T) { assert.Equal(t, 0, len(buys)) assert.Equal(t, 0, len(sells)) } + +func testPointExpansionAtFairPrice(t *testing.T) { + p := newTestPoolWithRanges(t, num.NewUint(7), num.NewUint(10), num.NewUint(13)) + defer p.ctrl.Finish() + + base := p.submission.Parameters.Base + + // range [10, 10] fair price is 10, no orders + ensurePositionN(t, p.pos, 0, num.UintZero(), 2) + buys, sells := p.pool.OrderbookShape(base, base, nil) + assert.Equal(t, 0, len(buys)) + assert.Equal(t, 0, len(sells)) + + // now try with a one sided curve where the input range shrinks to a point-expansion + p = newTestPoolWithRanges(t, num.NewUint(7), num.NewUint(10), nil) + defer p.ctrl.Finish() + + // range [10, 1000] but sell curve is empty so effective range is [10, 10] at fair-price + ensurePositionN(t, p.pos, 0, num.UintZero(), 2) + buys, sells = p.pool.OrderbookShape(base, num.NewUint(1000), nil) + assert.Equal(t, 0, len(buys)) + assert.Equal(t, 0, len(sells)) + + // now try with a one sided curve where the input range shrinks to a point-expansion + p = newTestPoolWithRanges(t, nil, num.NewUint(10), num.NewUint(13)) + defer p.ctrl.Finish() + + // range [1, 10] but buy curve is empty so effective range is [10, 10] at fair-price + ensurePositionN(t, p.pos, 0, num.UintZero(), 2) + buys, sells = p.pool.OrderbookShape(num.NewUint(1), base, nil) + assert.Equal(t, 0, len(buys)) + assert.Equal(t, 0, len(sells)) +}