Flow

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

Risk of underflow in the `Helpers::scaleAmount` function, leading to theft of funds.

Relevant GitHub Links

https://github.com/sablier-labs/flow/blob/5b3e293c24f9bf50e73876d67b0981779e865300/src/libraries/Helpers.sol#L72

Summary

Funds can be stolen using the `Helpers::scaleAmount` function.

Vulnerability Details

When scaling the amount provided with the Helpers::scaleAmount function, the user may receive more funds than they are supposed to. In this line uint256 scaleFactor = 10 ** (18 - decimals), if decimals is greater than 18, the function will not revert because of the unchecked keyword. Instead of reverting, it will return an incorrect uint256 number instead of the negative number and continue execution with this incorrect 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;
}
}

For example: Suppose we call scaleAmount with:

  • amount = 5

  • decimals = 20

Here’s what happens:

  1. Calculation of Exponent: 18 - 20 = -2, so scaleFactor = 10 ** -2.

  2. Overflow Occurs: Solidity doesn’t support negative exponents in integer operations, so it interprets 10 ** -2 incorrectly, resulting in an extremely large number due to underflow in the exponentiation operation.

  3. Incorrect Scale Factor: The overflowed scaleFactor will hold a large, incorrect value, potentially leading to further overflow if we calculate amount * scaleFactor. If scaleFactor overflows to something like 2^256 - 1, multiplying it by amount will also overflow.

Impact

  • Loss of funds: Attackers might exploit an underflow if they can influence the input values, leading to unexpected or excessive tokens.

  • Unexpected Reverts or Errors: If the overflowed scaleFactor is used in calculations, it may produce nonsensical results or cause reverts in later calculations, especially when multiplied by another large number.

  • Possibly DOS

Tools Used

Manual analysis.

Recommendations

function scaleAmount(uint256 amount, uint8 decimals) internal pure returns (uint256) {
+ require(decimals <= 18, "Decimals exceed 18");
if (decimals == 18) {
return amount;
}
unchecked {
uint256 scaleFactor = 10 ** (18 - decimals);
return amount * scaleFactor;
}
}
Updates

Lead Judging Commences

inallhonesty Lead Judge
9 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.