Skip to content

Commit 3f73928

Browse files
committed
Merge branch 'dev' of github.com:morpho-labs/blue into feat/enable-lltv
2 parents c916251 + 0ceaeda commit 3f73928

File tree

7 files changed

+70
-113
lines changed

7 files changed

+70
-113
lines changed

.github/workflows/test.yml

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@ name: Foundry CI
33
on:
44
workflow_dispatch:
55
push:
6-
branches:
7-
- main
86
pull_request:
97

108
jobs:
@@ -20,16 +18,11 @@ jobs:
2018

2119
- name: Install Foundry
2220
uses: foundry-rs/foundry-toolchain@v1
23-
with:
24-
version: nightly
25-
26-
- name: Run Forge build
27-
run: |
28-
forge --version
29-
forge build --sizes
30-
id: build
3121

3222
- name: Run Forge tests
33-
run: |
34-
forge test -vvv
35-
id: test
23+
run: forge test -vvv
24+
env:
25+
FOUNDRY_FUZZ_RUNS: 100000
26+
FOUNDRY_FUZZ_MAX_TEST_REJECTS: 500000
27+
FOUNDRY_INVARIANT_RUNS: 1000
28+
FOUNDRY_INVARIANT_DEPTH: 100

foundry.toml

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,6 @@
11
[profile.default]
2-
src = "src"
3-
out = "out"
4-
libs = ["lib"]
52
via-ir = true
63

7-
[fuzz]
8-
runs = 2048
9-
10-
[invariant]
11-
runs = 2048
12-
depth = 32
13-
144
[fmt]
155
int_types = "short"
166

src/Blue.sol

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -250,8 +250,8 @@ contract Blue {
250250

251251
if (marketTotalSupply != 0) {
252252
uint marketTotalBorrow = totalBorrow[id];
253-
uint accruedInterests =
254-
marketTotalBorrow.wMul(market.irm.borrowRate(market)).wMul(block.timestamp - lastUpdate[id]);
253+
uint borrowRate = market.irm.borrowRate(market);
254+
uint accruedInterests = marketTotalBorrow.wMul(borrowRate).wMul(block.timestamp - lastUpdate[id]);
255255
totalSupply[id] = marketTotalSupply + accruedInterests;
256256
totalBorrow[id] = marketTotalBorrow + accruedInterests;
257257
}

src/Ownable.sol

Lines changed: 0 additions & 31 deletions
This file was deleted.

src/mocks/IrmMock.sol

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
// SPDX-License-Identifier: UNLICENSED
22
pragma solidity 0.8.20;
33

4-
import {IERC20} from "src/interfaces/IERC20.sol";
5-
import {IOracle} from "src/interfaces/IOracle.sol";
6-
74
import {MathLib} from "src/libraries/MathLib.sol";
85

96
import "src/Blue.sol";

test/forge/Blue.t.sol

Lines changed: 51 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@ import {IrmMock as Irm} from "src/mocks/IrmMock.sol";
1515
contract BlueTest is Test {
1616
using MathLib for uint;
1717

18-
address private constant borrower = address(1234);
19-
address private constant liquidator = address(5678);
20-
uint private constant lltv = 0.8 ether;
18+
address private constant BORROWER = address(1234);
19+
address private constant LIQUIDATOR = address(5678);
20+
uint private constant LLTV = 0.8 ether;
2121
address private constant OWNER = address(0xdead);
2222

2323
Blue private blue;
@@ -46,13 +46,13 @@ contract BlueTest is Test {
4646
borrowableOracle,
4747
collateralOracle,
4848
irm,
49-
lltv
49+
LLTV
5050
);
5151
id = Id.wrap(keccak256(abi.encode(market)));
5252

5353
vm.startPrank(OWNER);
5454
blue.enableIrm(irm);
55-
blue.enableLltv(lltv);
55+
blue.enableLltv(LLTV);
5656
blue.createMarket(market);
5757
vm.stopPrank();
5858

@@ -63,11 +63,11 @@ contract BlueTest is Test {
6363

6464
borrowableAsset.approve(address(blue), type(uint).max);
6565
collateralAsset.approve(address(blue), type(uint).max);
66-
vm.startPrank(borrower);
66+
vm.startPrank(BORROWER);
6767
borrowableAsset.approve(address(blue), type(uint).max);
6868
collateralAsset.approve(address(blue), type(uint).max);
6969
vm.stopPrank();
70-
vm.startPrank(liquidator);
70+
vm.startPrank(LIQUIDATOR);
7171
borrowableAsset.approve(address(blue), type(uint).max);
7272
collateralAsset.approve(address(blue), type(uint).max);
7373
vm.stopPrank();
@@ -104,7 +104,7 @@ contract BlueTest is Test {
104104
}
105105

106106
function invariantLltvEnabled() public {
107-
assertTrue(blue.isLltvEnabled(lltv));
107+
assertTrue(blue.isLltvEnabled(LLTV));
108108
}
109109

110110
// Tests
@@ -149,7 +149,7 @@ contract BlueTest is Test {
149149
}
150150

151151
function testCreateMarketWithEnabledIrm(Market memory marketFuzz) public {
152-
marketFuzz.lltv = lltv;
152+
marketFuzz.lltv = LLTV;
153153

154154
vm.startPrank(OWNER);
155155
blue.enableIrm(marketFuzz.irm);
@@ -191,7 +191,7 @@ contract BlueTest is Test {
191191
}
192192

193193
function testCreateMarketWithNotEnabledLltv(Market memory marketFuzz) public {
194-
vm.assume(marketFuzz.lltv != lltv);
194+
vm.assume(marketFuzz.lltv != LLTV);
195195
marketFuzz.irm = irm;
196196

197197
vm.prank(OWNER);
@@ -223,17 +223,17 @@ contract BlueTest is Test {
223223
}
224224

225225
if (amountBorrowed > amountLent) {
226-
vm.prank(borrower);
226+
vm.prank(BORROWER);
227227
vm.expectRevert("not enough liquidity");
228228
blue.borrow(market, amountBorrowed);
229229
return;
230230
}
231231

232-
vm.prank(borrower);
232+
vm.prank(BORROWER);
233233
blue.borrow(market, amountBorrowed);
234234

235-
assertEq(blue.borrowShare(id, borrower), 1e18, "borrow share");
236-
assertEq(borrowableAsset.balanceOf(borrower), amountBorrowed, "borrower balance");
235+
assertEq(blue.borrowShare(id, BORROWER), 1e18, "borrow share");
236+
assertEq(borrowableAsset.balanceOf(BORROWER), amountBorrowed, "BORROWER balance");
237237
assertEq(borrowableAsset.balanceOf(address(blue)), amountLent - amountBorrowed, "blue balance");
238238
}
239239

@@ -246,7 +246,7 @@ contract BlueTest is Test {
246246
borrowableAsset.setBalance(address(this), amountLent);
247247
blue.supply(market, amountLent);
248248

249-
vm.prank(borrower);
249+
vm.prank(BORROWER);
250250
blue.borrow(market, amountBorrowed);
251251

252252
if (amountWithdrawn > amountLent - amountBorrowed) {
@@ -285,20 +285,20 @@ contract BlueTest is Test {
285285
collateralOracle.setPrice(priceCollateral);
286286

287287
borrowableAsset.setBalance(address(this), amountBorrowed);
288-
collateralAsset.setBalance(borrower, amountCollateral);
288+
collateralAsset.setBalance(BORROWER, amountCollateral);
289289

290290
blue.supply(market, amountBorrowed);
291291

292-
vm.prank(borrower);
292+
vm.prank(BORROWER);
293293
blue.supplyCollateral(market, amountCollateral);
294294

295295
uint collateralValue = amountCollateral.wMul(priceCollateral);
296296
uint borrowValue = amountBorrowed.wMul(priceBorrowable);
297-
if (borrowValue == 0 || (collateralValue > 0 && borrowValue <= collateralValue.wMul(lltv))) {
298-
vm.prank(borrower);
297+
if (borrowValue == 0 || (collateralValue > 0 && borrowValue <= collateralValue.wMul(LLTV))) {
298+
vm.prank(BORROWER);
299299
blue.borrow(market, amountBorrowed);
300300
} else {
301-
vm.prank(borrower);
301+
vm.prank(BORROWER);
302302
vm.expectRevert("not enough collateral");
303303
blue.borrow(market, amountBorrowed);
304304
}
@@ -312,15 +312,15 @@ contract BlueTest is Test {
312312
borrowableAsset.setBalance(address(this), amountLent);
313313
blue.supply(market, amountLent);
314314

315-
vm.startPrank(borrower);
315+
vm.startPrank(BORROWER);
316316
blue.borrow(market, amountBorrowed);
317317
blue.repay(market, amountRepaid);
318318
vm.stopPrank();
319319

320320
assertApproxEqAbs(
321-
blue.borrowShare(id, borrower), (amountBorrowed - amountRepaid) * 1e18 / amountBorrowed, 1e3, "borrow share"
321+
blue.borrowShare(id, BORROWER), (amountBorrowed - amountRepaid) * 1e18 / amountBorrowed, 1e3, "borrow share"
322322
);
323-
assertEq(borrowableAsset.balanceOf(borrower), amountBorrowed - amountRepaid, "borrower balance");
323+
assertEq(borrowableAsset.balanceOf(BORROWER), amountBorrowed - amountRepaid, "BORROWER balance");
324324
assertEq(borrowableAsset.balanceOf(address(blue)), amountLent - amountBorrowed + amountRepaid, "blue balance");
325325
}
326326

@@ -360,83 +360,83 @@ contract BlueTest is Test {
360360
amountLent = bound(amountLent, 1000, 2 ** 64);
361361

362362
uint amountCollateral = amountLent;
363-
uint borrowingPower = amountCollateral.wMul(lltv);
363+
uint borrowingPower = amountCollateral.wMul(LLTV);
364364
uint amountBorrowed = borrowingPower.wMul(0.8e18);
365-
uint toSeize = amountCollateral.wMul(lltv);
366-
uint incentive = WAD + ALPHA.wMul(WAD.wDiv(lltv) - WAD);
365+
uint toSeize = amountCollateral.wMul(LLTV);
366+
uint incentive = WAD + ALPHA.wMul(WAD.wDiv(LLTV) - WAD);
367367

368368
borrowableAsset.setBalance(address(this), amountLent);
369-
collateralAsset.setBalance(borrower, amountCollateral);
370-
borrowableAsset.setBalance(liquidator, amountBorrowed);
369+
collateralAsset.setBalance(BORROWER, amountCollateral);
370+
borrowableAsset.setBalance(LIQUIDATOR, amountBorrowed);
371371

372372
// Supply
373373
blue.supply(market, amountLent);
374374

375375
// Borrow
376-
vm.startPrank(borrower);
376+
vm.startPrank(BORROWER);
377377
blue.supplyCollateral(market, amountCollateral);
378378
blue.borrow(market, amountBorrowed);
379379
vm.stopPrank();
380380

381381
// Price change
382382
borrowableOracle.setPrice(2e18);
383383

384-
uint liquidatorNetWorthBefore = netWorth(liquidator);
384+
uint liquidatorNetWorthBefore = netWorth(LIQUIDATOR);
385385

386386
// Liquidate
387-
vm.prank(liquidator);
388-
blue.liquidate(market, borrower, toSeize);
387+
vm.prank(LIQUIDATOR);
388+
blue.liquidate(market, BORROWER, toSeize);
389389

390-
uint liquidatorNetWorthAfter = netWorth(liquidator);
390+
uint liquidatorNetWorthAfter = netWorth(LIQUIDATOR);
391391

392392
uint expectedRepaid = toSeize.wMul(collateralOracle.price()).wDiv(incentive).wDiv(borrowableOracle.price());
393393
uint expectedNetWorthAfter = liquidatorNetWorthBefore + toSeize.wMul(collateralOracle.price())
394394
- expectedRepaid.wMul(borrowableOracle.price());
395-
assertEq(liquidatorNetWorthAfter, expectedNetWorthAfter, "liquidator net worth");
396-
assertApproxEqAbs(borrowBalance(borrower), amountBorrowed - expectedRepaid, 100, "borrower balance");
397-
assertEq(blue.collateral(id, borrower), amountCollateral - toSeize, "borrower collateral");
395+
assertEq(liquidatorNetWorthAfter, expectedNetWorthAfter, "LIQUIDATOR net worth");
396+
assertApproxEqAbs(borrowBalance(BORROWER), amountBorrowed - expectedRepaid, 100, "BORROWER balance");
397+
assertEq(blue.collateral(id, BORROWER), amountCollateral - toSeize, "BORROWER collateral");
398398
}
399399

400400
function testRealizeBadDebt(uint amountLent) public {
401401
borrowableOracle.setPrice(1e18);
402402
amountLent = bound(amountLent, 1000, 2 ** 64);
403403

404404
uint amountCollateral = amountLent;
405-
uint borrowingPower = amountCollateral.wMul(lltv);
405+
uint borrowingPower = amountCollateral.wMul(LLTV);
406406
uint amountBorrowed = borrowingPower.wMul(0.8e18);
407407
uint toSeize = amountCollateral;
408408
uint incentive = WAD + ALPHA.wMul(WAD.wDiv(market.lltv) - WAD);
409409

410410
borrowableAsset.setBalance(address(this), amountLent);
411-
collateralAsset.setBalance(borrower, amountCollateral);
412-
borrowableAsset.setBalance(liquidator, amountBorrowed);
411+
collateralAsset.setBalance(BORROWER, amountCollateral);
412+
borrowableAsset.setBalance(LIQUIDATOR, amountBorrowed);
413413

414414
// Supply
415415
blue.supply(market, amountLent);
416416

417417
// Borrow
418-
vm.startPrank(borrower);
418+
vm.startPrank(BORROWER);
419419
blue.supplyCollateral(market, amountCollateral);
420420
blue.borrow(market, amountBorrowed);
421421
vm.stopPrank();
422422

423423
// Price change
424424
borrowableOracle.setPrice(100e18);
425425

426-
uint liquidatorNetWorthBefore = netWorth(liquidator);
426+
uint liquidatorNetWorthBefore = netWorth(LIQUIDATOR);
427427

428428
// Liquidate
429-
vm.prank(liquidator);
430-
blue.liquidate(market, borrower, toSeize);
429+
vm.prank(LIQUIDATOR);
430+
blue.liquidate(market, BORROWER, toSeize);
431431

432-
uint liquidatorNetWorthAfter = netWorth(liquidator);
432+
uint liquidatorNetWorthAfter = netWorth(LIQUIDATOR);
433433

434434
uint expectedRepaid = toSeize.wMul(collateralOracle.price()).wDiv(incentive).wDiv(borrowableOracle.price());
435435
uint expectedNetWorthAfter = liquidatorNetWorthBefore + toSeize.wMul(collateralOracle.price())
436436
- expectedRepaid.wMul(borrowableOracle.price());
437-
assertEq(liquidatorNetWorthAfter, expectedNetWorthAfter, "liquidator net worth");
438-
assertEq(borrowBalance(borrower), 0, "borrower balance");
439-
assertEq(blue.collateral(id, borrower), 0, "borrower collateral");
437+
assertEq(liquidatorNetWorthAfter, expectedNetWorthAfter, "LIQUIDATOR net worth");
438+
assertEq(borrowBalance(BORROWER), 0, "BORROWER balance");
439+
assertEq(blue.collateral(id, BORROWER), 0, "BORROWER collateral");
440440
uint expectedBadDebt = amountBorrowed - expectedRepaid;
441441
assertGt(expectedBadDebt, 0, "bad debt");
442442
assertApproxEqAbs(supplyBalance(address(this)), amountLent - expectedBadDebt, 10, "lender supply balance");
@@ -449,14 +449,14 @@ contract BlueTest is Test {
449449
borrowableAsset.setBalance(address(this), firstAmount);
450450
blue.supply(market, firstAmount);
451451

452-
borrowableAsset.setBalance(borrower, secondAmount);
453-
vm.prank(borrower);
452+
borrowableAsset.setBalance(BORROWER, secondAmount);
453+
vm.prank(BORROWER);
454454
blue.supply(market, secondAmount);
455455

456456
assertApproxEqAbs(supplyBalance(address(this)), firstAmount, 100, "same balance first user");
457457
assertEq(blue.supplyShare(id, address(this)), 1e18, "expected shares first user");
458-
assertApproxEqAbs(supplyBalance(borrower), secondAmount, 100, "same balance second user");
459-
assertEq(blue.supplyShare(id, borrower), secondAmount * 1e18 / firstAmount, "expected shares second user");
458+
assertApproxEqAbs(supplyBalance(BORROWER), secondAmount, 100, "same balance second user");
459+
assertEq(blue.supplyShare(id, BORROWER), secondAmount * 1e18 / firstAmount, "expected shares second user");
460460
}
461461

462462
function testUnknownMarket(Market memory marketFuzz) public {

0 commit comments

Comments
 (0)