Sablier

Sablier
DeFiFoundry
53,440 USDC
View results
Submission Details
Severity: high
Invalid

Incorrect Order of Tranche Timestamps

Summary

The _create function does not ensure that tranches are sorted by their timestamps, and this is leading to incorrect streaming behavior if the tranches are unordered.

Vulnerability Details

The function is responsible for creating a new stream based on the provided parameters, including tranches here where is the vulnerable lines where the tranches are pushed into the storage array _tranches[streamId] without any validation on their order:

for (uint256 i = 0; i < trancheCount; ++i) {
_tranches[streamId].push(params.tranches[i]);
}
  • let’s say a scenario that how this bug can is arise let’s say Alice wants to create a stream to Bob with three tranches and the Tranches are provided out of order that timestamps not in ascending order

  • Tranche 1: Amount = 100, Timestamp = 1650000000

  • Tranche 2: Amount = 200, Timestamp = 1640000000 (Earlier than Tranche 1, out of order)

  • Tranche 3: Amount = 300, Timestamp = 1660000000

  • the Attack Vector occur as :

  • Alice calls createWithTimestamps to create a stream with these tranches.

  • The function _create is called internally, and the tranches are pushed into the _tranches mapping without checking the order.

  • This results in the contract storing tranches in the wrong order:
    • Tranche 2 (1640000000)
    • Tranche 1 (1650000000)
    • Tranche 3 (1660000000)

  • When Bob tries to withdraw the streamed amount, the calculation in _calculateStreamedAmount will be flawed, leading to incorrect fund releases.

  • as result Bob might receive funds prematurely or late.

this is from the docs:

  • The milestones must be sorted in ascending order. It’s not possible for the i-1th milestone to be greater than the ith milestone (given we are dealing with increasing monotonic functions).

Impact

Funds might be released incorrectly or locked indefinitely

Tools Used

Manual review

Recommendations

Need to Ensure tranches are sorted by their timestamps before storing them as an example :

for (uint256 i = 1; i < trancheCount; ++i) {
require(params.tranches[i - 1].timestamp <= params.tranches[i].timestamp, "Tranches must be sorted by timestamp");
}
for (uint256 i = 0; i < trancheCount; ++i) {
_tranches[streamId].push(params.tranches[i]);
}
Updates

Lead Judging Commences

inallhonesty Lead Judge about 1 year ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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