Flow

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

Stream Voiding Race Condition Leading to Excess Token Withdrawals

Summary

The `_void` function in SablierFlow.sol contains a race condition vulnerability where the total debt calculation and state updates are not atomic. This could allow a recipient to withdraw more tokens than intended during the voiding process.

Vulnerability Details

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

The debt calculation (`_uncoveredDebtOf`) and state updates are not atomic. So between the debt calculation and the stream being marked as voided, a recipient could do the following:

  • Notice the void transaction in the mempool

  • Front-run with a withdrawal

  • Get more tokens than they should receive based on the final debt calculation

The vulnerability could

  1. Stream has 100 tokens balance

  2. Sender initiates void transaction

  3. Recipient monitors mempool

  4. When void transaction is seen:

    • Recipient front-runs with withdrawal of current withdrawable amount

    • Void transaction completes with incorrect debt calculationoid transaction completes with incorrect debt calculation

    • More tokens are withdrawn than should be possible as a result

Impact

Allows unauthorized withdrawal of additional tokens and could drain stream balance beyond intended amount. This exploit requires only mempool monitoring, can be automated and no special permissions needed beyond being stream recipient.

- Affects any stream being voided
- Could lead to significant token loss

Tools Used

manual code review

Recommendations

Make Void workflow Atomic

function _void(uint256 streamId) internal {
// First mark stream as voided to prevent new withdrawals
_streams[streamId].isVoided = true;
// Then calculate and update debt
uint256 debtToWriteOff = _uncoveredDebtOf(streamId);
// ... snip...
}

As well consider adding a Withdrawal Lock During Void

Updates

Lead Judging Commences

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.