Flow

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

`oneMVTScaled` is Incorrectly Scaled Inside the `SablierFlow::depletionTimeOf` function resulting in incorrect value of `oneMVTScaled`

Summary

The oneMVTScaled value that the protocol used inside of the SablierFlow::depletionTimeOf function is incorrectly scaled, which in turn means the protocol used the wrong oneMVTScaled value in doing the check inside SablierFlow::depletionTimeOfwhich is shown below. Here is the link https://github.com/sablier-labs/flow/blob/b01cc2daf6493ae792a858d6179facc6250403e2/src/SablierFlow.sol#L78 to the exact line of the code.

```
if (snapshotDebtScaled + _ongoingDebtScaledOf(streamId) >= balanceScaled + oneMVTScaled) {
return 0;
}
```

Vulnerability Details

The protocol checks if the depletionTimeOf of a stream should return the timestamp when the stream will be depleted or return 0 by checking if the totalDebtScaled of the stream at the time of checking is higher than or equal to the ScaledBalance of the stream plus oneMVTScaled This vulnerability arises when the SablierFlow::depletionTimeOffunction tries to get the value of oneMVTScaled by passing 1 into the Helpers::scaleAmount function. The Helpers::ScaleAmount function takes a value that is the decimal of the token you want to get oneMVTScaled for and returns the value with 18 decimals. The protocol uses the Helpers::ScaleAmount function in several parts of the SablierFlow.sol contract, and it works as expected, always returning the 18-decimal value of any number passed to it, but that is because the values are always in the token decimal form, which is not the case when the SablierFlow::depletionTimeOf calls the Helpers::ScaleAmount function passing 1 and as a result the Helper::ScaleAmount function returns 1e12 instead of 1e18 as the oneMVTScaled value.

The below is the Helpers::ScaleAmountfunction with its natspec comment explicitly saying that the function scale value from their token decimal to 18 decimals fixed-point number

/// @dev Scales the provided `amount` from token's decimals number to 18 decimals fixed-point number.
function scaleAmount(uint256 amount, uint8 decimals) internal pure returns (uint256) {
if (decimals == 18) {
return amount;
}
unchecked {
uint256 scaleFactor = 10 ** (18 - decimals);
return amount * scaleFactor;
}
}

Impact

This vulnerability will cause the SablierFlow::depletionTimeOf function to return 0 a little bit earlier than expected

Tools Used

Manual Review

Recommendations

1etokenDecimalshould be passed to the Helpers::ScaleAmountfunction when trying to get the scaled Minimum Value Transferable(oneMVTScaled) for a token instead of 1and like that the Helpers::ScaleAmountfunction will return an 18 decimal value as expected by the protocol.

Updates

Lead Judging Commences

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

Appeal created

engrpips Submitter
8 months ago
engrpips Submitter
8 months ago
engrpips Submitter
8 months ago
inallhonesty Lead Judge
8 months ago
inallhonesty Lead Judge 8 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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