Skip to content

Instantly share code, notes, and snippets.

@Dliteofficial
Created November 17, 2023 20:12
Show Gist options
  • Save Dliteofficial/e7e432f18614a575fd441e3ddab309a7 to your computer and use it in GitHub Desktop.
Save Dliteofficial/e7e432f18614a575fd441e3ddab309a7 to your computer and use it in GitHub Desktop.
//SPDX-License-Identifier: LICENSED
pragma solidity 0.8.19;
import "forge-std/Test.sol";
import {Morpho, MarketParams} from "src/Morpho.sol";
import "src/libraries/MarketParamsLib.sol";
import {IMorpho, Position} from "src/interfaces/IMorpho.sol";
import {ERC20Mock} from "src/mocks/ERC20Mock.sol";
import {OracleMock} from "src/mocks/OracleMock.sol";
import {IERC20} from "src/mocks/interfaces/IERC20.sol";
import {IrmMock} from "src/mocks/IrmMock.sol";
contract CantinaTest is Test{
using MarketParamsLib for MarketParams;
uint256 constant ORACLE_PRICE_SCALE = 1e36;
address SUPPLIER_1;
address SUPPLIER_2;
address BORROWER_1;
address BORROWER_2;
address LIQUIDATOR;
address OWNER;
address FEE_RECIPIENT;
ERC20Mock loanToken;
ERC20Mock collateralToken;
IMorpho morpho;
OracleMock oracle;
IrmMock irm;
MarketParams marketParams;
uint LLTV = 0.8e18; //(80%)
function setUp() public {
//set Loan token and collateral token
loanToken = new ERC20Mock();
vm.label(address(loanToken), "LoanToken");
collateralToken = new ERC20Mock();
vm.label(address(collateralToken), "CollateralToken");
oracle = new OracleMock();
oracle.setPrice(ORACLE_PRICE_SCALE); //1
irm = new IrmMock();
//create addresses for suppliers (2), liquidator (1), borrower(2), OWNER
SUPPLIER_1 = makeAddr("supplier 1");
deal(address(loanToken), SUPPLIER_1, 1_000_000 ether);
SUPPLIER_2 = makeAddr("supplier 2");
deal(address(loanToken), SUPPLIER_2, 1_000_000 ether);
BORROWER_1 = makeAddr("Borrower 1");
deal(address(collateralToken), BORROWER_1, 1_000 ether);
BORROWER_2 = makeAddr("Borrower 2");
deal(address(collateralToken), BORROWER_2, 1_000 ether);
LIQUIDATOR = makeAddr("Liquidator");
deal(address(loanToken), LIQUIDATOR, 1_000_000 ether);
OWNER = makeAddr("Owner Address");
FEE_RECIPIENT = makeAddr("FEE_RECIPIENT");
//create a new market contract
morpho = IMorpho(address(new Morpho(OWNER)));
vm.startPrank(OWNER);
morpho.enableIrm(address(irm));
morpho.setFeeRecipient(FEE_RECIPIENT);
morpho.enableLltv(LLTV);
vm.stopPrank();
//create a market
marketParams = MarketParams(address(loanToken), address(collateralToken), address(oracle), address(irm), LLTV);
morpho.createMarket(marketParams);
//Suppliers deposit loan tokens for borrowers to borrow
vm.startPrank(SUPPLIER_1);
loanToken.approve(address(morpho), loanToken.balanceOf(SUPPLIER_1));
morpho.supply(marketParams, loanToken.balanceOf(SUPPLIER_1), 0, SUPPLIER_1, bytes(""));
changePrank(SUPPLIER_2);
loanToken.approve(address(morpho), loanToken.balanceOf(SUPPLIER_2));
morpho.supply(marketParams, loanToken.balanceOf(SUPPLIER_2), 0, SUPPLIER_2, bytes(""));
vm.stopPrank();
assertEq(loanToken.balanceOf(address(morpho)), 2_000_000 ether);
}
//Improve on this. Include more than 1 borrower, have more borrowers on liquidation
function test__borrowImmediateRepay() public {
vm.startPrank(BORROWER_1);
collateralToken.approve(address(morpho), collateralToken.balanceOf(BORROWER_1));
morpho.supplyCollateral(marketParams, collateralToken.balanceOf(BORROWER_1), BORROWER_1, bytes(""));
//since lltv was set to 80%, we can only borrow up to 80% of the collateral deposited
(, uint256 shares) = morpho.borrow(marketParams, 800 ether, 0, BORROWER_1, BORROWER_1);
oracle.setPrice(8e35);//change to half the price so maxBorrows is lesser than value of borrowShares
changePrank(BORROWER_2);
collateralToken.approve(address(morpho), collateralToken.balanceOf(BORROWER_2));
morpho.supplyCollateral(marketParams, collateralToken.balanceOf(BORROWER_2), BORROWER_2, bytes(""));
morpho.borrow(marketParams, 63 ether, 0, BORROWER_2, BORROWER_2);
//begin liquidation process
changePrank(LIQUIDATOR);
loanToken.approve(address(morpho), loanToken.balanceOf(LIQUIDATOR));
(, uint repaidShares) = morpho.liquidate(marketParams, BORROWER_1, 1_000 ether, 0, bytes(""));
assertEq(collateralToken.balanceOf(LIQUIDATOR), 1_000 ether);
assertLt(loanToken.balanceOf(LIQUIDATOR), 1_000_000 ether);
console.log("The bad debt shares left is %s", shares - repaidShares);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment