MorpheusAI

MorpheusAI
Foundry
22,500 USDC
View results
Submission Details
Severity: medium
Invalid

Misleading and incorrect implementation of `_divideCeil()` in `LinearDistributionIntervalDecrease.sol`

Summary

Misleading implementation of _divideCeil() in LinearDistributionIntervalDecrease.sol

Vulnerability Details

In LinearDistributionIntervalDecrease.sol, _divideCeil() function is used to round up the divide result as the name suggest. To be noted, ceil is primarily used to refer round up. However, the implementation does the opposite than the function is intended to. It round down the result instead of round up. This is due to incorrect implementation of _divideCeil().

function _divideCeil(uint256 a_, uint256 b_) private pure returns (uint256) {
return (a_ + b_ - 1) / b_;
}

consider a scenario,

a= 10 and b=5, then _divideCeil() will equate to (10+5-1)/5 = 2.8

which the function will return the final result as 2, Howver the return result is round down and not round up since 2.8 is returned as 2 here.

This implementation of _divideCeil() is extremely misleading, Therefore, i suggest to follow below implementation which is directly taken from openzeppelin.

function ceilDiv(uint256 a, uint256 b) private pure returns (uint256) {
if (b == 0) {
// Guarantee the same behavior as in a regular Solidity division.
return a / b;
}
// The following calculation ensures accurate ceiling division without overflow.
// Since a is non-zero, (a - 1) / b will not overflow.
// The largest possible result occurs when (a - 1) / b is type(uint256).max,
// but the largest value we can obtain is type(uint256).max - 1, which happens
// when a = type(uint256).max and b = 1.
unchecked {
return a == 0 ? 0 : (a - 1) / b + 1;
}
}

Now, consider similar scenario here and see the difference to understand clearly,

a= 10 and b=5, then ceilDiv() will equate to (10-1)/(5+1) = 9/6 = 1.5

which the ceilDiv() function will return the final result as 2 which is absolutely correct.

Impact

Incorrect implementation of _divideCeil() is misleading the return value. Function is designed for round up but it is returning round down result.

Tools Used

Manual review

Recommendations

Recommend to implement below function for divide ceil functionality i.e to round up.

function _divideCeil(uint256 a_, uint256 b_) private pure returns (uint256) {
+ if (b == 0) {
+ // Guarantee the same behavior as in a regular Solidity division.
+ return a / b;
+ }
+ // The following calculation ensures accurate ceiling division without overflow.
+ // Since a is non-zero, (a - 1) / b will not overflow.
+ // The largest possible result occurs when (a - 1) / b is type(uint256).max,
+ // but the largest value we can obtain is type(uint256).max - 1, which happens
+ // when a = type(uint256).max and b = 1.
+ unchecked {
+ return a == 0 ? 0 : (a - 1) / b + 1;
+ }
- return (a_ + b_ - 1) / b_;
}
Updates

Lead Judging Commences

inallhonesty Lead Judge over 1 year ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity
0xrizwan Submitter
over 1 year ago
inallhonesty Lead Judge
over 1 year ago
inallhonesty Lead Judge over 1 year ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

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