Part 2

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

Missing Swap Strategy Length Validation in Asset Swap Path Configuration

Summary

The configure function in AssetSwapPath library accepts mismatched array lengths between assets and swap strategies, breaking the core assumption that each asset pair in the path needs exactly one swap strategy.

function configure(
Data storage self,
bool enabled,
address[] memory assets,
uint128[] memory dexSwapStrategyIds
) internal {
self.enabled = enabled;
self.assets = assets;
self.dexSwapStrategyIds = dexSwapStrategyIds;
}

Consider a swap path configuration:

assets = [sUSDe, USDe, USDC, WETH]
dexSwapStrategyIds = [3, 3] // Missing strategy for USDC→WETH

This misconfiguration causes failures in CreditDelegationBranch's debt settlement process.

This impacts protocol solvency and debt settlements through cascading failures in the core settlement mechanisms. When a settlement attempt fails in CreditDelegationBranch:

function settleVaultsDebt(uint256[] calldata vaultsIds) external onlyRegisteredSystemKeepers {
// Fails when trying to settle
ctx.usdcOut = _convertAssetsToUsdc(
vault.swapStrategy.usdcDexSwapStrategyId,
ctx.vaultAsset,
ctx.swapAmount,
vault.swapStrategy.usdcDexSwapPath,
address(this),
ctx.usdc
);

This failure prevents critical state updates in the vault. The vault's marketsRealizedDebtUsd remains unchanged, and crucially, the USDC backing for the engine isn't allocated through UsdTokenSwapConfig.load().usdcAvailableForEngine[vault.engine]. Assets become trapped in intermediate states within vaults, unable to complete their conversion to USDC.

The solvency impact further propagates through the market settlement system:

// In Market.sol
function settleCreditDeposit(Data storage self, address settledAsset, UD60x18 netUsdcReceivedX18) internal {
// Credit deposits remain unsettled
self.creditDeposits.remove(settledAsset);
// USDC per credit share isn't updated
UD60x18 addedUsdcPerCreditShareX18 = netUsdcReceivedX18.div(ud60x18(self.totalDelegatedCreditUsd));
self.usdcCreditPerVaultShare = ud60x18(self.usdcCreditPerVaultShare).add(addedUsdcPerCreditShareX18).intoUint128();

The failure to update USDC credit shares creates a systemic breakdown in collateralization. Markets become progressively undercollateralized as credit deposits remain unsettled. The USDC backing for USD tokens becomes insufficient, undermining the protocol's core stability mechanism. This disruption extends to vault credit capacity calculations and market auto-deleverage enforcement, ultimately compromising the protocol's ability to maintain accurate debt/credit ratios and proper collateralization levels.

Fix

function configure(
Data storage self,
bool enabled,
address[] memory assets,
uint128[] memory dexSwapStrategyIds
) internal {
require(
dexSwapStrategyIds.length == assets.length - 1,
"AssetSwapPath: strategy ids must match number of swaps"
);
self.enabled = enabled;
self.assets = assets;
self.dexSwapStrategyIds = dexSwapStrategyIds;
}
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.