The CreditDelegationBranch::settleVaultsDebt
function incorrectly determines whether a vault is in debt or credit due to an inverted conditional check. This issue causes incorrect asset swaps, leading to unintended fund movements and potential financial losses within the protocol.
The settleVaultsDebt
function evaluates whether a vault has unsettled debt using the following condition:
https://github.com/Cyfrin/2025-01-zaros-part-2/blob/35deb3e92b2a32cd304bf61d27e6071ef36e446d/src/market-making/branches/CreditDelegationBranch.sol#L436
Here, ctx.vaultUnsettledRealizedDebtUsdX18
represents the vault's unsettled realized debt in the system's internal precision format. The issue arises from the incorrect interpretation of the sign of vaultUnsettledRealizedDebtUsdX18
.
The getUnsettledRealizedDebt
function calculates the unsettled debt as follows:
https://github.com/Cyfrin/2025-01-zaros-part-2/blob/35deb3e92b2a32cd304bf61d27e6071ef36e446d/src/market-making/leaves/Vault.sol#L239
This formula can be broken down as:
Vault in Debt:
marketsRealizedDebtUsd = 100,000
depositedUsdc = 80,000
UnsettledRealizedDebt = 100,000 + (-80,000) = 20,000
The vault has 20,000 debt to settle, so the protocol should swap assets to USDC to cover this debt.
Vault in Credit:
marketsRealizedDebtUsd = 100,000
depositedUsdc = 120,000
UnsettledRealizedDebt = 100,000 + (-120,000) = -20,000
The vault has a 20,000 credit, so the protocol should swap USDC to assets.
Incorrect Asset Swaps:
A vault with positive vaultUnsettledRealizedDebtUsdX18
(actual debt) is incorrectly treated as having a surplus (credit), preventing proper debt settlement.
A vault with negative vaultUnsettledRealizedDebtUsdX18
(actual credit) is incorrectly treated as having debt, causing unnecessary swaps from USDC to assets.
Potential Financial Loss:
Failure to settle real debt create inconsistencies in the protocol’s accounting system, potentially affecting liquidity and solvency.
The root cause is the incorrect interpretation of the sign of vaultUnsettledRealizedDebtUsdX18
:
Positive Value: Indicates debt (realized debt exceeds USDC deposits).
Negative Value: Indicates credit (USDC deposits exceed realized debt).
The current implementation incorrectly treats a negative value as debt and a positive value as credit.
The condition should be updated to correctly distinguish between debt and credit:
This change ensures that:
If vaultUnsettledRealizedDebtUsdX18 > 0
, the vault is in debt and should swap assets to USDC.
If vaultUnsettledRealizedDebtUsdX18 < 0
, the vault is in credit and should swap USDC to assets.
marketRealizedDebt
SignThe marketRealizedDebt
value should always be positive when a vault is in debt. This is because the formula for calculating UnsettledRealizedDebt
is:
If marketsRealizedDebtUsd
were negative, the calculation would result in:
Given that depositedUsdc
is always positive (as it represents the amount of USDC deposited into the vault), this would lead to:
This would always result in a negative value, which does not make sense in the context of debt and credit calculations. For example:
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.