Flow

Sablier
FoundryDeFi
20,000 USDC
View results
Submission Details
Severity: high
Invalid

Inaccurate Handling of Uncovered Debt in _void Function

Summary

The _void function improperly manages the relationship between snapshot debt, ongoing debt, and uncovered debt, leading to potential inaccuracies in debt calculations and financial loss to the system

Vulnerability Details

https://github.com/Cyfrin/2024-10-sablier/blob/8a2eac7a916080f2022527408b004578b21c51d0/src/SablierFlow.sol#L728C5-L749C10

uint256 debtToWriteOff = _uncoveredDebtOf(streamId);
// If the stream is solvent, update the total debt normally.
if (debtToWriteOff == 0) {
uint256 ongoingDebtScaled = _ongoingDebtScaledOf(streamId);
if (ongoingDebtScaled > 0) {
// Effect: Update the snapshot debt by adding the ongoing debt.
_streams[streamId].snapshotDebtScaled += ongoingDebtScaled;
}
}
// If the stream is insolvent, write off the uncovered debt.
else {
// Effect: update the total debt by setting snapshot debt to the stream balance.
_streams[streamId].snapshotDebtScaled =
Helpers.scaleAmount({ amount: _streams[streamId].balance, decimals: _streams[streamId].tokenDecimals });
}

The code above is part of the function _void which attempts to set uncovered debt to zero when void function is called. From the technical docs, one of the invariants, specifically invariant number 16, inorder to void a stream, the uncovered debt must be set to 0.

Note that uncovered debt is total debt - balance, while total debt is snapshot debt + ongoing debt. In this code, when the system is insolvent, it attempts to write off the debt by setting the balance to snapshot debt. This will work if ongoing debt is zero so that total debt - balance becomes 0. How about when ongoing debt is not zero?

This is where the issue arrises. The function only takes care of the case where the system is solvent and the ongoing debt is not zero. BUT the current implementation does not consider when the system is insolvent and the ongoing debt is not zero. In that case, total debt will be greater than the snapshot debt which was set to the balance in the code. Eventually when total debt - balance is carried out, the result will not be zero. Hence, uncovered debt will not be zero.This could lead to a situation where uncovered debt remains, potentially allowing claims that exceed the actual available balance.

Impact

  1. This leads to a situation where the total debt remains inaccurately calculated, allowing for inconsistencies between what is owed and what can be withdrawn.

  2. Users potentially being able to withdraw funds beyond what is available.

  3. Invariant that the stream should not be set to isVoid without uncovered debt=0 being broken

  4. An attacker or malicious user could be able to steal funds.

Tools Used

Manual analysis

Recommendations

Implement a thorough check that ensures that uncovered debt is zero when the system is insolvent and ongoing debt is greater than 0, ensuring that the total debt accurately reflects the state of the stream.

Updates

Lead Judging Commences

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

Appeal created

pndukwo Submitter
9 months ago
inallhonesty Lead Judge
9 months ago
inallhonesty Lead Judge 9 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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