For collaterals with less than 18 decimals, the formula used in tradingAccount.withdrawMarginUsd()
is wrong,
function withdrawMarginUsd()
is used for: 1. liquidation 2. charge orderFee, settlementFee and negative unsettled PnL.
For margins with less than 18 decimals(for example, WBTC has 8 decimals), There is a problem with the following logic:
convertUd60x18ToTokenAmount(requiredMarginInCollateralX18)
will truncate the last 10 digits of 18 decimals, so that the actual value received by the receiver is always less than withdrawnMarginUsdX18
. The difference between the two value is locked into the contract forever.
It is worth noting that withdrawMarginUsd()
is executed multiple times in a single order. For users with multiple margins, this rounding issue can happen dozens of times.
If we assume withdrawMarginUsd()
is executed ten times in an order and WBTC's price = 70000usd, that means 0.007usd worth of WBTC would be locked in the contract. As orders accumulate, users suffer more and more losses.
Likelihood: high - Every transaction for every user with a margin that is not 18 decimals will experience this.
+
Impact: low - Losses from a single order are small, but can accumulate.
=
Severity: medium
Manual review
Recalculate withdrawnMarginUsdX18
based on amountToTransfer
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.