The adjustRatePerSecond function in the SablierFlow contract allows the sender to modify the ratePerSecond of a stream without any upper limit validation. There is no check to ensure that the newRatePerSecond is within safe and reasonable bounds. As a result, setting an excessively high ratePerSecond can lead to arithmetic overflows in functions that rely on this value, particularly during debt calculations. This can cause transactions to revert and also render the stream unusable for both the sender and the recipient.
The adjustRatePerSecond function lacks upper limit validation:
The _adjustRatePerSecond function directly assigns the new rate without validation:
The _ongoingDebtScaledOf function uses ratePerSecond in arithmetic operations:
Exploit Prerequisites:
The sender has control over a stream and can call adjustRatePerSecond. The sender intends to set an excessively high ratePerSecond.
The sender calls adjustRatePerSecond with a newRatePerSecond value that is extremely large.
Functions that calculate debt, such as _ongoingDebtScaledOf, attempt to compute elapsedTime * ratePerSecond.
If ratePerSecond is excessively high, this multiplication can exceed uint256 limits, causing an overflow.
Both sender and recipient are affected, as they cannot interact with the stream without encountering errors. The issue affects individual streams where the sender sets an excessive rate. Other streams and the overall protocol remain unaffected.
Manual Review
(1) Use SafeMath or Solidity's checked arithmetic to handle potential overflows gracefully. Catch overflows and provide meaningful error messages instead of allowing reverts without context.
Or,
(2) Introduce a cap on the ratePerSecond to prevent values that can cause overflows. The maximum value should be calculated based on the token's decimals and the maximum expected elapsed time.
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.