Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unit tests #274

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 2 additions & 9 deletions test/forge/BaseTest.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@ import "src/Blue.sol";
import {ERC20Mock as ERC20} from "src/mocks/ERC20Mock.sol";
import {OracleMock as Oracle} from "src/mocks/OracleMock.sol";
import {IrmMock as Irm} from "src/mocks/IrmMock.sol";
import {MathUtils} from "./helpers/MathUtils.sol";

contract BaseTest is Test {
contract BaseTest is Test, MathUtils {
using FixedPointMathLib for uint256;
using MarketLib for Market;

Expand Down Expand Up @@ -148,12 +149,4 @@ contract BaseTest is Test {
function neq(Market memory a, Market memory b) internal pure returns (bool) {
return (Id.unwrap(a.id()) != Id.unwrap(b.id()));
}

function max(uint256 a, uint256 b) internal pure returns (uint256) {
return a > b ? a : b;
}

function min(uint256 a, uint256 b) internal pure returns (uint256) {
return a < b ? a : b;
}
}
12 changes: 12 additions & 0 deletions test/forge/helpers/MathUtils.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;

abstract contract MathUtils {
function max(uint256 a, uint256 b) internal pure returns (uint256) {
return a > b ? a : b;
}

function min(uint256 a, uint256 b) internal pure returns (uint256) {
return a < b ? a : b;
}
}
28 changes: 28 additions & 0 deletions test/forge/unit/TestFixedPointMathLib.t.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;

import "forge-std/Test.sol";

import {WAD, FixedPointMathLib} from "src/libraries/FixedPointMathLib.sol";

contract UnitFixedPointMathLib is Test {
using FixedPointMathLib for uint256;

function testWTaylorCompounded(uint256 rate, uint256 timeElapsed) public {
// Assume rate is less than a ~500% APY. (~180% APR)
vm.assume(rate < (WAD / 20_000_000) && timeElapsed < 365 days);
uint256 result = rate.wTaylorCompounded(timeElapsed) + WAD;
uint256 toCompare = wPow(WAD + rate, timeElapsed);
assertLe(result, toCompare, "rate should be less than the compounded rate");
assertGe(result, WAD + timeElapsed * rate, "rate should be greater than the simple interest rate");
assertLe((toCompare - result) * 100_00 / toCompare, 8_00, "The error should be less than or equal to 8%");
}

function wPow(uint256 x, uint256 n) private pure returns (uint256 z) {
z = WAD;
for (; n != 0; n /= 2) {
z = n % 2 != 0 ? z.wMulUp(x) : z;
x = x.wMulUp(x);
}
}
}
51 changes: 51 additions & 0 deletions test/forge/unit/TestMarketLib.t.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;

import "forge-std/Test.sol";

import {Market, Id} from "src/interfaces/IBlue.sol";
import {MarketLib} from "src/libraries/MarketLib.sol";

contract UnitMarketLibTest is Test {
using MarketLib for Market;

function testMarketIdWithDifferentBorrowableAsset(Market memory market, address newBorrowableAsset) public {
vm.assume(market.borrowableAsset != newBorrowableAsset);
Id oldId = market.id();
market.borrowableAsset = newBorrowableAsset;
Id newId = market.id();
assertNotEq(Id.unwrap(oldId), Id.unwrap(newId));
}

function testMarketIdWithDifferentCollateralAsset(Market memory market, address newCollateralAsset) public {
vm.assume(market.collateralAsset != newCollateralAsset);
Id oldId = market.id();
market.collateralAsset = newCollateralAsset;
Id newId = market.id();
assertNotEq(Id.unwrap(oldId), Id.unwrap(newId));
}

function testMarketIdWithDifferentOracle(Market memory market, address newOracle) public {
vm.assume(market.oracle != newOracle);
Id oldId = market.id();
market.oracle = newOracle;
Id newId = market.id();
assertNotEq(Id.unwrap(oldId), Id.unwrap(newId));
}

function testMarketIdWithDifferentIrm(Market memory market, address newIrm) public {
vm.assume(market.irm != newIrm);
Id oldId = market.id();
market.irm = newIrm;
Id newId = market.id();
assertNotEq(Id.unwrap(oldId), Id.unwrap(newId));
}

function testMarketIdWithDifferentLltv(Market memory market, uint256 newLltv) public {
vm.assume(market.lltv != newLltv);
Id oldId = market.id();
market.lltv = newLltv;
Id newId = market.id();
assertNotEq(Id.unwrap(oldId), Id.unwrap(newId));
}
}
36 changes: 36 additions & 0 deletions test/forge/unit/TestUtilsLib.t.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;

import "forge-std/Test.sol";

import {UtilsLib} from "src/libraries/UtilsLib.sol";

contract UnitUtilsLibTest is Test {
function testZeroFloorSub(uint256 x, uint256 y) public {
assertEq(UtilsLib.zeroFloorSub(x, y), x > y ? x - y : 0);
}

function testExactlyOneZero(uint256 x, uint256 y) public {
assertEq(UtilsLib.exactlyOneZero(x, y), (x != 0 && y == 0) || (x == 0 && y != 0));
}

function testExactlyOneZeroBothZero() public {
assertFalse(UtilsLib.exactlyOneZero(0, 0));
}

function testExactlyOneZeroBothNonZero(uint256 x, uint256 y) public {
x = bound(x, 1, type(uint256).max);
y = bound(y, 1, type(uint256).max);
assertFalse(UtilsLib.exactlyOneZero(x, y));
}

function testExactlyOneZeroFirstIsZero(uint256 y) public {
y = bound(y, 1, type(uint256).max);
assertTrue(UtilsLib.exactlyOneZero(0, y));
}

function testExactlyOneZeroSecondIsZero(uint256 x) public {
x = bound(x, 1, type(uint256).max);
assertTrue(UtilsLib.exactlyOneZero(x, 0));
}
}