-
Notifications
You must be signed in to change notification settings - Fork 29
/
PrizeVaultInvariant.t.sol
69 lines (57 loc) · 2.92 KB
/
PrizeVaultInvariant.t.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
import { Test } from "forge-std/Test.sol";
import { PrizeVaultFuzzHarness, PrizeVault } from "./PrizeVaultFuzzHarness.sol";
/// @dev This contract runs tests in a scenario where the yield vault can never lose funds (strictly increasing).
contract PrizeVaultInvariant is Test {
PrizeVaultFuzzHarness public vaultHarness;
modifier useCurrentTime() {
vm.warp(vaultHarness.currentTime());
_;
}
function setUp() external virtual {
vaultHarness = new PrizeVaultFuzzHarness(1e5);
targetContract(address(vaultHarness));
// mint some initial yield (enough to cover the yield buffer)
vaultHarness.accrueYield(1e5);
}
function invariantAssetsCoverDebt() external useCurrentTime {
uint256 totalAssets = vaultHarness.vault().totalAssets();
uint256 totalDebt = vaultHarness.vault().totalDebt();
assertGe(totalAssets, totalDebt);
}
function invariantDebtAtLeastSupply() external useCurrentTime {
uint256 totalDebt = vaultHarness.vault().totalDebt();
uint256 totalSupply = vaultHarness.vault().totalSupply();
assertGe(totalDebt, totalSupply);
}
function invariantLiquidBalanceOfAssetsNoMoreThanAvailableYield() external useCurrentTime {
address asset = address(vaultHarness.underlyingAsset());
uint256 liquidBalance = vaultHarness.vault().liquidatableBalanceOf(asset);
uint256 availableYieldBalance = vaultHarness.vault().availableYieldBalance();
assertLe(liquidBalance, availableYieldBalance);
}
function invariantLiquidBalanceOfSharesNoMoreThanAvailableYield() external useCurrentTime {
address vault = address(vaultHarness.vault());
uint256 liquidBalance = vaultHarness.vault().liquidatableBalanceOf(vault);
uint256 availableYieldBalance = vaultHarness.vault().availableYieldBalance();
assertLe(liquidBalance, availableYieldBalance);
}
function invariantYieldFeeBalanceAlwaysClaimable() external useCurrentTime {
uint256 supplyLimit = type(uint96).max - vaultHarness.vault().totalSupply();
uint256 yieldFeeBalance = vaultHarness.vault().yieldFeeBalance();
assertLe(yieldFeeBalance, supplyLimit);
}
function invariantAllAssetsAccountedFor() external useCurrentTime {
PrizeVault vault = vaultHarness.vault();
uint256 totalAssets = vault.totalAssets();
uint256 totalDebt = vault.totalDebt();
uint256 currentYieldBuffer = vault.currentYieldBuffer();
uint256 availableYieldBalance = vault.availableYieldBalance();
uint256 totalAccounted = totalDebt + currentYieldBuffer + availableYieldBalance;
assertEq(totalAssets, totalAccounted);
// totalYieldBalance = currentYieldBuffer + availableYieldBalance
uint256 totalAccounted2 = totalDebt + vault.totalYieldBalance();
assertEq(totalAssets, totalAccounted2);
}
}