sherlock-audit / 2023-01-uxd-judging

3 stars 1 forks source link

yongkiws - calculating Fullmatch:: MulDiv avoiding Overflow/Underflow #433

Closed github-actions[bot] closed 1 year ago

github-actions[bot] commented 1 year ago

yongkiws

medium

calculating Fullmatch:: MulDiv avoiding Overflow/Underflow

Summary

An overflow/underflow happens when an arithmetic operation reaches the maximum or minimum size of a type. For instance if a number is stored in the uint8 type, it means that the number is stored in a 8 bits unsigned number ranging from 0 to 2^8-1. In computer programming, an integer overflow occurs when an arithmetic operation attempts to create a numeric value that is outside of the range that can be represented with a given number of bits – either larger than the maximum or lower than the minimum representable value. Arithmetic overflow refers to the phenomenon where the numbers stored in a variable are too large for the variable to handle. And underflow is the opposite, where the amount is too small for the variable to store and handle.

Vulnerability Detail

type uint256 ,uint256 can only store non-negative numbers from 0 to (2**256 -1), Since the current maximum possible amount that can be stored is (2**256 -1) for uint256, if we add 1 to it, making it (2**256), the variable overflows, causing it to reset to 0. Similarly, if the variable is set to 0 and the arithmetic function tries to modify the variable by subtracting 1, the variable underflows and becomes (2**256).

Impact

 function mulDiv(
        uint256 a,
        uint256 b,
        uint256 denominator
    ) internal pure returns (uint256 result) {
        // 512-bit multiply [prod1 prod0] = a * b
        // Compute the product mod 2**256 and mod 2**256 - 1
        // then use the Chinese Remainder Theorem to reconstruct
        // the 512 bit result. The result is stored in two 256
        // variables such that product = prod1 * 2**256 + prod0
        uint256 prod0; // Least significant 256 bits of the product
        uint256 prod1; // Most significant 256 bits of the product
        assembly {
            let mm := mulmod(a, b, not(0))
            prod0 := mul(a, b)
            prod1 := sub(sub(mm, prod0), lt(mm, prod0))
        }

        // Handle non-overflow cases, 256 by 256 division
        if (prod1 == 0) {
            require(denominator > 0);
            assembly {
                result := div(prod0, denominator)
            }
            return result;
        }

Code Snippet

contracts/libraries/FullMath.sol#L17-L109

    function mulDiv(

Tool used

Manual Review

Recommendation

consider calculations that can cause overflow/underflow in uint256 require rigorous validation and updating to the latest version to reduce some gas Mathemagic finale: muldiv