-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy pathBaseTest.sol
More file actions
162 lines (131 loc) · 6.42 KB
/
BaseTest.sol
File metadata and controls
162 lines (131 loc) · 6.42 KB
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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity ^0.8.0;
import "../lib/forge-std/src/Test.sol";
import "../lib/forge-std/src/console2.sol";
import {ERC20Mock} from "../src/mocks/ERC20Mock.sol";
import {IrmMock} from "../src/mocks/IrmMock.sol";
import {OracleMock} from "../src/mocks/OracleMock.sol";
import {MarketParams, IMorpho, Id} from "../lib/morpho-blue/src/interfaces/IMorpho.sol";
import {IOracle} from "../lib/morpho-blue/src/interfaces/IOracle.sol";
import {MarketParamsLib} from "../lib/morpho-blue/src/libraries/MarketParamsLib.sol";
import {ORACLE_PRICE_SCALE} from "../lib/morpho-blue/src/libraries/ConstantsLib.sol";
import {WAD, MathLib} from "../lib/morpho-blue/src/libraries/MathLib.sol";
import {UtilsLib} from "../lib/morpho-blue/src/libraries/UtilsLib.sol";
import {PreLiquidationParams, IPreLiquidation} from "../src/interfaces/IPreLiquidation.sol";
import {PreLiquidationFactory} from "../src/PreLiquidationFactory.sol";
contract BaseTest is Test {
using MarketParamsLib for MarketParams;
using MathLib for uint256;
address internal SUPPLIER = makeAddr("Supplier");
address internal BORROWER = makeAddr("Borrower");
address internal LIQUIDATOR = makeAddr("Liquidator");
address internal MORPHO_OWNER = makeAddr("MorphoOwner");
address internal MORPHO_FEE_RECIPIENT = makeAddr("MorphoFeeRecipient");
IMorpho internal MORPHO = IMorpho(deployCode("Morpho.sol", abi.encode(MORPHO_OWNER)));
ERC20Mock internal loanToken = new ERC20Mock("loan", "B", 18);
ERC20Mock internal collateralToken = new ERC20Mock("collateral", "C", 18);
OracleMock internal oracle = new OracleMock();
IrmMock internal irm = new IrmMock();
uint256 internal lltv = 0.8 ether; // 80%
MarketParams internal marketParams;
Id internal id;
uint256 internal minCollateral = 10 ** 18;
uint256 internal maxCollateral = 10 ** 24;
PreLiquidationFactory internal factory;
IPreLiquidation internal preLiquidation;
function setUp() public virtual {
vm.label(address(MORPHO), "Morpho");
vm.label(address(loanToken), "Loan");
vm.label(address(collateralToken), "Collateral");
vm.label(address(oracle), "Oracle");
vm.label(address(irm), "Irm");
oracle.setPrice(ORACLE_PRICE_SCALE);
irm.setApr(0.5 ether); // 50%.
vm.startPrank(MORPHO_OWNER);
MORPHO.enableIrm(address(irm));
MORPHO.setFeeRecipient(MORPHO_FEE_RECIPIENT);
MORPHO.enableLltv(lltv);
vm.stopPrank();
marketParams = MarketParams({
loanToken: address(loanToken),
collateralToken: address(collateralToken),
oracle: address(oracle),
irm: address(irm),
lltv: lltv
});
id = marketParams.id();
MORPHO.createMarket(marketParams);
vm.startPrank(SUPPLIER);
loanToken.approve(address(MORPHO), type(uint256).max);
vm.stopPrank();
vm.prank(BORROWER);
collateralToken.approve(address(MORPHO), type(uint256).max);
}
function boundPreLiquidationParameters(
PreLiquidationParams memory preLiquidationParams,
uint256 minPreLltv,
uint256 maxPreLltv,
uint256 minPreLCF,
uint256 maxPreLCF,
uint256 minPreLIF,
uint256 maxPreLIF,
address preLiqOracle
) internal pure returns (PreLiquidationParams memory) {
preLiquidationParams.preLltv = bound(preLiquidationParams.preLltv, minPreLltv, maxPreLltv);
preLiquidationParams.preLCF1 = bound(preLiquidationParams.preLCF1, minPreLCF, maxPreLCF);
preLiquidationParams.preLCF2 = bound(preLiquidationParams.preLCF2, preLiquidationParams.preLCF1, maxPreLCF);
preLiquidationParams.preLIF1 = bound(preLiquidationParams.preLIF1, minPreLIF, maxPreLIF);
preLiquidationParams.preLIF2 = bound(preLiquidationParams.preLIF2, preLiquidationParams.preLIF1, maxPreLIF);
preLiquidationParams.preLiquidationOracle = preLiqOracle;
return preLiquidationParams;
}
function _preparePreLiquidation(
PreLiquidationParams memory preLiquidationParams,
uint256 collateralAmount,
uint256 borrowAmount,
address liquidator
) internal {
preLiquidation = factory.createPreLiquidation(id, preLiquidationParams);
loanToken.mint(SUPPLIER, borrowAmount);
vm.prank(SUPPLIER);
if (borrowAmount > 0) {
MORPHO.supply(marketParams, borrowAmount, 0, SUPPLIER, hex"");
}
collateralToken.mint(BORROWER, collateralAmount);
vm.startPrank(BORROWER);
MORPHO.supplyCollateral(marketParams, collateralAmount, BORROWER, hex"");
if (borrowAmount > 0) {
MORPHO.borrow(marketParams, borrowAmount, 0, BORROWER, BORROWER);
}
MORPHO.setAuthorization(address(preLiquidation), true);
vm.stopPrank();
loanToken.mint(liquidator, type(uint128).max);
vm.prank(liquidator);
loanToken.approve(address(preLiquidation), type(uint256).max);
}
function _closeFactor(PreLiquidationParams memory preLiquidationParams, uint256 ltv)
internal
view
returns (uint256)
{
return (ltv - preLiquidationParams.preLltv).wDivDown(marketParams.lltv - preLiquidationParams.preLltv).wMulDown(
preLiquidationParams.preLCF2 - preLiquidationParams.preLCF1
) + preLiquidationParams.preLCF1;
}
function _preLIF(PreLiquidationParams memory preLiquidationParams, uint256 ltv) internal view returns (uint256) {
return (ltv - preLiquidationParams.preLltv).wDivDown(marketParams.lltv - preLiquidationParams.preLltv).wMulDown(
preLiquidationParams.preLIF2 - preLiquidationParams.preLIF1
) + preLiquidationParams.preLIF1;
}
function _getBorrowBounds(
PreLiquidationParams memory preLiquidationParams,
MarketParams memory _marketParams,
uint256 collateralAmount
) internal view returns (uint256, uint256, uint256) {
uint256 collateralPrice = IOracle(preLiquidationParams.preLiquidationOracle).price();
uint256 collateralQuoted = collateralAmount.mulDivDown(collateralPrice, ORACLE_PRICE_SCALE);
uint256 borrowPreLiquidationThreshold = collateralQuoted.wMulDown(preLiquidationParams.preLltv);
uint256 borrowLiquidationThreshold = collateralQuoted.wMulDown(_marketParams.lltv);
return (collateralQuoted, borrowPreLiquidationThreshold, borrowLiquidationThreshold);
}
}