-
Notifications
You must be signed in to change notification settings - Fork 50
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'main' of github.com:morpho-labs/morpho-blue into feat/i…
…nvariant-tests
- Loading branch information
Showing
7 changed files
with
161 additions
and
32 deletions.
There are no files selected for viewing
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,42 +1,58 @@ | ||
// SPDX-License-Identifier: UNLICENSED | ||
pragma solidity ^0.8.0; | ||
|
||
import {IMorpho, Id} from "../../Morpho.sol"; | ||
import {IMorpho, Id} from "../../interfaces/IMorpho.sol"; | ||
import {MorphoStorageLib} from "./MorphoStorageLib.sol"; | ||
|
||
library MorphoLib { | ||
function supplyShares(IMorpho morpho, Id id, address user) internal view returns (uint256 res) { | ||
(res,,) = morpho.user(id, user); | ||
function supplyShares(IMorpho morpho, Id id, address user) internal view returns (uint256) { | ||
bytes32[] memory slot = _array(MorphoStorageLib.userSupplySharesSlot(id, user)); | ||
return uint256(morpho.extSloads(slot)[0]); | ||
} | ||
|
||
function borrowShares(IMorpho morpho, Id id, address user) internal view returns (uint256 res) { | ||
(, res,) = morpho.user(id, user); | ||
function borrowShares(IMorpho morpho, Id id, address user) internal view returns (uint256) { | ||
bytes32[] memory slot = _array(MorphoStorageLib.userBorrowSharesAndCollateralSlot(id, user)); | ||
return uint128(uint256(morpho.extSloads(slot)[0])); | ||
} | ||
|
||
function collateral(IMorpho morpho, Id id, address user) internal view returns (uint256 res) { | ||
(,, res) = morpho.user(id, user); | ||
function collateral(IMorpho morpho, Id id, address user) internal view returns (uint256) { | ||
bytes32[] memory slot = _array(MorphoStorageLib.userBorrowSharesAndCollateralSlot(id, user)); | ||
return uint256(morpho.extSloads(slot)[0] >> 128); | ||
} | ||
|
||
function totalSupplyAssets(IMorpho morpho, Id id) internal view returns (uint256 res) { | ||
(res,,,,,) = morpho.market(id); | ||
function totalSupplyAssets(IMorpho morpho, Id id) internal view returns (uint256) { | ||
bytes32[] memory slot = _array(MorphoStorageLib.marketTotalSupplyAssetsAndSharesSlot(id)); | ||
return uint128(uint256(morpho.extSloads(slot)[0])); | ||
} | ||
|
||
function totalSupplyShares(IMorpho morpho, Id id) internal view returns (uint256 res) { | ||
(, res,,,,) = morpho.market(id); | ||
function totalSupplyShares(IMorpho morpho, Id id) internal view returns (uint256) { | ||
bytes32[] memory slot = _array(MorphoStorageLib.marketTotalSupplyAssetsAndSharesSlot(id)); | ||
return uint256(morpho.extSloads(slot)[0] >> 128); | ||
} | ||
|
||
function totalBorrowAssets(IMorpho morpho, Id id) internal view returns (uint256 res) { | ||
(,, res,,,) = morpho.market(id); | ||
function totalBorrowAssets(IMorpho morpho, Id id) internal view returns (uint256) { | ||
bytes32[] memory slot = _array(MorphoStorageLib.marketTotalBorrowAssetsAndSharesSlot(id)); | ||
return uint128(uint256(morpho.extSloads(slot)[0])); | ||
} | ||
|
||
function totalBorrowShares(IMorpho morpho, Id id) internal view returns (uint256 res) { | ||
(,,, res,,) = morpho.market(id); | ||
function totalBorrowShares(IMorpho morpho, Id id) internal view returns (uint256) { | ||
bytes32[] memory slot = _array(MorphoStorageLib.marketTotalBorrowAssetsAndSharesSlot(id)); | ||
return uint256(morpho.extSloads(slot)[0] >> 128); | ||
} | ||
|
||
function lastUpdate(IMorpho morpho, Id id) internal view returns (uint256 res) { | ||
(,,,, res,) = morpho.market(id); | ||
function lastUpdate(IMorpho morpho, Id id) internal view returns (uint256) { | ||
bytes32[] memory slot = _array(MorphoStorageLib.marketLastUpdateAndFeeSlot(id)); | ||
return uint128(uint256(morpho.extSloads(slot)[0])); | ||
} | ||
|
||
function fee(IMorpho morpho, Id id) internal view returns (uint256 res) { | ||
(,,,,, res) = morpho.market(id); | ||
function fee(IMorpho morpho, Id id) internal view returns (uint256) { | ||
bytes32[] memory slot = _array(MorphoStorageLib.marketLastUpdateAndFeeSlot(id)); | ||
return uint256(morpho.extSloads(slot)[0] >> 128); | ||
} | ||
|
||
function _array(bytes32 x) private pure returns (bytes32[] memory) { | ||
bytes32[] memory res = new bytes32[](1); | ||
res[0] = x; | ||
return res; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
// SPDX-License-Identifier: UNLICENSED | ||
pragma solidity ^0.8.0; | ||
|
||
import {MorphoBalancesLib} from "src/libraries/periphery/MorphoBalancesLib.sol"; | ||
|
||
import "../BaseTest.sol"; | ||
|
||
contract MorphoLibTest is BaseTest { | ||
using MathLib for uint256; | ||
using MorphoLib for Morpho; | ||
|
||
function _testMorphoLibCommon(uint256 amountSupplied, uint256 amountBorrowed, uint256 timestamp, uint256 fee) | ||
private | ||
{ | ||
// Prepare storage layout with non empty values. | ||
|
||
amountSupplied = bound(amountSupplied, 2, MAX_TEST_AMOUNT); | ||
amountBorrowed = bound(amountBorrowed, 1, amountSupplied); | ||
timestamp = bound(timestamp, block.timestamp, type(uint32).max); | ||
fee = bound(fee, 0, MAX_FEE); | ||
|
||
// Set fee parameters. | ||
vm.prank(OWNER); | ||
morpho.setFee(market, fee); | ||
|
||
// Set timestamp. | ||
vm.warp(timestamp); | ||
|
||
borrowableToken.setBalance(address(this), amountSupplied); | ||
morpho.supply(market, amountSupplied, 0, address(this), hex""); | ||
|
||
uint256 collateralPrice = IOracle(market.oracle).price(); | ||
collateralToken.setBalance(BORROWER, amountBorrowed.wDivUp(LLTV).mulDivUp(ORACLE_PRICE_SCALE, collateralPrice)); | ||
|
||
vm.startPrank(BORROWER); | ||
morpho.supplyCollateral( | ||
market, amountBorrowed.wDivUp(LLTV).mulDivUp(ORACLE_PRICE_SCALE, collateralPrice), BORROWER, hex"" | ||
); | ||
morpho.borrow(market, amountBorrowed, 0, BORROWER, BORROWER); | ||
vm.stopPrank(); | ||
} | ||
|
||
function testSupplyShares(uint256 amountSupplied, uint256 amountBorrowed, uint256 timestamp, uint256 fee) public { | ||
_testMorphoLibCommon(amountSupplied, amountBorrowed, timestamp, fee); | ||
|
||
(uint256 expectedSupplyShares,,) = morpho.user(id, address(this)); | ||
assertEq(morpho.supplyShares(id, address(this)), expectedSupplyShares); | ||
} | ||
|
||
function testBorrowShares(uint256 amountSupplied, uint256 amountBorrowed, uint256 timestamp, uint256 fee) public { | ||
_testMorphoLibCommon(amountSupplied, amountBorrowed, timestamp, fee); | ||
|
||
(, uint256 expectedBorrowShares,) = morpho.user(id, BORROWER); | ||
assertEq(morpho.borrowShares(id, BORROWER), expectedBorrowShares); | ||
} | ||
|
||
function testCollateral(uint256 amountSupplied, uint256 amountBorrowed, uint256 timestamp, uint256 fee) public { | ||
_testMorphoLibCommon(amountSupplied, amountBorrowed, timestamp, fee); | ||
|
||
(,, uint256 expectedCollateral) = morpho.user(id, BORROWER); | ||
assertEq(morpho.collateral(id, BORROWER), expectedCollateral); | ||
} | ||
|
||
function testTotalSupplyAssets(uint256 amountSupplied, uint256 amountBorrowed, uint256 timestamp, uint256 fee) | ||
public | ||
{ | ||
_testMorphoLibCommon(amountSupplied, amountBorrowed, timestamp, fee); | ||
|
||
(uint256 expectedTotalSupplyAssets,,,,,) = morpho.market(id); | ||
assertEq(morpho.totalSupplyAssets(id), expectedTotalSupplyAssets); | ||
} | ||
|
||
function testTotalSupplyShares(uint256 amountSupplied, uint256 amountBorrowed, uint256 timestamp, uint256 fee) | ||
public | ||
{ | ||
_testMorphoLibCommon(amountSupplied, amountBorrowed, timestamp, fee); | ||
|
||
(, uint256 expectedTotalSupplyShares,,,,) = morpho.market(id); | ||
assertEq(morpho.totalSupplyShares(id), expectedTotalSupplyShares); | ||
} | ||
|
||
function testTotalBorrowAssets(uint256 amountSupplied, uint256 amountBorrowed, uint256 timestamp, uint256 fee) | ||
public | ||
{ | ||
_testMorphoLibCommon(amountSupplied, amountBorrowed, timestamp, fee); | ||
|
||
(,, uint256 expectedTotalBorrowAssets,,,) = morpho.market(id); | ||
assertEq(morpho.totalBorrowAssets(id), expectedTotalBorrowAssets); | ||
} | ||
|
||
function testTotalBorrowShares(uint256 amountSupplied, uint256 amountBorrowed, uint256 timestamp, uint256 fee) | ||
public | ||
{ | ||
_testMorphoLibCommon(amountSupplied, amountBorrowed, timestamp, fee); | ||
|
||
(,,, uint256 expectedTotalBorrowShares,,) = morpho.market(id); | ||
assertEq(morpho.totalBorrowShares(id), expectedTotalBorrowShares); | ||
} | ||
|
||
function testLastUpdate(uint256 amountSupplied, uint256 amountBorrowed, uint256 timestamp, uint256 fee) public { | ||
_testMorphoLibCommon(amountSupplied, amountBorrowed, timestamp, fee); | ||
|
||
(,,,, uint256 expectedLastUpdate,) = morpho.market(id); | ||
assertEq(morpho.lastUpdate(id), expectedLastUpdate); | ||
} | ||
|
||
function testFee(uint256 amountSupplied, uint256 amountBorrowed, uint256 timestamp, uint256 fee) public { | ||
_testMorphoLibCommon(amountSupplied, amountBorrowed, timestamp, fee); | ||
|
||
(,,,,, uint256 expectedFee) = morpho.market(id); | ||
assertEq(morpho.fee(id), expectedFee); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters