Part 2

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

Inverted Logic in `UsdTokenSwapConfig` Leading to Economic Instability

Summary

The protocol's price adjustment mechanism for USD-to-asset swaps contains a critical flaw in its market-making logic. When vaults hold excess collateral, users face higher prices (premiums) for asset withdrawals, while debt-laden vaults offer discounted prices - exactly opposite to sound market-making principles. This inverted pricing model creates a feedback loop where struggling vaults become more unstable through increased withdrawals, while healthy vaults accumulate unnecessary collateral.

Vulnerability Details

The fulfillSwap function in the protocol uses getAmountOfAssetOut to calculate swap outputs, which applies a premium/discount factor based on the vault's debt/TVL ratio. The current implementation in UsdTokenSwapConfig.getPremiumDiscountFactor() has inverted logic:

// Current implementation
premiumDiscountFactorX18 =
vaultDebtUsdX18.lt(SD59x18_ZERO) ? UD60x18_UNIT.sub(pdCurveYX18) : UD60x18_UNIT.add(pdCurveYX18);

In the current implementation, vaults with outstanding debt (debt > 0) have a factor calculated as UD60x18_UNIT + pdCurveYX18, which results in a value greater than 1. This means users receive more assets for their USD, creating an incentive to withdraw additional assets from already indebted vaults.

Conversely, when a vault has excess collateral (debt < 0), the factor is determined as UD60x18_UNIT - pdCurveYX18, resulting in a value less than 1. As a result, users receive fewer assets for their USD, discouraging the withdrawal of surplus collateral from overcollateralized vaults.

However, the intended behavior should be the opposite: when a vault is in debt (premium scenario), users should receive fewer assets per USD, effectively paying more USD per asset. In contrast, when a vault holds excess collateral (discount scenario), users should receive more assets per USD, allowing them to pay less USD per asset.

Impact

HIGH. The inverted premium and discount logic creates systemic risks:

  1. Indebted vaults become more indebted due to increased asset withdrawals

  2. Overcollateralized vaults accumulate excessive collateral

Tools Used

Manual Review

Recommendations

Reverse the premium and discount logic in getPremiumDiscountFactor():

// Corrected implementation
premiumDiscountFactorX18 =
vaultDebtUsdX18.lt(SD59x18_ZERO) ? UD60x18_UNIT.add(pdCurveYX18) : UD60x18_UNIT.sub(pdCurveYX18);
Updates

Lead Judging Commences

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

The getPremiumDiscountFactor() function applies premiums and discounts inversely to what would maintain protocol stability

Support

FAQs

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

Give us feedback!