The depletionTimeOf
function calculates stream insolvency timing through integer division of scaled token amounts by rate per second. While it attempts to handle non-exact divisions by adding one second for any remainder, this simplistic rounding mechanism falls short when dealing with significant remainders. The function's core calculation solvencyPeriod = solvencyAmount / ratePerSecond
represents a critical precision point where valuable streaming duration data can be lost through truncation, affecting the accuracy of stream timing predictions.
The precision loss issue in depletionTimeOf
centers on the division operation that calculates solvencyPeriod
:
https://github.com/Cyfrin/2024-10-sablier/blob/main/src/SablierFlow.sol#L57
While the code attempts to handle non-exact division by adding 1 to the period when there's a remainder, this crude rounding can be problematic when dealing with large rates or amounts. Consider:
The +1 compensation becomes inadequate when the remainder represents a significant portion of the rate, leading to materially incorrect depletion time calculations. This imprecision can cause streams to deplete earlier than the actual available funds would allow.
The precision loss in the depletion time calculation creates a systemic underestimation of stream durations, particularly pronounced with large amounts or non-standard rates. When integer division truncates significant remainders, adding a single second fails to adequately compensate for the lost precision. This means streams consistently report earlier depletion times than their actual token reserves would support, leading to premature settlement triggers and incorrect solvency assessments in integrated DeFi protocols. The cumulative effect ripples through any financial planning or risk assessment systems depending on accurate stream forecasting, potentially triggering unnecessary liquidations or missed streaming opportunities due to artificially shortened duration calculations.
The key improvement is implementing proper "round-to-nearest" logic instead of always rounding up for any remainder. When the remainder exceeds half the rate per second, we round up; otherwise, we round down. This provides more accurate depletion time calculations, particularly important for:
High-value streams where precision matters
Non-standard rates where remainders can be significant
Integration contracts requiring precise timing
For example, if solvencyAmount = 1000000
and ratePerSecond = 333333
, the old code would potentially underestimate by nearly a full period, while the new code makes a more informed rounding decision based on the actual size of the remainder relative to the rate.
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.