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

Precision Loss in Multiplication `(mulWad)`

Summary:

The mulWad function in the provided Solidity code may exhibit precision loss during multiplication, especially when the inputs are close to the upper limit of type(uint256).max. This vulnerability could lead to unexpected rounding down of results.

Vulnerability Details:

The mulWad function utilizes fixed-point arithmetic by multiplying two unsigned integers (x and y) and subsequently dividing the result by a constant (WAD). Fixed-point arithmetic involves representing fractional numbers using integers by designating a specific number of decimal places. In this context, the WAD constant represents 1e18 (1 followed by 18 zeros), indicating that the calculations are meant to handle values with 18 decimal places.

The vulnerability arises when the inputs (x and y) approach the upper limit of the type(uint256).max. In Solidity, type(uint256).max represents the maximum value that can be stored in a uint256. When the multiplication of large inputs approaches this upper limit, the subsequent division by WAD might result in precision loss.

Precision loss occurs because the fixed-point arithmetic relies on the assumption that the multiplication result fits within the limits of a uint256. If the multiplication exceeds this limit, the division will truncate the result, leading to a loss of precision.

For instance, if x and y are sufficiently large such that their product exceeds type(uint256).max, the division by WAD may not accurately represent the intended fractional value, causing unexpected rounding down of the result. This imprecision could impact applications relying on accurate arithmetic calculations, especially in financial contexts where precise handling of token balances is crucial.

In summary, the vulnerability is characterized by potential precision loss during multiplication when dealing with large inputs, specifically near the upper limit of type(uint256).max. The consequences include inaccuracies in fixed-point arithmetic calculations, introducing the risk of miscalculations in financial or token-related operations.

POC

function mulWad(uint256 x, uint256 y) internal pure returns (uint256 z) {
assembly {
if mul(y, gt(x, div(not(0), y))) {
mstore(0x40, 0xbac65e5b) // `MathMasters__MulWadFailed()`.
revert(0x1c, 0x04)
}
z := div(mul(x, y), WAD)
}
}

Impact:

Precision loss during multiplication can lead to unexpected results, especially when dealing with large numbers. In financial applications, such as those using fixed-point arithmetic for token balances, this precision loss might result in inaccurate calculations, potentially affecting user balances or financial outcomes.

Tools Used:

  • Manual Code Review

  • Solidity Linter

Recommendations:

Consider implementing additional checks or adjustments to the algorithm to handle scenarios where the multiplication result approaches the upper limit. One approach could involve using SafeMath for multiplication operations or adding checks to identify potential precision loss before performing the multiplication.

SafeMath is used to perform the multiplication, and a check is added to ensure that the result remains unchanged after applying SafeMath. If the check fails, an exception is raised, providing more transparency about potential precision loss.

Updated

import "@openzeppelin/contracts/utils/math/SafeMath.sol";
function mulWad(uint256 x, uint256 y) internal pure returns (uint256 z) {
require(SafeMath.mul(x, y) / WAD == x * y / WAD, "MathMasters__MulWadFailed");
z := div(mul(x, y), WAD);
}
Updates

Lead Judging Commences

inallhonesty Lead Judge over 1 year ago
Submission Judgement Published
Invalidated
Reason: Too generic

Support

FAQs

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