building-secure-contracts icon indicating copy to clipboard operation
building-secure-contracts copied to clipboard

Error in learn_evm/arithmetic-checks.md : Arithmetic checks for int256 multiplication

Open Strapontin opened this issue 1 year ago • 1 comments

At this page : https://github.com/crytic/building-secure-contracts/blob/master/learn_evm/arithmetic-checks.md#arithmetic-checks-for-int256-multiplication

The first block of code is :

/// @notice versions >=0.8.0 && <0.8.17
function checkedMulInt(int256 a, int256 b) public pure returns (int256 c) {
    unchecked {
        c = a * b;

        if (a > 0 && b > 0 && a > type(int256).max / b) arithmeticError();
        if (a > 0 && b < 0 && a < type(int256).min / b) arithmeticError();
        if (a < 0 && b > 0 && a < type(int256).min / b) arithmeticError();
        if (a < 0 && b < 0 && a < type(int256).max / b) arithmeticError();
    }
}

There is an issue on the third condition that should be replaced :

/// @notice versions >=0.8.0 && <0.8.17
function checkedMulInt(int256 a, int256 b) public pure returns (int256 c) {
    unchecked {
        c = a * b;

        if (a > 0 && b > 0 && a > type(int256).max / b) arithmeticError();
        if (a > 0 && b < 0 && a < type(int256).min / b) arithmeticError();
-       if (a < 0 && b > 0 && a < type(int256).min / b) arithmeticError();
+       if (a < 0 && b > 0 && a > type(int256).min / b) arithmeticError();
        if (a < 0 && b < 0 && a < type(int256).max / b) arithmeticError();
    }
}

I discovered this issue while trying to use the code block for the solution of nodeGuardian's yul assembly quest.

Let me know if you need more details.

Strapontin avatar Sep 12 '24 16:09 Strapontin

I tested this with concrete examples and found the original code (<) appears correct:

a b Original (<) Proposed (>) Actual
-10 5 OK ✓ OVERFLOW ✗ No overflow
MIN/2 - 1 2 OVERFLOW ✓ OK ✗ Overflow

When a < 0 and b > 0, underflow occurs when a * b < MIN, which means a < MIN / b (dividing by positive preserves inequality).

The proposed > causes false positives and misses real overflows.

quan-tob avatar Nov 29 '25 22:11 quan-tob