Skip to content

Commit

Permalink
program: handle underflow in calculate_liability_transfer_to_cover_ma… (
Browse files Browse the repository at this point in the history
#774)

* program: handle underflow in calculate_liability_transfer_to_cover_margin_shortage

* CHANGELOG
  • Loading branch information
crispheaney authored Dec 19, 2023
1 parent 929251e commit 337edac
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 13 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Fixes

- program: handle underflow in calculate_liability_transfer_to_cover_margin_shortage ([#774](https://github.com/drift-labs/protocol-v2/pull/774))
- program: flip auction flag when trigger order adds auction ([#775](https://github.com/drift-labs/protocol-v2/pull/775))
- program: don't perform funding rate updates when slots_since_amm_update is stale ([#757](https://github.com/drift-labs/protocol-v2/pull/757))
- program: add update last slot for filler in pay_keeper_flat_reward_for_spot
Expand Down
27 changes: 14 additions & 13 deletions programs/drift/src/math/liquidation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ pub fn calculate_liability_transfer_to_cover_margin_shortage(
if_liquidation_fee: u32,
) -> DriftResult<u128> {
// If unsettled pnl asset weight is 1 and quote asset is 1, this calculation breaks
if asset_weight == liability_weight && asset_weight >= liability_weight {
if asset_weight >= liability_weight {
return Ok(u128::MAX);
}

Expand All @@ -78,24 +78,25 @@ pub fn calculate_liability_transfer_to_cover_margin_shortage(
(1, 10_u128.pow(6 - liability_decimals))
};

let liability_weight_component = liability_weight.cast::<u128>()?.safe_mul(10)?; // multiply market weights by extra 10 to increase precision

let asset_weight_component = asset_weight
.cast::<u128>()?
.safe_mul(10)?
.safe_mul(asset_liquidation_multiplier.cast()?)?
.safe_div(liability_liquidation_multiplier.cast()?)?;

if asset_weight_component > liability_weight_component {
return Ok(u128::MAX);
}

margin_shortage
.safe_mul(numerator_scale)?
.safe_mul(PRICE_PRECISION * SPOT_WEIGHT_PRECISION_U128 * 10)?
.safe_div(
liability_price
.cast::<u128>()?
.safe_mul(
liability_weight
.cast::<u128>()?
.safe_mul(10)? // multiply market weights by extra 10 to increase precision
.safe_sub(
asset_weight
.cast::<u128>()?
.safe_mul(10)?
.safe_mul(asset_liquidation_multiplier.cast()?)?
.safe_div(liability_liquidation_multiplier.cast()?)?,
)?,
)?
.safe_mul(liability_weight_component.safe_sub(asset_weight_component)?)?
.safe_sub(
liability_price
.cast::<u128>()?
Expand Down
25 changes: 25 additions & 0 deletions programs/drift/src/math/liquidation/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,31 @@ mod calculate_liability_transfer_to_cover_margin_shortage {
);
assert_eq!(liability_transfer, 475669504);
}

#[test]
pub fn liability_weight_component_less_than_asset_weight_component() {
let margin_shortage = 10 * QUOTE_PRECISION; // $10 shortage
let asset_weight = SPOT_WEIGHT_PRECISION; // .8
let asset_liquidation_multiplier = LIQUIDATION_FEE_PRECISION;
let liability_weight = SPOT_WEIGHT_PRECISION; // 1
let liability_liquidation_multiplier = 75 * LIQUIDATION_FEE_PRECISION / 100; // .75
let liability_decimals = 6;
let liability_price = 100 * PRICE_PRECISION_I64;

let liability_transfer = calculate_liability_transfer_to_cover_margin_shortage(
margin_shortage,
asset_weight,
asset_liquidation_multiplier,
liability_weight,
liability_liquidation_multiplier,
liability_decimals,
liability_price,
0,
)
.unwrap();

assert_eq!(liability_transfer, u128::MAX);
}
}

mod calculate_liability_transfer_implied_by_asset_amount {
Expand Down

0 comments on commit 337edac

Please sign in to comment.