Flow

Sablier
FoundryDeFi
20,000 USDC
View results
Submission Details
Severity: medium
Invalid

Incorrect calculation when rate changes in _ongoingDebtScaledOf

Summary

Incorrect calculation when rate changes in _ongoingDebtScaledOf

Vulnerability Details

/// @dev Calculates the ongoing debt, as a 18-decimals fixed point number, accrued since last snapshot. Return 0 if
/// the stream is paused or `block.timestamp` is less than or equal to snapshot time.
function _ongoingDebtScaledOf(uint256 streamId) internal view returns (uint256) {
uint256 blockTimestamp = block.timestamp;
uint256 snapshotTime = _streams[streamId].snapshotTime;
uint256 ratePerSecond = _streams[streamId].ratePerSecond.unwrap();
// Check:if the rate per second is zero or the `block.timestamp` is less than the `snapshotTime`.
if (ratePerSecond == 0 || blockTimestamp <= snapshotTime) {
return 0;
}
uint256 elapsedTime;
// Safe to use unchecked because subtraction cannot underflow.
unchecked {
// Calculate time elapsed since the last snapshot.
elapsedTime = blockTimestamp - snapshotTime;
}
// Calculate the ongoing debt scaled accrued by multiplying the elapsed time by the rate per second.
return elapsedTime * ratePerSecond;
}

The function assumes a constant rate throughout the entire period from snapshotTime to block.timestamp. However, if there was a rate change during this period, the calculation will be incorrect because it:

  1. Only uses the current rate (_streams[streamId].ratePerSecond)

  2. Applies this rate to the entire period

  3. Ignores the historical rate that was active for part of the period

Time: [Start]---------------[End]

Rate: 100 tokens/second (constant)

Period: 100 seconds

Debt: 100 * 100 = 10,000 tokens

Time: [Start]-----[Rate Change]-----[End]

Rate: 100 tokens/s -> 200 tokens/s

Period: 50s at 100/s + 50s at 200/s

Expected: (50 * 100) + (50 * 200) = 15,000 tokens

Actual: 100s * 200 = 20,000 tokens (incorrect)

Impact

The total debt will be wrong if any rate changes occurred. Users might withdraw incorrect amounts. Protocol-wide accounting will be inaccurate

Tools Used

Manual Review

Recommendations

Track all rate changes in a period

Calculate debt separately for each sub-period

Sum up the total correctly accounting for different rates

Updates

Lead Judging Commences

inallhonesty Lead Judge
10 months ago
inallhonesty Lead Judge 10 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.