The _withdraw
function performs an invariant check that compares debt and balance differences using asymmetric scaling operations. The left side of the comparison undergoes two descaling operations while the right side uses raw values, potentially causing precision mismatches and assertion failures.
https://github.com/Cyfrin/2024-10-sablier/blob/8a2eac7a916080f2022527408b004578b21c51d0/src/SablierFlow.sol#L866
The assertion in the withdraw function checks the consistency between the change in total debt and the stream's balance after a withdrawal:
This assertion ensures that the change in total debt (totalDebt - _totalDebtOf(streamId)) should match the change in balance (balance - _streams[streamId].balance). However, the _totalDebtOf(streamId)
function introduces an additional descaling step which is prone to precision loss though minor, causing the assertion to fail under certain conditions.
Even a small discrepancy caused by rounding errors in the descaling process results in the assertion failing.
The failed assertion reverts the transaction
Potential denial of service for specific withdrawal amounts
Manual analysis
Add rounding tolerance
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.