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

test(foundry): fix invariant tests #68

Merged
merged 3 commits into from
Nov 13, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
12 changes: 10 additions & 2 deletions foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ out = "out"
test = "test"
libs = ["lib"]

[profile.default.fuzz]
runs = 4096
Rubilmax marked this conversation as resolved.
Show resolved Hide resolved
[profile.default.invariant]
fail_on_revert = true

[profile.default.fmt]
wrap_comments = true
Expand All @@ -20,5 +20,13 @@ script = "/dev/null"
[profile.test]
via-ir = false

[profile.test.fuzz]
runs = 8192

[profile.test.invariant]
runs = 32
depth = 1024
fail_on_revert = true


# See more config options https://github.com/foundry-rs/foundry/blob/master/crates/config/README.md#all-options
49 changes: 36 additions & 13 deletions test/SpeedJumpIrmTest.sol
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ contract AdaptativeCurveIrmTest is Test {

event BorrowRateUpdate(Id indexed id, uint256 avgBorrowRate, uint256 rateAtTarget);

int256 internal constant CURVE_STEEPNESS = 4 ether;
uint256 internal constant CURVE_STEEPNESS = 4 ether;
int256 internal constant ADJUSTMENT_SPEED = 50 ether / int256(365 days);
int256 internal constant TARGET_UTILIZATION = 0.9 ether;
uint256 internal constant INITIAL_RATE_AT_TARGET = 0.01 ether / uint256(365 days);
Expand All @@ -26,10 +26,17 @@ contract AdaptativeCurveIrmTest is Test {

function setUp() public {
irm =
new AdaptativeCurveIrm(address(this), uint256(CURVE_STEEPNESS), uint256(ADJUSTMENT_SPEED), uint256(TARGET_UTILIZATION), INITIAL_RATE_AT_TARGET);
new AdaptativeCurveIrm(address(this), CURVE_STEEPNESS, uint256(ADJUSTMENT_SPEED), uint256(TARGET_UTILIZATION), INITIAL_RATE_AT_TARGET);
vm.warp(90 days);

bytes4[] memory selectors = new bytes4[](1);
selectors[0] = AdaptativeCurveIrmTest.handleBorrowRate.selector;
targetSelector(FuzzSelector({addr: address(this), selectors: selectors}));
targetContract(address(this));
MathisGD marked this conversation as resolved.
Show resolved Hide resolved
}

/* TESTS */

function testDeployment() public {
vm.expectRevert(bytes(ErrorsLib.ZERO_ADDRESS));
new AdaptativeCurveIrm(address(0), 0, 0, 0, 0);
Expand Down Expand Up @@ -176,22 +183,37 @@ contract AdaptativeCurveIrmTest is Test {
MathLib.wExp(MathLib.WEXP_UPPER_BOUND).wMulDown(irm.MAX_RATE_AT_TARGET());
}

function invariantMinRateAtTarget() public {
/* HANDLERS */

function handleBorrowRate(uint256 totalSupplyAssets, uint256 totalBorrowAssets) external {
Rubilmax marked this conversation as resolved.
Show resolved Hide resolved
totalSupplyAssets = bound(totalSupplyAssets, 0, type(uint128).max);
totalBorrowAssets = bound(totalBorrowAssets, 0, totalSupplyAssets);

Market memory market;
market.totalBorrowAssets = uint128(totalSupplyAssets);
market.totalSupplyAssets = uint128(totalBorrowAssets);

irm.borrowRate(marketParams, market);
}

/* INVARIANTS */

function invariantGeMinRateAtTarget() public {
Market memory market;
market.totalBorrowAssets = 9 ether;
market.totalSupplyAssets = 10 ether;
assertGt(
irm.borrowRate(marketParams, market), uint256(int256(irm.MIN_RATE_AT_TARGET()).wDivDown(CURVE_STEEPNESS))
);

assertGe(irm.borrowRateView(marketParams, market), irm.MIN_RATE_AT_TARGET());
assertGe(irm.borrowRate(marketParams, market), irm.MIN_RATE_AT_TARGET());
Rubilmax marked this conversation as resolved.
Show resolved Hide resolved
}

function invariantMaxRateAtTarget() public {
function invariantLeMaxRateAtTarget() public {
Market memory market;
market.totalBorrowAssets = 9 ether;
market.totalSupplyAssets = 10 ether;
assertLt(
irm.borrowRate(marketParams, market), uint256(int256(irm.MAX_RATE_AT_TARGET()).wMulDown(CURVE_STEEPNESS))
);

assertLe(irm.borrowRateView(marketParams, market), irm.MAX_RATE_AT_TARGET());
assertLe(irm.borrowRate(marketParams, market), irm.MAX_RATE_AT_TARGET());
Rubilmax marked this conversation as resolved.
Show resolved Hide resolved
}

function _expectedRateAtTarget(Id id, Market memory market) internal view returns (uint256) {
Expand Down Expand Up @@ -229,12 +251,13 @@ contract AdaptativeCurveIrmTest is Test {
// Safe "unchecked" cast because err >= -1 (in WAD).
if (err < 0) {
return uint256(
(WAD_INT - WAD_INT.wDivDown(CURVE_STEEPNESS)).wMulDown(int256(rateAtTarget)).wMulDown(err)
(WAD_INT - WAD_INT.wDivDown(int256(CURVE_STEEPNESS))).wMulDown(int256(rateAtTarget)).wMulDown(err)
+ int256(rateAtTarget)
);
} else {
return
uint256((CURVE_STEEPNESS - WAD_INT).wMulDown(int256(rateAtTarget)).wMulDown(err) + int256(rateAtTarget));
return uint256(
(int256(CURVE_STEEPNESS) - WAD_INT).wMulDown(int256(rateAtTarget)).wMulDown(err) + int256(rateAtTarget)
);
}
}

Expand Down