Part 2

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

The amoutOut received after a swap will be wrong

Summary

Bad calculation of unsettled realized debt will incur in a bad total debt, that will ruin the swap since the amount that will be received by the user will be different from the expected amount out.

Vulnerability Details

/// @notice Returns the vault's total debt distributed from connected markets.
/// @dev Takes into account the unrealized debt, the unsettled (yet to be settled) realized debt and the usdc
/// credit deposited by markets.
/// @param self The vault storage pointer.
function getTotalDebt(Data storage self) internal view returns (SD59x18 totalDebtUsdX18) { // ok
totalDebtUsdX18 = getUnsettledRealizedDebt(self).add(sd59x18(self.marketsUnrealizedDebtUsd)); // ok
}
/// @notice Returns the vault's total unsettled debt in USD, taking into account both the markets' unrealized
/// debt, but yet to be settled, and the usdc deposits allocated to the vault.
/// @dev Note that only the vault's share of the markets' realized debt is taken into consideration for debt /
/// credit settlements. Unrealized debt isn't taken into account for this purpose until realized by the markets,
/// but it affects the vault's credit capacity and the conversion rate between index and underlying tokens.
/// @dev USDC deposits are considered a net credit taking part of the unsettled realized debt, as they're used to
/// back usd tokens and deducted during debt settlements. This is why we unary minus the deposited USDC value to
/// calculate the vault's total unsettled debt.
/// @param self The vault storage pointer.
/// @return unsettledRealizedDebtUsdX18 The vault's total unsettled debt in USD.
function getUnsettledRealizedDebt(Data storage self) // ok @audit code/comment mismatch unrealized/realized debt
internal // ok
view // ok
returns (SD59x18 unsettledRealizedDebtUsdX18) // ok
{
unsettledRealizedDebtUsdX18 = // ok
sd59x18(self.marketsRealizedDebtUsd).add(unary(ud60x18(self.depositedUsdc).intoSD59x18())); // ok
}

As we can see in the code snippet above: @notice Returns the vault's total unsettled debt in USD, taking into account both the markets' unrealized debt, but yet to be settled, and the usdc deposits allocated to the vault.````But what is really taken into account instead of unrealized debt is the realized debt as we can see in the code:````sd59x18(self.marketsRealizedDebtUsd).add(unary(ud60x18(self.depositedUsdc).intoSD59x18()));

Impact

There are several impacts linked to this issue that come from the use of these 2 view functions:

  • `getUnsettledRealizedDebt(...)`

  • `getTotalDebt(...)`

Impact:

  • Vaults debt might not be settled

  • The rebalancing of the vault might revert or be performed the wrong way

  • The swap amount out will be wrong since it uses `getTotalDebt(...)`

Tools Used

Manual review

Recommendations

Replace `marketsRealizedDebtUsd` with marketsUnrealizedDebtUsd

Updates

Lead Judging Commences

inallhonesty Lead Judge 3 months ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

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