DeFiFoundry
60,000 USDC
View results
Submission Details
Severity: medium
Invalid

Math.sol Violates the fundamental properties of Division of Numbers

Summary

The Math.sol violates the fundamental properties of division namely

  1. X divided by 1

  2. X divided by itself

  3. Division must be the inverse of multiplication

Vulnerability Details

The issues described are tested by Foundry and their respective responses by running the tests are attached

  1. X divided by 1 , division result should be X , but the library's output is different

emit val_with_caption(title=«expected », value=1)
emit val_with_caption(title=«actual », value=-1000000000000000000)
  1. X divided by itself , result should be 1

[FAIL. Reason: panic: assertion failed (0x01); counterexample: calldata=0x04a3de55fffffffffffffffffffffffffffffffffc071f3f639b4c849ff50fe923868d8c args=[-5279932128231207277076622544905794164 [-5.279e36]]] test_division_by_itself(int256) (runs: 0, μ: 0, ~: 0)
Traces:
[4720] TestMath::test_division_by_itself(-5279932128231207277076622544905794164 [-5.279e36])
├─ emit val_with_caption(title: "expected ", value: 1)
├─ emit val_with_caption(title: "actual ", value: 1000000000000000000 [1e18])
└─ ← [Revert] panic: assertion failed (0x01)
Suite result: FAILED. 0 passed; 1 failed; 0 skipped; finished in 29.70ms (15.36ms CPU time)
  1. Division and Multiplication must be inverses of each other i.e a/b = a*1/b

[FAIL. Reason: panic: assertion failed (0x01); counterexample: calldata=0x3059d84b0000000000000000000902b5efdb52f4d43faa240c42621aec5994db88b478a00000000007d981425ffc8b45e777767b3c99980c487f3cac139630f22a88b474 args=[863042931711616742395571839419341622713847975807056032 [8.63e53], 826662375564581815062914149040971734032835598727036180843706496116 [8.266e65]]] testFuzz_divide_mul_inv(int256,int256) (runs: 0, μ: 0, ~: 0)
Traces:
[9678] TestMath::testFuzz_divide_mul_inv(863042931711616742395571839419341622713847975807056032 [8.63e53], 826662375564581815062914149040971734032835598727036180843706496116 [8.266e65])
├─ [0] VM::assume(true) [staticcall]
│ └─ ← [Return]
├─ emit val_with_caption(title: "a/b ", value: 1044009 [1.044e6])
├─ emit val_with_caption(title: "a*1/b", value: 863042931711616742395571839419341622 [8.63e35])
└─ ← [Revert] panic: assertion failed (0x01)
Suite result: FAILED. 0 passed; 1 failed; 0 skipped; finished in 35.42ms (18.69ms CPU time)

But as we see , the attached bash responses , all the tests fail.

Here is the exact test file i've used

// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.25;
// PRB Math dependencies
import { UD60x18, ud60x18 } from "@prb-math/UD60x18.sol";
import { SD59x18, sd59x18 } from "@prb-math/SD59x18.sol";
import{Vm} from "forge-std/Vm.sol";
library Math {
function divUp(SD59x18 a, SD59x18 b) internal pure returns (SD59x18) {
return a.mod(b).isZero() ? a.div(b) : a.div(b).add(sd59x18(1));
}
function divUp(UD60x18 a, UD60x18 b) internal pure returns (UD60x18) {
return a.mod(b).isZero() ? a.div(b) : a.div(b).add(ud60x18(1));
}
function max(SD59x18 a, SD59x18 b) internal pure returns (SD59x18) {
return a.gt(b) ? a : b;
}
function max(UD60x18 a, UD60x18 b) internal pure returns (UD60x18) {
return a.gt(b) ? a : b;
}
function min(SD59x18 a, SD59x18 b) internal pure returns (SD59x18) {
return a.lt(b) ? a : b;
}
function min(UD60x18 a, UD60x18 b) internal pure returns (UD60x18) {
return a.lt(b) ? a : b;
}
}
contract TestMath {
using Math for SD59x18;
Vm private constant vm = Vm(address(uint160(uint256(keccak256("hevm cheat code")))));
constructor() {}
event val_with_caption(string title, SD59x18 value);
function test_division_by_1(SD59x18 a) external {
SD59x18 one=(sd59x18(1));
SD59x18 res = a.divUp(one);
emit val_with_caption('expected ',a);
emit val_with_caption('actual ',res);
assert(res==a);
}
function test_division_by_itself(SD59x18 a) external {
SD59x18 res = a.divUp(a);
emit val_with_caption('expected ',sd59x18(1));
emit val_with_caption('actual ',res);
assert(res==sd59x18(1));
}
function testFuzz_divide_mul_inv(SD59x18 a,SD59x18 b) external {
/**
*
* a/b = a*1/b
*/
vm.assume(b>sd59x18(0));
SD59x18 a_by_b = a.divUp(b);
SD59x18 one=sd59x18(1);
SD59x18 one_by_b = one.divUp(b);
emit val_with_caption('a/b ',a_by_b);
emit val_with_caption('a*1/b',a*one_by_b);
assert(a_by_b==a*one_by_b);
}
}

Impact

Incorrect calculation lead to jeopardizing the system as a whole

Tools Used

Foundry

Recommendations

Carefully examine these properties and make sure all of them hold

Updates

Lead Judging Commences

inallhonesty Lead Judge
11 months ago
inallhonesty Lead Judge 11 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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