-
Notifications
You must be signed in to change notification settings - Fork 20
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: add blue tests #134
base: main
Are you sure you want to change the base?
test: add blue tests #134
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.0; | ||
|
||
import "../../src/adaptive-curve-irm/interfaces/IAdaptiveCurveIrm.sol"; | ||
import "../../src/fixed-rate-irm/interfaces/IFixedRateIrm.sol"; | ||
|
||
import {IMorpho, MarketParams} from "../../lib/morpho-blue/src/interfaces/IMorpho.sol"; | ||
import {MathLib} from "../../lib/morpho-blue/src/libraries/MathLib.sol"; | ||
import {MarketParamsLib} from "../../lib/morpho-blue/src/libraries/MarketParamsLib.sol"; | ||
import {ORACLE_PRICE_SCALE} from "../../lib/morpho-blue/src/libraries/ConstantsLib.sol"; | ||
|
||
import "../../lib/forge-std/src/Test.sol"; | ||
import {ERC20Mock} from "../../lib/morpho-blue/src/mocks/ERC20Mock.sol"; | ||
import {OracleMock} from "../../lib/morpho-blue/src/mocks/OracleMock.sol"; | ||
|
||
contract BlueTest is Test { | ||
using MathLib for uint256; | ||
using MarketParamsLib for MarketParams; | ||
|
||
event BorrowRateUpdate(Id indexed id, uint256 avgBorrowRate, uint256 rateAtTarget); | ||
|
||
uint256 internal constant MIN_TEST_AMOUNT = 100; | ||
uint256 internal constant MAX_TEST_AMOUNT = 1e28; | ||
uint256 internal constant MIN_TIME_ELAPSED = 10; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why do we need this? |
||
uint256 internal constant MAX_TIME_ELAPSED = 315360000; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. where dois this value come from? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. for There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i think we can just use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. you can write |
||
uint256 internal constant DEFAULT_TEST_LLTV = 0.8 ether; | ||
|
||
address internal OWNER = makeAddr("Owner"); | ||
address internal SUPPLIER = makeAddr("Supplier"); | ||
address internal BORROWER = makeAddr("Borrower"); | ||
|
||
IMorpho internal morpho = IMorpho(deployCode("Morpho.sol", abi.encode(OWNER))); | ||
ERC20Mock internal loanToken; | ||
ERC20Mock internal collateralToken; | ||
OracleMock internal oracle; | ||
|
||
IAdaptiveCurveIrm internal adaptiveCurveIrm = | ||
IAdaptiveCurveIrm(deployCode("AdaptiveCurveIrm.sol", abi.encode(address(morpho)))); | ||
IFixedRateIrm public fixedRateIrm = IFixedRateIrm(deployCode("FixedRateIrm.sol")); | ||
Comment on lines
+37
to
+39
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can't we instead have one test that tests with all the IRMs (not sure how to do this) , and all their configs (That is why I was more thinking about doing some formal verification here, maybe with halmos?) ? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What kind of properties you are thinking of @MathisGD ? For some of them I think fuzzing would be more appropriate because bounds are not "hardcoded". For example, if the fixed rate IRM has a given rate then we could check that, fuzzing the parameters, this is "more or less" the rate that borrowers get over time. This "more or less" is not formal and difficult to put in a specification. But it would not be difficult with fuzzing, just use |
||
|
||
function setUp() public { | ||
SUPPLIER = makeAddr("Supplier"); | ||
BORROWER = makeAddr("Borrower"); | ||
|
||
loanToken = new ERC20Mock(); | ||
vm.label(address(loanToken), "LoanToken"); | ||
|
||
collateralToken = new ERC20Mock(); | ||
vm.label(address(collateralToken), "CollateralToken"); | ||
|
||
oracle = new OracleMock(); | ||
|
||
oracle.setPrice(ORACLE_PRICE_SCALE); | ||
|
||
vm.startPrank(OWNER); | ||
morpho.enableIrm(address(adaptiveCurveIrm)); | ||
morpho.enableIrm(address(fixedRateIrm)); | ||
morpho.enableLltv(DEFAULT_TEST_LLTV); | ||
vm.stopPrank(); | ||
|
||
vm.prank(SUPPLIER); | ||
loanToken.approve(address(morpho), type(uint256).max); | ||
|
||
vm.startPrank(BORROWER); | ||
loanToken.approve(address(morpho), type(uint256).max); | ||
collateralToken.approve(address(morpho), type(uint256).max); | ||
vm.stopPrank(); | ||
} | ||
|
||
/* TESTS */ | ||
|
||
function testAdaptiveCurveIrm(uint256 amountSupplied, uint256 amountBorrowed, uint256 timeElapsed) public { | ||
amountSupplied = bound(amountSupplied, MIN_TEST_AMOUNT, MAX_TEST_AMOUNT); | ||
amountBorrowed = bound(amountBorrowed, MIN_TEST_AMOUNT, amountSupplied); | ||
timeElapsed = bound(timeElapsed, MIN_TIME_ELAPSED, MAX_TIME_ELAPSED); | ||
|
||
MarketParams memory marketParams = MarketParams( | ||
address(loanToken), address(collateralToken), address(oracle), address(adaptiveCurveIrm), DEFAULT_TEST_LLTV | ||
); | ||
morpho.createMarket(marketParams); | ||
|
||
loanToken.setBalance(SUPPLIER, amountSupplied); | ||
vm.prank(SUPPLIER); | ||
morpho.supply(marketParams, amountSupplied, 0, SUPPLIER, hex""); | ||
|
||
uint256 collateralAmount = amountBorrowed.wDivUp(DEFAULT_TEST_LLTV); | ||
collateralToken.setBalance(BORROWER, collateralAmount); | ||
|
||
vm.startPrank(BORROWER); | ||
morpho.supplyCollateral(marketParams, collateralAmount, BORROWER, hex""); | ||
morpho.borrow(marketParams, amountBorrowed, 0, BORROWER, BORROWER); | ||
vm.stopPrank(); | ||
|
||
vm.warp(timeElapsed); | ||
|
||
morpho.accrueInterest(marketParams); | ||
} | ||
|
||
function testFixedRateIrm(uint256 amountSupplied, uint256 amountBorrowed, uint256 fixedRate, uint256 timeElapsed) | ||
public | ||
{ | ||
amountSupplied = bound(amountSupplied, MIN_TEST_AMOUNT, MAX_TEST_AMOUNT); | ||
amountBorrowed = bound(amountBorrowed, MIN_TEST_AMOUNT, amountSupplied); | ||
fixedRate = bound(timeElapsed, 1, fixedRateIrm.MAX_BORROW_RATE()); | ||
timeElapsed = bound(timeElapsed, MIN_TIME_ELAPSED, MAX_TIME_ELAPSED); | ||
|
||
MarketParams memory marketParams = MarketParams( | ||
address(loanToken), address(collateralToken), address(oracle), address(fixedRateIrm), DEFAULT_TEST_LLTV | ||
); | ||
fixedRateIrm.setBorrowRate(marketParams.id(), fixedRate); | ||
morpho.createMarket(marketParams); | ||
|
||
loanToken.setBalance(SUPPLIER, amountSupplied); | ||
vm.prank(SUPPLIER); | ||
morpho.supply(marketParams, amountSupplied, 0, SUPPLIER, hex""); | ||
|
||
uint256 collateralAmount = amountBorrowed.wDivUp(DEFAULT_TEST_LLTV); | ||
collateralToken.setBalance(BORROWER, collateralAmount); | ||
|
||
vm.startPrank(BORROWER); | ||
morpho.supplyCollateral(marketParams, collateralAmount, BORROWER, hex""); | ||
morpho.borrow(marketParams, amountBorrowed, 0, BORROWER, BORROWER); | ||
vm.stopPrank(); | ||
|
||
vm.warp(timeElapsed); | ||
|
||
morpho.accrueInterest(marketParams); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It would make sense to test that the accrued intereste are in a certain range (approximate it very roughly). This is because forgetting the line |
||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
didn't we agree to only use the "import files technique" from now, which is more robust