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

```MathMasters::mulWad``` and ```MathMasters::mulWadUp``` stores ```MathMasters__MulWadFailed()``` at 0x40 memory location

Summary

The MathMasters::mulWad and MathMasters::mulWadUp functions loading error codes into memory space 0x40, which is conventionally used for the free memory pointer in Ethereum smart contracts (ref. solidity docs https://docs.soliditylang.org/en/latest/internals/layout_in_memory.html). This unconventional use of memory space and error handling in assembly poses potential vulnerabilities and risks.

Vulnerability Details

In Ethereum smart contracts, the memory space at 0x40 is conventionally used as a free memory pointer. This pointer indicates the start of the free memory area where new data can be stored during the execution of a contract. Solidity and the Ethereum Virtual Machine (EVM) rely on this convention for efficient memory management.

The provided Solidity functions mulWad and mulWadUp utilize inline assembly to perform arithmetic operations and handle errors. In the process of handling errors, these functions explicitly store an error code (0xbac65e5b) at memory space 0x40 using the mstore assembly instruction. This operation overwrites the free memory pointer with a hardcoded value, disregarding its original purpose.

/// @dev Equivalent to `(x * y) / WAD` rounded down.
function mulWad(uint256 x, uint256 y) internal pure returns (uint256 z) {
// @solidity memory-safe-assembly
assembly {
// Equivalent to `require(y == 0 || x <= type(uint256).max / y)`.
if mul(y, gt(x, div(not(0), y))) {
@> mstore(0x40, 0xbac65e5b) // `MathMasters__MulWadFailed()`.
revert(0x1c, 0x04)
}
z := div(mul(x, y), WAD)
}
}
/// @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)`.
if mul(y, gt(x, or(div(not(0), y), x))) {
@> mstore(0x40, 0xbac65e5b) // `MathMasters__MulWadFailed()`.
revert(0x1c, 0x04)
}
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))
}
}

Impact

  • Unpredictable Memory Allocation: Overwriting the free memory pointer disrupts the conventional memory management in Solidity contracts. Subsequent attempts to allocate memory (e.g., creating new variables, arrays, or structs) may result in unpredictable behavior, as they could overwrite existing data or fail due to incorrect assumptions about free memory space.

  • Contract Instability: The integrity and stability of the contract can be compromised. Functions that rely on proper memory allocation may not work as intended, leading to unexpected results or contract failure.

Example Scenario:
Imagine a contract that, after calling mulWad or mulWadUp, attempts to allocate memory for a new variable or data structure. Since the free memory pointer has been overwritten, the contract might allocate memory that overlaps with previously stored data, leading to data corruption or loss. This could affect critical contract functionalities, such as token transfers, voting mechanisms, or access controls, potentially leading to financial loss or compromised contract integrity.

Tools Used

Manual review

Recommendations

Avoid Overwriting 0x40. In this case can be used 0x00.

Updates

Lead Judging Commences

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

Wrong error storage

Support

FAQs

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