Part 2

Zaros
PerpetualsDEXFoundrySolidity
70,000 USDC
View results
Submission Details
Severity: high
Valid

Incorrect debt/credit determination in `settleVaultsDebt()`

Summary

The settleVaultsDebt() function incorrectly determines vault debt/credit status by using an inverted comparison operator leading to incorrect asset swaps.

Vulnerability Details

The issue exists in the following code where the debt/credit determination is reversed.

File: CreditDelegationBranch.sol
435: // if the vault is in debt, swap its assets to USDC
436: if (ctx.vaultUnsettledRealizedDebtUsdX18.lt(SD59x18_ZERO)) {
437: // get swap amount; both input and output in native precision
438: ctx.swapAmount = calculateSwapAmount(
439: dexSwapStrategy.dexAdapter,
440: ctx.usdc,
441: ctx.vaultAsset,
442: usdcCollateralConfig.convertSd59x18ToTokenAmount(ctx.vaultUnsettledRealizedDebtUsdX18.abs())
443: );
444:
...
478: } else {
479: // else vault is in credit, swap its USDC previously accumulated
480: // from market and vault deposits into its underlying asset
481:
482: // get swap amount; both input and output in native precision
483: ctx.usdcIn = calculateSwapAmount(
484: dexSwapStrategy.dexAdapter,
485: ctx.vaultAsset,
486: ctx.usdc,
487: usdcCollateralConfig.convertSd59x18ToTokenAmount(ctx.vaultUnsettledRealizedDebtUsdX18.abs())
488: );

As we can see from the comments, it considers the vault is in credit when the vault's realized debt is greater than zero.

The getUnsettledRealizedDebt() returns a negative vaule when the vault is in credit, and vice versa.

File: Vault.sol
239: function getUnsettledRealizedDebt(Data storage self)
240: internal
241: view
242: returns (SD59x18 unsettledRealizedDebtUsdX18)
243: {
244: unsettledRealizedDebtUsdX18 =
245: sd59x18(self.marketsRealizedDebtUsd).add(unary(ud60x18(self.depositedUsdc).intoSD59x18()));
246: }

However, the current implementation treats negative values as debt and positive values as credit, which is incorrect.

Impact

The incorrect debt/credit determination leads to wrong asset swaps causing unintended fund movements and potential financial losses.

Recommendations

Update the condition to use gt() instead of lt() to correctly identify debt versus credit positions.

Updates

Lead Judging Commences

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

settleVaultDebt functions in opposite direction because of `ctx.vaultUnsettledRealizedDebtUsdX18.lt(SD59x18_ZERO)` having an inversed comparator (should have been gt)

Support

FAQs

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