Skip to content

Commit

Permalink
program: fix small precision issues (#1399)
Browse files Browse the repository at this point in the history
* program: fix small precision issues

* sdk: add numeratorScale/denominatorScale for getWithdrawalLimit

* update CHANGELOG.md

---------

Co-authored-by: 0xbigz <[email protected]>
  • Loading branch information
crispheaney and 0xbigz authored Dec 23, 2024
1 parent b0b3be2 commit 42eb38d
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 8 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

- program: fix force delete user for token 2022 ([#1358](https://github.com/drift-labs/protocol-v2/pull/1358))
- program: fix liquidating dust prediction mkt position ([#1397](https://github.com/drift-labs/protocol-v2/pull/1397))
- program: spot market decimals under 6 precision fixes ([#1399](https://github.com/drift-labs/protocol-v2/pull/1399))

### Breaking

Expand Down
9 changes: 7 additions & 2 deletions programs/drift/src/math/margin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -801,14 +801,19 @@ pub fn calculate_max_withdrawable_amount(

let free_collateral = calculation.get_free_collateral()?;

let precision_increase = 10u128.pow(spot_market.decimals - 6);
let (numerator_scale, denominator_scale) = if spot_market.decimals > 6 {
(10_u128.pow(spot_market.decimals - 6), 1)
} else {
(1, 10_u128.pow(6 - spot_market.decimals))
};

free_collateral
.safe_mul(MARGIN_PRECISION_U128)?
.safe_div(asset_weight.cast()?)?
.safe_mul(PRICE_PRECISION)?
.safe_div(oracle_price.cast()?)?
.safe_mul(precision_increase)?
.safe_mul(numerator_scale)?
.safe_div(denominator_scale)?
.cast()
}

Expand Down
9 changes: 7 additions & 2 deletions programs/drift/src/math/orders.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1130,12 +1130,17 @@ pub fn calculate_max_spot_order_size(
user_custom_asset_weight,
)?;

let precision_increase = 10i128.pow(spot_market.decimals - 6);
let (numerator_scale, denominator_scale) = if spot_market.decimals > 6 {
(10_i128.pow(spot_market.decimals - 6), 1)
} else {
(1, 10_i128.pow(6 - spot_market.decimals))
};

let calculate_order_size_and_free_collateral_delta = |free_collateral_delta: u32| {
let new_order_size = free_collateral
.safe_sub(OPEN_ORDER_MARGIN_REQUIREMENT.cast()?)?
.safe_mul(precision_increase)?
.safe_mul(numerator_scale)?
.safe_div(denominator_scale)?
.safe_mul(SPOT_WEIGHT_PRECISION.cast()?)?
.safe_div(free_collateral_delta.cast()?)?
.safe_mul(PRICE_PRECISION_I128)?
Expand Down
19 changes: 15 additions & 4 deletions sdk/src/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ import {
QUOTE_PRECISION_EXP,
QUOTE_SPOT_MARKET_INDEX,
SPOT_MARKET_WEIGHT_PRECISION,
TEN,
TEN_THOUSAND,
TWO,
ZERO,
Expand Down Expand Up @@ -3540,7 +3539,16 @@ export class User {
const freeCollateral = this.getFreeCollateral();
const initialMarginRequirement = this.getInitialMarginRequirement();
const oracleData = this.getOracleDataForSpotMarket(marketIndex);
const precisionIncrease = TEN.pow(new BN(spotMarket.decimals - 6));
const { numeratorScale, denominatorScale } =
spotMarket.decimals > 6
? {
numeratorScale: new BN(10).pow(new BN(spotMarket.decimals - 6)),
denominatorScale: new BN(1),
}
: {
numeratorScale: new BN(1),
denominatorScale: new BN(10).pow(new BN(6 - spotMarket.decimals)),
};

const { canBypass, depositAmount: userDepositAmount } =
this.canBypassWithdrawLimits(marketIndex);
Expand All @@ -3566,7 +3574,9 @@ export class User {
PRICE_PRECISION
),
oracleData.price
).mul(precisionIncrease);
)
.mul(numeratorScale)
.div(denominatorScale);
}

const maxWithdrawValue = BN.min(
Expand All @@ -3592,7 +3602,8 @@ export class User {
.div(new BN(spotMarket.initialLiabilityWeight))
.mul(PRICE_PRECISION)
.div(oracleData.price)
.mul(precisionIncrease);
.mul(numeratorScale)
.div(denominatorScale);

const maxBorrowValue = BN.min(
maxWithdrawValue.add(maxLiabilityAllowed),
Expand Down

0 comments on commit 42eb38d

Please sign in to comment.