The SablierFlow::depletionTimeOf
function calculates the time at which a stream will run out of funds. It does this by dividing the excess scaled balance by the ratePerSecond
to determine the number of remaining seconds. If the totalDebt
is greater than the streamBalance
, then depletionTime
should be zero.
However, an issue arises in a solvent stream (totalDebt < streamBalance
). If you adjust ratePerSecond
to a value greater than the current streamBalance
and then call depletionTimeOf
within the same block (using a batch operation), the depletionTime
will be incorrect. This results in an unrealistic number of seconds, likely returning either the snapshotTime
or snapshotTime + 1
instead. This happens because solvencyPeriod
becomes zero, as streamBalance
is divided by ratePerSecond
when streamBalance < ratePerSecond
:
At first glance, this issue might not seem significant, but when other protocols integrate with Sablier, it can become a major problem, as this type of data can be crucial in determining whether certain operations are allowed.
Incorrect depletionTime
value
Scenario:
Start timestamp: October-01-2024
Deposit: 50_000e6
Wrap 30 days: accrue some debt
In the same block:
Adjust rate: 100_000e18 tokens per second.
Call depletionTimeOf
: get incorrect value (should be 0)
Paste the following code in /tests/integration/concrete/adjust-rate-per-second/adjustRatePerSecond.t.sol
Before executing the test, paste this import at the beginning of the contract:
After calculating solvencyPeriod
, add a check to return zero if solvencyPeriod
is zero.
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.