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

Refactor testing suite #218

Merged
merged 72 commits into from
Aug 15, 2023
Merged
Show file tree
Hide file tree
Changes from 70 commits
Commits
Show all changes
72 commits
Select commit Hold shift + click to select a range
d073155
refactor: delete tests
makcandrov Aug 3, 2023
e8caf81
Revert "refactor: delete tests"
makcandrov Aug 3, 2023
ca0dbe2
fix: remove flashloan receiver
makcandrov Aug 3, 2023
c509d12
feat: add set authorization tests
Jean-Grimal Aug 3, 2023
60993fd
refactor: delete old tests
makcandrov Aug 3, 2023
47e7eb3
Merge branch 'feat/tests' of github.com:morpho-labs/blue into feat/tests
makcandrov Aug 3, 2023
6f2d1b4
Merge branch 'test/tree' into feat/tests
makcandrov Aug 3, 2023
4ce8f65
feat: add accrued interests integration tests
Jean-Grimal Aug 3, 2023
26a34c9
test: improve test borrow
makcandrov Aug 3, 2023
067a888
Merge branch 'test/tree' into feat/tests
makcandrov Aug 3, 2023
cb6e845
refactor: borrow and withdraw collateral tests
makcandrov Aug 4, 2023
2b17afa
refactor: withdraw tests
makcandrov Aug 4, 2023
baaeff8
refactor: testLiquidateHealthyPosition
makcandrov Aug 4, 2023
e29da38
style: format
makcandrov Aug 4, 2023
05e8d38
refactor: testLiquidateNoBadDebt
makcandrov Aug 4, 2023
0d5733d
refactor: testLiquidateBadDebt
makcandrov Aug 4, 2023
3e7bd88
style: formatting
makcandrov Aug 4, 2023
68515b1
Merge branch 'test/tree' into feat/tests
makcandrov Aug 4, 2023
0ba62c5
feat: add getter and callbacks integration tests
Jean-Grimal Aug 4, 2023
5549bac
feat: first events
makcandrov Aug 7, 2023
89deed3
feat: events
makcandrov Aug 7, 2023
a2b61c4
feat: test liquidate events
makcandrov Aug 7, 2023
72a73b2
Apply suggestions from code review
makcandrov Aug 8, 2023
8758178
style: harmonize comments and typo
makcandrov Aug 8, 2023
af92791
fix: clean BlueBase.t.sol
Jean-Grimal Aug 8, 2023
b23d478
refactor: more fuzz in borrow tests
makcandrov Aug 8, 2023
3cfaa2c
Merge branch 'feat/tests' of github.com:morpho-labs/blue into feat/tests
makcandrov Aug 8, 2023
ae363b6
fix: remove useless line
makcandrov Aug 8, 2023
6918dd9
fix: constant max test amount
Jean-Grimal Aug 8, 2023
5cf6f8f
refactor: create market tests
makcandrov Aug 8, 2023
3fc6e27
fix: fix conflicts
Jean-Grimal Aug 8, 2023
9fc4b95
feat: more fuzzing in test withdraw collateral
makcandrov Aug 8, 2023
e3a122a
Merge remote-tracking branch 'origin/feat/tests' into feat/tests
makcandrov Aug 8, 2023
dc3dba2
fix: exact borrow shares
makcandrov Aug 8, 2023
7b60fcc
fix: test total shares
makcandrov Aug 8, 2023
64cf487
feat: merge supply on behalf tests
makcandrov Aug 8, 2023
0eab3da
feat: more fuzzing in supply tests
makcandrov Aug 8, 2023
244c652
feat: labelled addresses
makcandrov Aug 8, 2023
a178fee
fix: apply suggestions
makcandrov Aug 8, 2023
f90fba7
style: rename files
makcandrov Aug 8, 2023
b8d11a7
style: use market lib to compute the id
makcandrov Aug 8, 2023
4698b51
fix: remove useless vm.assume
makcandrov Aug 8, 2023
1b29907
fix: rename unknown market to market not created
makcandrov Aug 8, 2023
a18d925
style: use the SECP256K1_ORDER constant
makcandrov Aug 9, 2023
e2b62fd
feat: invalid nonce and signature replay tests
makcandrov Aug 9, 2023
c50d042
style: string to address internal function
makcandrov Aug 9, 2023
edbba16
Merge branch 'test/tree' into feat/tests
makcandrov Aug 10, 2023
304cdb7
fix: comment and wad
makcandrov Aug 10, 2023
63f7a9f
style: format
makcandrov Aug 10, 2023
b35c265
feat: add supply and withdraw shares tests
Jean-Grimal Aug 10, 2023
4de662c
feat: warp in the set up
makcandrov Aug 11, 2023
3e4ca66
Merge branch 'main' into feat/tests
makcandrov Aug 11, 2023
5926858
fix: merge
makcandrov Aug 11, 2023
927d896
feat: add borrow and repay shares tests
Jean-Grimal Aug 11, 2023
e537bdf
Merge branch 'feat/tests' of github.com:morpho-labs/morpho-blue into …
Jean-Grimal Aug 11, 2023
781f80d
Delete Blue.t.sol
Jean-Grimal Aug 11, 2023
16f8cee
refactor: morpho naming
Jean-Grimal Aug 11, 2023
ae9962f
fix: tests after merges
Jean-Grimal Aug 14, 2023
150f5a7
fix: liquidate callback test
Jean-Grimal Aug 14, 2023
3b36a3a
fix: signatures nonce verification
Jean-Grimal Aug 14, 2023
18bed11
feat: add return value tests
Jean-Grimal Aug 14, 2023
6077851
fix: formatting.yml
Jean-Grimal Aug 14, 2023
847fa82
fix: forge fmt
Jean-Grimal Aug 14, 2023
6841e59
fix: accrue interests with accrueInterests function
Jean-Grimal Aug 14, 2023
be37f98
refactor: rename borrowableAsset to borrowableToken (same for collate…
Jean-Grimal Aug 14, 2023
4478931
feat: add liquidate return value test
Jean-Grimal Aug 14, 2023
72cd0d5
fix: forge fmt
Jean-Grimal Aug 14, 2023
53228b9
fix: accrue interests shares fee computation
Jean-Grimal Aug 15, 2023
a503e51
fix: no fuzz on addresses, and increase max amounts
Jean-Grimal Aug 15, 2023
85fc322
fix: forge fmt
Jean-Grimal Aug 15, 2023
4aa66f5
docs: apply suggestions
MerlinEgalite Aug 15, 2023
32c15cd
refactor: lint
MerlinEgalite Aug 15, 2023
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
184 changes: 184 additions & 0 deletions test/forge/BaseTest.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;

import "forge-std/Test.sol";
import "forge-std/console.sol";

import {SigUtils} from "test/forge/helpers/SigUtils.sol";
import "src/Morpho.sol";
import {ERC20Mock as ERC20} from "src/mocks/ERC20Mock.sol";
import {OracleMock as Oracle} from "src/mocks/OracleMock.sol";
import {IrmMock as Irm} from "src/mocks/IrmMock.sol";

contract BaseTest is Test {
using MathLib for uint256;
using MarketLib for Market;

uint256 internal constant HIGH_COLLATERAL_AMOUNT = 1e35;
uint256 internal constant MIN_TEST_AMOUNT = 100;
uint256 internal constant MAX_TEST_AMOUNT = 1e28;
uint256 internal constant MIN_TEST_SHARES = MIN_TEST_AMOUNT * SharesMathLib.VIRTUAL_SHARES;
uint256 internal constant MAX_TEST_SHARES = MAX_TEST_AMOUNT * SharesMathLib.VIRTUAL_SHARES;
uint256 internal constant MIN_COLLATERAL_PRICE = 1000;
uint256 internal constant MAX_COLLATERAL_PRICE = 1e40;

address internal SUPPLIER = _addrFromHashedString("Morpho Supplier");
address internal BORROWER = _addrFromHashedString("Morpho Borrower");
address internal REPAYER = _addrFromHashedString("Morpho Repayer");
address internal ONBEHALF = _addrFromHashedString("Morpho On Behalf");
address internal RECEIVER = _addrFromHashedString("Morpho Receiver");
address internal LIQUIDATOR = _addrFromHashedString("Morpho Liquidator");
address internal OWNER = _addrFromHashedString("Morpho Owner");

uint256 internal constant LLTV = 0.8 ether;

Morpho internal morpho;
ERC20 internal borrowableToken;
ERC20 internal collateralToken;
Oracle internal oracle;
Irm internal irm;
Market internal market;
Id internal id;

function setUp() public {
vm.label(OWNER, "Owner");
vm.label(SUPPLIER, "Supplier");
vm.label(BORROWER, "Borrower");
vm.label(REPAYER, "Repayer");
vm.label(ONBEHALF, "OnBehalf");
vm.label(RECEIVER, "Receiver");
vm.label(LIQUIDATOR, "Liquidator");

// Create Morpho.
morpho = new Morpho(OWNER);
vm.label(address(morpho), "Morpho");

// List a market.
borrowableToken = new ERC20("borrowable", "B");
vm.label(address(borrowableToken), "Borrowable asset");

collateralToken = new ERC20("collateral", "C");
vm.label(address(collateralToken), "Collateral asset");

oracle = new Oracle();
vm.label(address(oracle), "Oracle");

oracle.setPrice(1e36);

irm = new Irm(morpho);
vm.label(address(irm), "IRM");

market = Market(address(borrowableToken), address(collateralToken), address(oracle), address(irm), LLTV);
id = market.id();

vm.startPrank(OWNER);
morpho.enableIrm(address(irm));
morpho.enableLltv(LLTV);
morpho.createMarket(market);
vm.stopPrank();

borrowableToken.approve(address(morpho), type(uint256).max);
collateralToken.approve(address(morpho), type(uint256).max);
vm.startPrank(SUPPLIER);
borrowableToken.approve(address(morpho), type(uint256).max);
collateralToken.approve(address(morpho), type(uint256).max);
vm.stopPrank();
vm.startPrank(BORROWER);
Jean-Grimal marked this conversation as resolved.
Show resolved Hide resolved
borrowableToken.approve(address(morpho), type(uint256).max);
collateralToken.approve(address(morpho), type(uint256).max);
vm.stopPrank();
vm.startPrank(REPAYER);
borrowableToken.approve(address(morpho), type(uint256).max);
collateralToken.approve(address(morpho), type(uint256).max);
vm.stopPrank();
vm.startPrank(LIQUIDATOR);
borrowableToken.approve(address(morpho), type(uint256).max);
collateralToken.approve(address(morpho), type(uint256).max);
vm.stopPrank();
vm.startPrank(ONBEHALF);
borrowableToken.approve(address(morpho), type(uint256).max);
collateralToken.approve(address(morpho), type(uint256).max);
morpho.setAuthorization(BORROWER, true);
vm.stopPrank();

vm.roll(block.number + 1);
vm.warp(block.timestamp + 1 days);
}

function _addrFromHashedString(string memory str) internal pure returns (address) {
return address(uint160(uint256(keccak256(bytes(str)))));
}

function _supply(uint256 amount) internal {
borrowableToken.setBalance(address(this), amount);
morpho.supply(market, amount, 0, address(this), hex"");
}

function _supplyCollateralForBorrower(address borrower) internal {
collateralToken.setBalance(borrower, HIGH_COLLATERAL_AMOUNT);
vm.startPrank(borrower);
collateralToken.approve(address(morpho), type(uint256).max);
morpho.supplyCollateral(market, HIGH_COLLATERAL_AMOUNT, borrower, hex"");
vm.stopPrank();
}

function _boundHealthyPosition(uint256 amountCollateral, uint256 amountBorrowed, uint256 priceCollateral)
internal
view
returns (uint256, uint256, uint256)
{
priceCollateral = bound(priceCollateral, MIN_COLLATERAL_PRICE, MAX_COLLATERAL_PRICE);
amountBorrowed = bound(amountBorrowed, MIN_TEST_AMOUNT, MAX_TEST_AMOUNT);

uint256 minCollateral = amountBorrowed.wDivUp(market.lltv).mulDivUp(ORACLE_PRICE_SCALE, priceCollateral);
Jean-Grimal marked this conversation as resolved.
Show resolved Hide resolved
// vm.assume(minCollateral <= MAX_TEST_AMOUNT);

amountCollateral = bound(amountCollateral, minCollateral, max(minCollateral, MAX_TEST_AMOUNT));

return (amountCollateral, amountBorrowed, priceCollateral);
}

function _boundUnhealthyPosition(uint256 amountCollateral, uint256 amountBorrowed, uint256 priceCollateral)
internal
view
returns (uint256, uint256, uint256)
{
priceCollateral = bound(priceCollateral, MIN_COLLATERAL_PRICE, MAX_COLLATERAL_PRICE);
amountBorrowed = bound(amountBorrowed, MIN_TEST_AMOUNT, MAX_TEST_AMOUNT);

uint256 maxCollateral = amountBorrowed.wDivDown(market.lltv).mulDivDown(ORACLE_PRICE_SCALE, priceCollateral);
vm.assume(
maxCollateral.mulDivDown(priceCollateral, ORACLE_PRICE_SCALE).wMulDown(market.lltv) < amountBorrowed
&& maxCollateral > 0
);

amountCollateral = bound(amountBorrowed, 1, maxCollateral);

return (amountCollateral, amountBorrowed, priceCollateral);
}

function _boundValidLltv(uint256 lltv) internal view returns (uint256) {
return bound(lltv, 0, WAD - 1);
}

function _boundInvalidLltv(uint256 lltv) internal view returns (uint256) {
return bound(lltv, WAD, type(uint256).max);
}

function _liquidationIncentive(uint256 lltv) internal pure returns (uint256) {
MathisGD marked this conversation as resolved.
Show resolved Hide resolved
return
UtilsLib.min(MAX_LIQUIDATION_INCENTIVE_FACTOR, WAD.wDivDown(WAD - LIQUIDATION_CURSOR.wMulDown(WAD - lltv)));
}

function neq(Market memory a, Market memory b) internal pure returns (bool) {
return (Id.unwrap(a.id()) != Id.unwrap(b.id()));
}

function max(uint256 a, uint256 b) internal pure returns (uint256) {
return a > b ? a : b;
}

function min(uint256 a, uint256 b) internal pure returns (uint256) {
return a < b ? a : b;
}
}
Loading