Skip to content

Commit

Permalink
Merge pull request #11550 from vegaprotocol/fix-estimate-amm-bounds-a…
Browse files Browse the repository at this point in the history
…gain

fix: do not panic if commitment is super low in estimate-AMM bounds a…
  • Loading branch information
wwestgarth authored Aug 9, 2024
2 parents c8af335 + c1e1bca commit 4bdcc38
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 12 deletions.
34 changes: 22 additions & 12 deletions core/execution/amm/estimator.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,17 @@ func EstimateBounds(
lowerPriceD := lowerPrice.ToDecimal()
boundPosLower := PositionAtLowerBound(riskFactorLower, balanceD, lowerPriceD, avgEntryLower, positionFactor)

lossLower := LossOnCommitment(avgEntryLower, lowerPriceD, boundPosLower)
// if the commitment is *so low* that the position at the bound is 0 then we will panic trying to calculate the rest
// and the "too wide" check below will flag it up as an invalid AMM defn
if !boundPosLower.IsZero() {
lossLower := LossOnCommitment(avgEntryLower, lowerPriceD, boundPosLower)

liquidationPriceAtLower := LiquidationPrice(balanceD, lossLower, boundPosLower, lowerPriceD, linearSlippageFactor, riskFactorLong)
liquidationPriceAtLower := LiquidationPrice(balanceD, lossLower, boundPosLower, lowerPriceD, linearSlippageFactor, riskFactorLong)

r.PositionSizeAtLower = boundPosLower
r.LiquidationPriceAtLower = liquidationPriceAtLower
r.LossOnCommitmentAtLower = lossLower
r.PositionSizeAtLower = boundPosLower.Mul(positionFactor)
r.LiquidationPriceAtLower = liquidationPriceAtLower
r.LossOnCommitmentAtLower = lossLower
}

// now lets check that the lower bound is not too wide that the volume is spread too thin
l := unitLower.Mul(boundPosLower).Abs()
Expand All @@ -78,13 +82,19 @@ func EstimateBounds(
avgEntryUpper := AverageEntryPrice(sqrter, unitUpper, upperPrice)
riskFactorUpper := RiskFactor(leverageUpper, riskFactorShort, linearSlippageFactor, initialMargin)
upperPriceD := upperPrice.ToDecimal()

boundPosUpper := PositionAtUpperBound(riskFactorUpper, balanceD, upperPriceD, avgEntryUpper, positionFactor)
lossUpper := LossOnCommitment(avgEntryUpper, upperPriceD, boundPosUpper)
liquidationPriceAtUpper := LiquidationPrice(balanceD, lossUpper, boundPosUpper, upperPriceD, linearSlippageFactor, riskFactorShort)

r.PositionSizeAtUpper = boundPosUpper
r.LiquidationPriceAtUpper = liquidationPriceAtUpper
r.LossOnCommitmentAtUpper = lossUpper
// if the commitment is *so low* that the position at the bound is 0 then we will panic trying to calculate the rest
// and the "too wide" check below will flag it up as an invalid AMM defn
if !boundPosUpper.IsZero() {
lossUpper := LossOnCommitment(avgEntryUpper, upperPriceD, boundPosUpper)

liquidationPriceAtUpper := LiquidationPrice(balanceD, lossUpper, boundPosUpper, upperPriceD, linearSlippageFactor, riskFactorShort)
r.PositionSizeAtUpper = boundPosUpper.Mul(positionFactor)
r.LiquidationPriceAtUpper = liquidationPriceAtUpper
r.LossOnCommitmentAtUpper = lossUpper
}

// now lets check that the lower bound is not too wide that the volume is spread too thin
l := unitUpper.Mul(boundPosUpper).Abs()
Expand Down Expand Up @@ -128,7 +138,7 @@ func PositionAtLowerBound(rf, b, pl, pa, positionFactor num.Decimal) num.Decimal
pv := rf.Mul(b).Div(
pl.Mul(oneSubRf).Add(rfMulPa),
)
return pv.Mul(positionFactor)
return pv
}

// Pvl = -rf * b / (pl * (1 + rf) - rf * pa).
Expand All @@ -139,7 +149,7 @@ func PositionAtUpperBound(rf, b, pl, pa, positionFactor num.Decimal) num.Decimal
pv := rf.Neg().Mul(b).Div(
pl.Mul(onePlusRf).Sub(rfMulPa),
)
return pv.Mul(positionFactor)
return pv
}

// lc = |(pa - pb) * pB|.
Expand Down
22 changes: 22 additions & 0 deletions core/execution/amm/estimator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -211,4 +211,26 @@ func TestEstimatePositionFactor(t *testing.T) {
assert.Equal(t, expectedMetrics.PositionSizeAtLower.String(), metrics.PositionSizeAtLower.Round(3).String())
assert.False(t, metrics.TooWideLower)
assert.False(t, metrics.TooWideUpper)

// if commitment is super low then we could panic, so test that we don't
metrics = EstimateBounds(
sqrter,
lowerPrice,
basePrice,
upperPrice,
leverageLower,
leverageUpper,
num.UintOne(),
linearSlippageFactor,
initialMargin,
riskFactorShort,
riskFactorLong,
num.DecimalFromInt64(1000000000000000000),
num.DecimalOne(),
)

assert.Equal(t, "0", metrics.PositionSizeAtUpper.Round(3).String())
assert.Equal(t, "0", metrics.PositionSizeAtLower.Round(3).String())
assert.True(t, metrics.TooWideLower)
assert.True(t, metrics.TooWideUpper)
}

0 comments on commit 4bdcc38

Please sign in to comment.