During the ERC20 token transfer, malicious contracts could re-enter the withdrawal function
https://github.com/Cyfrin/2024-10-sablier/blob/main/src/SablierFlow.sol#L772-#L880.
The potential reentrancy vulnerability exists due to the order of operations in the _withdraw function:
The function updates critical state variables (balance and aggregateBalance) before making the external call (token.safeTransfer).
Attack Sequence
Initial State:
Stream Balance: 100 tokens
Attacker calls withdraw for 50 tokens
Function Execution:
First call:
Checks pass (amount <= balance)
Updates balance (100 -> 50)
Calls safeTransfer
During safeTransfer:
4. Malicious contract re-enters _withdraw
5. Checks pass again (balance still shows 50)
6. Updates balance (50 -> 0)
7. Second transfer executes
Result:
Attacker withdraws 100 tokens when only 50 were available
This vulnerability allows a user to carry out double withdrawal of funds which leads to Incorrect balance tracking and Protocol fee manipulation.
Manual code review
use the Checks-Effects-Interactions Pattern and Implement ReentrancyGuard.
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.