Detailed description of the impact of this finding.
File: Math.sol
Function: mulDiv(uint256,uint256,uint256)
Location: Line 340-433
The function mulDiv in the Math.sol library uses the bitwise-xor operator ^ instead of the exponentiation operator **. This occurs at line 414 in the expression inv = (3 * denominator) ^ 2. This misuse of operators can lead to incorrect calculations and potentially severe arithmetic errors in smart contracts that rely on this function for mathematical operations.
Proof of Concept
Provide direct links to all referenced code in GitHub. Add screenshots, logs, or any other relevant proof that illustrates the concept.
The incorrect operator is used in the following line:
The correct implementation should use the exponentiation operator ** to raise the result of (3 * denominator) to the power of 2.
File Name: test/foundry/libraries/Maths.t.sol
Prerequisites:
1. Copy the solidity code below into the file and path: test/foundry/libraries/Maths.t.sol
2. Save the file.
3. Within terminal, in the panoptic root folder run forge test -vvvvv --match-contract MathsTest --fork-url "https://eth-mainnet.g.alchemy.com/v2/{Token}"
Please see POC below.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "ds-test/test.sol";
import "../../../contracts/libraries/Math.sol";
contract MathsTest is DSTest {
function testMulDivWithFailure() public {
// Values that typically cause failure due to incorrect operator
uint256 a = 123456789;
uint256 b = 987654321;
uint256 c = 2;
// Expected value with correct exponentiation
uint256 expected = (a * b) ** c;
// Actual value using the incorrect operator
uint256 actual = Math.mulDiv(a, b, c);
// Assert that the actual value does not match the expected value
assertEq(expected, actual, "The mulDiv function returned the incorrect value.");
}
}
forge test -vvvvv --match-contract MathsTest --fork-url "https://eth-mainnet.g.alchemy.com/v2/{Token}"
[⠊] Compiling...
No files changed, compilation skipped
Ran 1 test for test/foundry/libraries/Maths.t.sol:MathsTest
[FAIL. Reason: assertion failed] testMulDivWithFailure() (gas: 18701)
Logs:
Error: The mulDiv function returned the incorrect value.
Error: a == b not satisfied [uint]
Left: 14867566530049990397812181822702361
Right: 60966315556317634
Traces:
[18701] MathsTest::testMulDivWithFailure()
├─ emit log_named_string(key: "Error", val: "The mulDiv function returned the incorrect value.")
├─ emit log(val: "Error: a == b not satisfied [uint]")
├─ emit log_named_uint(key: " Left", val: 14867566530049990397812181822702361 [1.486e34])
├─ emit log_named_uint(key: " Right", val: 60966315556317634 [6.096e16])
├─ [0] VM::store(VM: [0x7109709ECfa91a80626fF3989D68f67F5b1DD12D], 0x6661696c65640000000000000000000000000000000000000000000000000000, 0x0000000000000000000000000000000000000000000000000000000000000001)
│ └─ ← [Return]
└─ ← [Stop]
Suite result: FAILED. 0 passed; 1 failed; 0 skipped; finished in 1.04s (155.00ms CPU time)
Ran 1 test suite in 2.18s (1.04s CPU time): 0 tests passed, 1 failed, 0 skipped (1 total tests)
Failing tests:
Encountered 1 failing test in test/foundry/libraries/Maths.t.sol:MathsTest
[FAIL. Reason: assertion failed] testMulDivWithFailure() (gas: 18701)
Encountered a total of 1 failing tests, 0 tests succeeded
This test will import the Math.sol library and the DSTest contract from the Dappsys test library, which is commonly used in smart contract testing. The testMulDivWithFailure function calculates the expected value using the correct exponentiation operator ** and compares it to the actual value returned by the mulDiv function using the incorrect operator ^. If the values do not match, the test will fail, indicating that the mulDiv function needs to be corrected. And the test did indeed fail with incorrect matching values as depicted in the bash log above this.
Tools Used
Manual review, Slither and Foundry POC.
Recommended Mitigation Steps
Replace the bitwise-xor operator ^ with the exponentiation operator ** to correctly perform the power operation:
Lines of code
https://github.com/code-423n4/2024-06-panoptic/blob/153f0d82440b7e63075d55b0659706531431145f/contracts/libraries/Math.sol#L340-L433 https://github.com/code-423n4/2024-06-panoptic/blob/153f0d82440b7e63075d55b0659706531431145f/contracts/libraries/Math.sol#L414
Vulnerability details
Impact
Detailed description of the impact of this finding.
File: Math.sol
Function: mulDiv(uint256,uint256,uint256)
Location: Line 340-433
The function mulDiv in the Math.sol library uses the bitwise-xor operator
^
instead of the exponentiation operator**
. This occurs at line 414 in the expressioninv = (3 * denominator) ^ 2
. This misuse of operators can lead to incorrect calculations and potentially severe arithmetic errors in smart contracts that rely on this function for mathematical operations.Proof of Concept
Provide direct links to all referenced code in GitHub. Add screenshots, logs, or any other relevant proof that illustrates the concept.
The incorrect operator is used in the following line:
The correct implementation should use the exponentiation operator
**
to raise the result of (3*
denominator) to the power of 2.This test will import the Math.sol library and the DSTest contract from the Dappsys test library, which is commonly used in smart contract testing. The testMulDivWithFailure function calculates the expected value using the correct exponentiation operator ** and compares it to the actual value returned by the mulDiv function using the incorrect operator ^. If the values do not match, the test will fail, indicating that the mulDiv function needs to be corrected. And the test did indeed fail with incorrect matching values as depicted in the bash log above this.
Tools Used
Manual review, Slither and Foundry POC.
Recommended Mitigation Steps
Replace the
bitwise-xor
operator^
with the exponentiation operator**
to correctly perform the power operation:Assessed type
Math