Beginner FriendlyFoundry
100 EXP
View results
Submission Details
Severity: high
Valid

Unnecessary rounding adjustment in `mulWadUp` function

Summary

There is a rounding adjustment in the mulWadUp function, which appears to be unnecessary given the existing rounding logic. This additional rounding adjustment has been identified as the cause of an assertion failure during fuzz testing.

Vulnerability Details

In the mulWadUp function, the following code snippet is unnecessary:

if iszero(sub(div(add(z, x), y), 1)) {
x := add(x, 1)
}

This code attempts a rounding adjustment, but the existing rounding logic in the function effectively handles rounding up after the multiplication. The unnecessary adjustment is causing assertion failures during fuzz testing.

Impact

This unnecessary rounding adjustment is leading to assertion failures. However, in normal execution scenarios, it does not contribute to the correct functionality of the rounding process. Removing this unnecessary code will likely result in cleaner and more efficient code execution.

POC

  • Make sure to configure foundry.toml runs = 1000000

  • Run the fuzz test on original code and you will get this result

Failing tests:
Encountered 1 failing test in test/MathMasters.t.sol:MathMastersTest
[FAIL. Reason: assertion failed; counterexample: calldata=0xfb6ea94f00000000000000000000000000000000000000000002bfc66f73219d55eb3274000000000000000000000000000000000000000000015fe337b990ceaaf5993b args=[3323484123583475243233908 [3.323e24], 1661742061791737621616955 [1.661e24]]] testMulWadUpFuzz(uint256,uint256) (runs: 3979, μ: 895, ~: 1146)
  • Now remove/comment the unnecessary rounding code and run the fuzzer via cmd orge test --match-test testMulWadUpFuzz -vvvvv

Result:

Test result: ok. 1 passed; 0 failed; 0 skipped; finished in 65.07s
Ran 1 test suites: 1 tests passed, 0 failed, 0 skipped (1 total tests)

Tools Used

  • Foundry fuzzing

Recommendations

The following recommendations are provided:

Remove Unnecessary Rounding Adjustment:
The unnecessary rounding adjustment code should be removed from the mulWadUp function to streamline the logic and prevent assertion failures during fuzz testing.

/// @dev Equivalent to `(x * y) / WAD` rounded up.
function mulWadUp(uint256 x, uint256 y) internal pure returns (uint256 z) {
/// @solidity memory-safe-assembly
assembly {
// Equivalent to `require(y == 0 || x <= type(uint256).max / y)`.
//Overflow Check
if mul(y, gt(x, or(div(not(0), y), x))) {
// extra x in end? and what is or used for?
mstore(0x40, 0xbac65e5b) // `MathMasters__MulWadFailed()`.
revert(0x1c, 0x04)
}
// Rounding Adjustment
- if iszero(sub(div(add(z, x), y), 1)) { x := add(x, 1) }
z := add(iszero(iszero(mod(mul(x, y), WAD))), div(mul(x, y), WAD))
}
}
Updates

Lead Judging Commences

inallhonesty Lead Judge over 1 year ago
Submission Judgement Published
Validated
Assigned finding tags:

`mulWadUp` has an unnecessary line that makes the result wrong for some inputs

Support

FAQs

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