Part 2

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

`rebalanceVaultsAssets` has wrong implementation

Summary

The whole implementation of the rebalanceVaultsAssets is completely incorrect

Vulnerability Details

function rebalanceVaultsAssets(uint128[2] calldata vaultsIds) external onlyRegisteredSystemKeepers {
// prepare the data for executing the swap asset -> usdc
SwapExactInputSinglePayload memory swapCallData = SwapExactInputSinglePayload({
tokenIn: ctx.inDebtVaultCollateralAsset,
tokenOut: usdc,
amountIn: assetInputNative,
recipient: address(this) // deposit the usdc to the market making engine proxy
});
// approve the collateral token to the dex adapter and swap assets for USDC
IERC20(ctx.inDebtVaultCollateralAsset).approve(ctx.dexAdapter, assetInputNative);
dexSwapStrategy.executeSwapExactInputSingle(swapCallData);
// SD59x18 -> uint128 using zaros internal precision
uint128 usdDelta = depositAmountUsdX18.intoUint256().toUint128();
// important considerations:
// 1) all subsequent storge updates must use zaros internal precision
// 2) code implicitly assumes that 1 USD = 1 USDC
}

In the function we can see that the following steps are made:
1.It swaps the in-debt vault's assets for USDC using _convertAssetsToUsdc.
In some cases the swapped amount of collateral tokens may be enough to cover for the debt of the vault which is simular to the settleVaultsDebt
After that the following storage updates are made:

//
// deposits the USDC to the in-credit vault
1) inCreditVault.depositedUsdc += usdDelta;
// increase the in-credit vault's share of the markets realized debt
// as it has received the USDC and needs to settle it in the future
2) inCreditVault.marketsRealizedDebtUsd += usdDelta.toInt256().toInt128();
// withdraws the USDC from the in-debt vault
3) inDebtVault.depositedUsdc -= usdDelta;
// decrease the in-debt vault's share of the markets realized debt
// as it has transferred USDC to the in-credit vault
4) inDebtVault.marketsRealizedDebtUsd -= usdDelta.toInt256().toInt128();
// emit an event
emit LogRebalanceVaultsAssets(vaultsIds[0], vaultsIds[1], usdDelta);

Here in point 4) we can see that the debt of the vault will be decreased by the usd that the collateral purchased. After that in point 3) the depositedUsdc will actually be decreased which results in the getUnsettledRealizedDebt remaining the same for the in debt vault.
In point 1) and 2) the vault that is in credit receives some USDC that is subtracted from the deposited USDC in point(3). However as a result the in credit vault will also have the same unrealizedDebt.
After all these operations are completed both vaults will still have the same unsettled debt, however the inDebt vault will lose collateral.

Impact

Loss for the inDebt vault

Tools Used

Manual Review

Recommendations

rebalanceVaultsAssets should facilitate settlement of their credit and debt, while currently it is the same.

Updates

Lead Judging Commences

inallhonesty Lead Judge
7 months ago
inallhonesty Lead Judge 7 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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