Summary
In the current implementation the `rebalanceVaultsAssets` is very likely to revert due to an underflow of depositedUsdc
Vulnerability Details
The function will first check if the credit vault has more credit then the debt:\
SD59x18 depositAmountUsdX18 = inCreditVaultUnsettledRealizedDebtUsdX18.gt(
inDebtVaultUnsettledRealizedDebtUsdX18Abs
) ? inDebtVaultUnsettledRealizedDebtUsdX18Abs : inCreditVaultUnsettledRealizedDebtUsdX18;
If the debt is less than the credit then the whole debt will be used.
After that this amount is converted to the collateral token and swapped:
uint256 assetInputNative = IDexAdapter(ctx.dexAdapter).getExpectedOutput(
usdc,
ctx.inDebtVaultCollateralAsset,
Collateral.load(usdc).convertSd59x18ToTokenAmount(depositAmountUsdX18)
);
SwapExactInputSinglePayload memory swapCallData = SwapExactInputSinglePayload({
tokenIn: ctx.inDebtVaultCollateralAsset,
tokenOut: usdc,
amountIn: assetInputNative,
recipient: address(this)
});
IERC20(ctx.inDebtVaultCollateralAsset).approve(ctx.dexAdapter, assetInputNative);
dexSwapStrategy.executeSwapExactInputSingle(swapCallData);
>>> uint128 usdDelta = depositAmountUsdX18.intoUint256().toUint128();
After the swap is executed the following updates are performed:
inCreditVault.depositedUsdc += usdDelta;
inCreditVault.marketsRealizedDebtUsd += usdDelta.toInt256().toInt128();
inDebtVault.depositedUsdc -= usdDelta;
inDebtVault.marketsRealizedDebtUsd -= usdDelta.toInt256().toInt128();
However the depositedUsdc
is of uint type so it will revert whenever usdDelta
is more than the depositedUsdc
.
Impact
Some inDebt vaults cannot be rebalanced.
Tools Used
Manual Review
Recommendations