Part 2

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

Insufficient Swap Output Check in settleVaultsDebt

Summary

The current implementation only checks if ctx.usdcOut == 0 after a swap operation. However, this is not a sufficient validation because a nonzero output does not necessarily mean the swap provided enough USDC to settle the debt. Instead, the output should be compared to the required USDC amount to ensure the vault has sufficient funds to cover its obligations.

Vulnerability Details

Affected Code Snippet

https://github.com/Cyfrin/2025-01-zaros-part-2/blob/35deb3e92b2a32cd304bf61d27e6071ef36e446d/src/market-making/branches/CreditDelegationBranch.sol#L457

if (ctx.usdcOut == 0) revert Errors.ZeroOutputTokens();

https://github.com/Cyfrin/2025-01-zaros-part-2/blob/35deb3e92b2a32cd304bf61d27e6071ef36e446d/src/market-making/branches/CreditDelegationBranch.sol#L510

if (ctx.assetOutAmount == 0) revert Errors.ZeroOutputTokens();

This check only verifies whether the output is exactly zero, but does not account for cases where the returned amount is nonzero yet insufficient to cover the unsettled debt.

  • The purpose of swapping vaultAsset to USDC is to obtain a specific amount of USDC to settle a debt. Therefore, instead of merely checking if usdcOut is nonzero, the protocol should ensure that the received USDC is sufficient to cover the debt.

  • Additionally, the protocol can internally estimate how much vaultAsset it should receive when swapping USDC. Using this expected amount as a threshold, rather than just checking for a zero output, would improve accuracy and prevent insufficient swaps.

Impact of the Bug

  • Debt may remain unsettled: If the swap does not provide enough USDC, the vault might still be unable to cover its obligations.

  • Insufficient slippage checks expose the protocol to price manipulation, leading to potential fund losses.

Suggested Fix

Instead of checking only if ctx.usdcOut == 0, we should compare it against the required amount of USDC:

uint256 requiredUsdcAmount = usdcCollateralConfig.convertSd59x18ToTokenAmount(ctx.vaultUnsettledRealizedDebtUsdX18.abs());
if (ctx.usdcOut < requiredUsdcAmount) {
revert Errors.InsufficientSwapOutput(); // New error to indicate under-settlement
}
Updates

Lead Judging Commences

inallhonesty Lead Judge 4 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.