You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
198 lines
8.0 KiB
Solidity
198 lines
8.0 KiB
Solidity
// SPDX-License-Identifier: MIT
|
|
pragma solidity >=0.8.0 <0.9.0;
|
|
|
|
import "../src/StdMath.sol";
|
|
import "../src/Test.sol";
|
|
|
|
contract StdMathTest is Test {
|
|
function testGetAbs() external {
|
|
assertEq(stdMath.abs(-50), 50);
|
|
assertEq(stdMath.abs(50), 50);
|
|
assertEq(stdMath.abs(-1337), 1337);
|
|
assertEq(stdMath.abs(0), 0);
|
|
|
|
assertEq(stdMath.abs(type(int256).min), (type(uint256).max >> 1) + 1);
|
|
assertEq(stdMath.abs(type(int256).max), (type(uint256).max >> 1));
|
|
}
|
|
|
|
function testGetAbs_Fuzz(int256 a) external {
|
|
uint256 manualAbs = getAbs(a);
|
|
|
|
uint256 abs = stdMath.abs(a);
|
|
|
|
assertEq(abs, manualAbs);
|
|
}
|
|
|
|
function testGetDelta_Uint() external {
|
|
assertEq(stdMath.delta(uint256(0), uint256(0)), 0);
|
|
assertEq(stdMath.delta(uint256(0), uint256(1337)), 1337);
|
|
assertEq(stdMath.delta(uint256(0), type(uint64).max), type(uint64).max);
|
|
assertEq(stdMath.delta(uint256(0), type(uint128).max), type(uint128).max);
|
|
assertEq(stdMath.delta(uint256(0), type(uint256).max), type(uint256).max);
|
|
|
|
assertEq(stdMath.delta(0, uint256(0)), 0);
|
|
assertEq(stdMath.delta(1337, uint256(0)), 1337);
|
|
assertEq(stdMath.delta(type(uint64).max, uint256(0)), type(uint64).max);
|
|
assertEq(stdMath.delta(type(uint128).max, uint256(0)), type(uint128).max);
|
|
assertEq(stdMath.delta(type(uint256).max, uint256(0)), type(uint256).max);
|
|
|
|
assertEq(stdMath.delta(1337, uint256(1337)), 0);
|
|
assertEq(stdMath.delta(type(uint256).max, type(uint256).max), 0);
|
|
assertEq(stdMath.delta(5000, uint256(1250)), 3750);
|
|
}
|
|
|
|
function testGetDelta_Uint_Fuzz(uint256 a, uint256 b) external {
|
|
uint256 manualDelta;
|
|
if (a > b) {
|
|
manualDelta = a - b;
|
|
} else {
|
|
manualDelta = b - a;
|
|
}
|
|
|
|
uint256 delta = stdMath.delta(a, b);
|
|
|
|
assertEq(delta, manualDelta);
|
|
}
|
|
|
|
function testGetDelta_Int() external {
|
|
assertEq(stdMath.delta(int256(0), int256(0)), 0);
|
|
assertEq(stdMath.delta(int256(0), int256(1337)), 1337);
|
|
assertEq(stdMath.delta(int256(0), type(int64).max), type(uint64).max >> 1);
|
|
assertEq(stdMath.delta(int256(0), type(int128).max), type(uint128).max >> 1);
|
|
assertEq(stdMath.delta(int256(0), type(int256).max), type(uint256).max >> 1);
|
|
|
|
assertEq(stdMath.delta(0, int256(0)), 0);
|
|
assertEq(stdMath.delta(1337, int256(0)), 1337);
|
|
assertEq(stdMath.delta(type(int64).max, int256(0)), type(uint64).max >> 1);
|
|
assertEq(stdMath.delta(type(int128).max, int256(0)), type(uint128).max >> 1);
|
|
assertEq(stdMath.delta(type(int256).max, int256(0)), type(uint256).max >> 1);
|
|
|
|
assertEq(stdMath.delta(-0, int256(0)), 0);
|
|
assertEq(stdMath.delta(-1337, int256(0)), 1337);
|
|
assertEq(stdMath.delta(type(int64).min, int256(0)), (type(uint64).max >> 1) + 1);
|
|
assertEq(stdMath.delta(type(int128).min, int256(0)), (type(uint128).max >> 1) + 1);
|
|
assertEq(stdMath.delta(type(int256).min, int256(0)), (type(uint256).max >> 1) + 1);
|
|
|
|
assertEq(stdMath.delta(int256(0), -0), 0);
|
|
assertEq(stdMath.delta(int256(0), -1337), 1337);
|
|
assertEq(stdMath.delta(int256(0), type(int64).min), (type(uint64).max >> 1) + 1);
|
|
assertEq(stdMath.delta(int256(0), type(int128).min), (type(uint128).max >> 1) + 1);
|
|
assertEq(stdMath.delta(int256(0), type(int256).min), (type(uint256).max >> 1) + 1);
|
|
|
|
assertEq(stdMath.delta(1337, int256(1337)), 0);
|
|
assertEq(stdMath.delta(type(int256).max, type(int256).max), 0);
|
|
assertEq(stdMath.delta(type(int256).min, type(int256).min), 0);
|
|
assertEq(stdMath.delta(type(int256).min, type(int256).max), type(uint256).max);
|
|
assertEq(stdMath.delta(5000, int256(1250)), 3750);
|
|
}
|
|
|
|
function testGetDelta_Int_Fuzz(int256 a, int256 b) external {
|
|
uint256 absA = getAbs(a);
|
|
uint256 absB = getAbs(b);
|
|
uint256 absDelta = absA > absB ? absA - absB : absB - absA;
|
|
|
|
uint256 manualDelta;
|
|
if ((a >= 0 && b >= 0) || (a < 0 && b < 0)) {
|
|
manualDelta = absDelta;
|
|
}
|
|
// (a < 0 && b >= 0) || (a >= 0 && b < 0)
|
|
else {
|
|
manualDelta = absA + absB;
|
|
}
|
|
|
|
uint256 delta = stdMath.delta(a, b);
|
|
|
|
assertEq(delta, manualDelta);
|
|
}
|
|
|
|
function testGetPercentDelta_Uint() external {
|
|
assertEq(stdMath.percentDelta(uint256(0), uint256(1337)), 1e18);
|
|
assertEq(stdMath.percentDelta(uint256(0), type(uint64).max), 1e18);
|
|
assertEq(stdMath.percentDelta(uint256(0), type(uint128).max), 1e18);
|
|
assertEq(stdMath.percentDelta(uint256(0), type(uint192).max), 1e18);
|
|
|
|
assertEq(stdMath.percentDelta(1337, uint256(1337)), 0);
|
|
assertEq(stdMath.percentDelta(type(uint192).max, type(uint192).max), 0);
|
|
assertEq(stdMath.percentDelta(0, uint256(2500)), 1e18);
|
|
assertEq(stdMath.percentDelta(2500, uint256(2500)), 0);
|
|
assertEq(stdMath.percentDelta(5000, uint256(2500)), 1e18);
|
|
assertEq(stdMath.percentDelta(7500, uint256(2500)), 2e18);
|
|
|
|
vm.expectRevert(stdError.divisionError);
|
|
stdMath.percentDelta(uint256(1), 0);
|
|
}
|
|
|
|
function testGetPercentDelta_Uint_Fuzz(uint192 a, uint192 b) external {
|
|
vm.assume(b != 0);
|
|
uint256 manualDelta;
|
|
if (a > b) {
|
|
manualDelta = a - b;
|
|
} else {
|
|
manualDelta = b - a;
|
|
}
|
|
|
|
uint256 manualPercentDelta = manualDelta * 1e18 / b;
|
|
uint256 percentDelta = stdMath.percentDelta(a, b);
|
|
|
|
assertEq(percentDelta, manualPercentDelta);
|
|
}
|
|
|
|
function testGetPercentDelta_Int() external {
|
|
assertEq(stdMath.percentDelta(int256(0), int256(1337)), 1e18);
|
|
assertEq(stdMath.percentDelta(int256(0), -1337), 1e18);
|
|
assertEq(stdMath.percentDelta(int256(0), type(int64).min), 1e18);
|
|
assertEq(stdMath.percentDelta(int256(0), type(int128).min), 1e18);
|
|
assertEq(stdMath.percentDelta(int256(0), type(int192).min), 1e18);
|
|
assertEq(stdMath.percentDelta(int256(0), type(int64).max), 1e18);
|
|
assertEq(stdMath.percentDelta(int256(0), type(int128).max), 1e18);
|
|
assertEq(stdMath.percentDelta(int256(0), type(int192).max), 1e18);
|
|
|
|
assertEq(stdMath.percentDelta(1337, int256(1337)), 0);
|
|
assertEq(stdMath.percentDelta(type(int192).max, type(int192).max), 0);
|
|
assertEq(stdMath.percentDelta(type(int192).min, type(int192).min), 0);
|
|
|
|
assertEq(stdMath.percentDelta(type(int192).min, type(int192).max), 2e18); // rounds the 1 wei diff down
|
|
assertEq(stdMath.percentDelta(type(int192).max, type(int192).min), 2e18 - 1); // rounds the 1 wei diff down
|
|
assertEq(stdMath.percentDelta(0, int256(2500)), 1e18);
|
|
assertEq(stdMath.percentDelta(2500, int256(2500)), 0);
|
|
assertEq(stdMath.percentDelta(5000, int256(2500)), 1e18);
|
|
assertEq(stdMath.percentDelta(7500, int256(2500)), 2e18);
|
|
|
|
vm.expectRevert(stdError.divisionError);
|
|
stdMath.percentDelta(int256(1), 0);
|
|
}
|
|
|
|
function testGetPercentDelta_Int_Fuzz(int192 a, int192 b) external {
|
|
vm.assume(b != 0);
|
|
uint256 absA = getAbs(a);
|
|
uint256 absB = getAbs(b);
|
|
uint256 absDelta = absA > absB ? absA - absB : absB - absA;
|
|
|
|
uint256 manualDelta;
|
|
if ((a >= 0 && b >= 0) || (a < 0 && b < 0)) {
|
|
manualDelta = absDelta;
|
|
}
|
|
// (a < 0 && b >= 0) || (a >= 0 && b < 0)
|
|
else {
|
|
manualDelta = absA + absB;
|
|
}
|
|
|
|
uint256 manualPercentDelta = manualDelta * 1e18 / absB;
|
|
uint256 percentDelta = stdMath.percentDelta(a, b);
|
|
|
|
assertEq(percentDelta, manualPercentDelta);
|
|
}
|
|
|
|
/*//////////////////////////////////////////////////////////////////////////
|
|
HELPERS
|
|
//////////////////////////////////////////////////////////////////////////*/
|
|
|
|
function getAbs(int256 a) private pure returns (uint256) {
|
|
if (a < 0) {
|
|
return a == type(int256).min ? uint256(type(int256).max) + 1 : uint256(-a);
|
|
}
|
|
|
|
return uint256(a);
|
|
}
|
|
}
|