The calculateSwapAmount function in CreditDelegationBranch::settleVaultsDebt will return zero when tokenIn is an asset and tokenOut is USDC. This issue arises because the vault debt in USD is first converted to USDC’s decimal precision (6 decimals) and this small value then gets processed by getExpectedOutput, leading to a zero return value. This prevents swaps from executing properly, resulting in failure when settling vaults' debt.
The issue occurs in the else section of settleVaultsDebt:
vaultUnsettledRealizedDebtUsdX18 is sent in 6 decimals by passing through usdcCollateralConfig.convertSd59x18ToTokenAmount
The calculateSwapAmount function calls getExpectedOutput, where the 6 decimals value is converted to 18 decimals:
But if the tokenIn is a 18 decimals token, amountInX18 will be same as amountIn, since convertTokenAmountToUd60x18 returns the same value when token decimal is same as system decimal
Next, expectedAmountOut is calculated from the 6 decimals amountInX18:
The calculation: amountInX18.mul(priceTokenInX18).div(priceTokenOutX18) will return a 6 decimal value, but when it is passed to convertUd60x18ToTokenAmount to convert it to token decimals, it will return zero. Since tokenOut decimal is 6, the input of convertUd60x18ToTokenAmount will be divided by 1^12 and will return zero.
After that, this will revert due to the check in getExpectedOutput:
This will prevent the swap from happening
The vault cannot settle its credit position properly, leading to failed transactions.
The system will not be able to back it's usd token
Manual code review
Convert the vaultUnsettledRealizedDebtUsdX18 to amount of asset using a price oracle before passing it to getExpectedOutput
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.