DeFiFoundry
60,000 USDC
View results
Submission Details
Severity: high
Valid

check in withdrawMargin doesnt prevent user from withdrawing all the way to maintenance margin which could lead to liquidation of the account

Summary

when withdrawing margin the validateMarginRequirement check is bypassed when requiredInitialMarginUsdX18 and marginBalanceUsdX18 are equal which means the function may allow users to withdraw funds down to the maintenance margin, increasing the risk of liquidation.

Vulnerability Details

here is the check which is supposed to prevent user from withdrawing to the maintainance margin.

check against initial margin requirement as initial margin > maintanance margin
hence prevent the user from withdrawing all the way to the maintenance margin
so that they couldn't be liquidated very soon afterwards if their position
goes against them even a little bit

in , validateMarginRequirement it uses gt which becomes true when both values are equal.

TradingAccountBranch:withdrawMargin
tradingAccount.validateMarginRequirement(requiredInitialMarginUsdX18, marginBalanceUsdX18, UD60x18_ZERO);
TradingAccount:validateMarginRequirement
// @audit requirdbalance >= marginbalance
if (requiredMarginUsdX18.add(totalFeesUsdX18).intoSD59x18().gt(marginBalanceUsdX18)) {
revert Errors.InsufficientMargin(
self.id,
marginBalanceUsdX18.intoInt256(),
requiredMarginUsdX18.intoUint256(),
totalFeesUsdX18.intoUint256()
);
}

Impact

high risk of user being liquidated.

Tools Used

manual review

Recommendations

use gte() instead of gt().

TradingAccount:validateMarginRequirement
// @audit requirdbalance >= marginbalance
if (requiredMarginUsdX18.add(totalFeesUsdX18).intoSD59x18().gte(marginBalanceUsdX18)) {
revert Errors.InsufficientMargin(
self.id,
marginBalanceUsdX18.intoInt256(),
requiredMarginUsdX18.intoUint256(),
totalFeesUsdX18.intoUint256()
);

Title

liquidation fee is not added when calculating LiquidationBranch:isLiquidatable

Summary

The LiquidationBranch:isLiquidatable function does not include the liquidation fee when determining if an account is liquidatable. The function only compares the required maintenance margin to the margin balance, which is inconsistent with the documented formula.

Vulnerability Details

The current implementation of the LiquidationBranch:isLiquidatable function does not match with the documentation. This function only computes the required maintenance margin to the margin balance, excluding the liquidation fee.

formula for calculating isLiquidatable in the documentation
$ isLiquidatable={ requiredMM+ liquidationFeeUsd ≥ marginBalanceUsd​ }$.

Impact

The function behavior does not match the documented formula.

Tools Used

manual review

Recommendations

add liquidationFeeUsdX18 to calculate isLiquidatable

Title

branches could be upgraded to empty addresses

Summary

Branches might be upgraded to empty addresses if the length of initializables and initializePayloads does not match the length of branchUpgrades.

Vulnerability Details

there is no check for the length sizes for initializables and initilaizePayloads.
if these two parameters are not equal to branchUpgrades the slots which are empty will initialize the empty addresses.

Impact

The contract might initialize branches incorrectly,which leads to incomplete upgrades.

Tools Used

manual review

Recommendations

add a validation step at the beginning of the upgrade function to ensure that all arrays have the same length.

require(
branchUpgrades.length == initializables.length &&
branchUpgrades.length == initializePayloads.length,
"Array lengths do not match"
);
Updates

Lead Judging Commences

inallhonesty Lead Judge
11 months ago
inallhonesty Lead Judge 11 months ago
Submission Judgement Published
Validated
Assigned finding tags:

Liquidation doesn't take the liquidation fee in consideration inside the isLiquidatable check

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.