diff --git a/src/libraries/periphery/MorphoLib.sol b/src/libraries/periphery/MorphoLib.sol index 6c9a80f04..b3f1f7727 100644 --- a/src/libraries/periphery/MorphoLib.sol +++ b/src/libraries/periphery/MorphoLib.sol @@ -14,14 +14,14 @@ import {MorphoStorageLib} from "./MorphoStorageLib.sol"; /// @custom:contact security@morpho.xyz /// @notice Helper library exposing getters with the expected value after interest accrual. /// @dev This library is not used in Morpho itself and is intended to be used by integrators. -/// @dev The getter to retrieve the total borrow shares is not exposed because interest accrual does not apply to it. +/// @dev The getter to retrieve the expected total borrow shares is not exposed because interest accrual does not apply to it. /// The value can be queried directly on Morpho using `totalBorrowShares`. library MorphoLib { using MathLib for uint256; using MarketLib for Market; using SharesMathLib for uint256; - function virtualAccrueInterest(IMorpho morpho, Market memory market) + function expectedAccrueInterest(IMorpho morpho, Market memory market) internal view returns (uint256 totalSupply, uint256 toralBorrow, uint256 totalSupplyShares) @@ -63,11 +63,11 @@ library MorphoLib { } function expectedTotalSupply(IMorpho morpho, Market memory market) internal view returns (uint256 totalSupply) { - (totalSupply,,) = virtualAccrueInterest(morpho, market); + (totalSupply,,) = expectedAccrueInterest(morpho, market); } function expectedTotalBorrow(IMorpho morpho, Market memory market) internal view returns (uint256 totalBorrow) { - (, totalBorrow,) = virtualAccrueInterest(morpho, market); + (, totalBorrow,) = expectedAccrueInterest(morpho, market); } function expectedTotalSupplyShares(IMorpho morpho, Market memory market) @@ -75,7 +75,7 @@ library MorphoLib { view returns (uint256 totalSupplyShares) { - (,, totalSupplyShares) = virtualAccrueInterest(morpho, market); + (,, totalSupplyShares) = expectedAccrueInterest(morpho, market); } /// @dev Warning: It does not work for `feeRecipient` because their supply shares increase is not taken into account. @@ -86,7 +86,7 @@ library MorphoLib { { Id id = market.id(); uint256 supplyShares = morpho.supplyShares(id, user); - (uint256 totalSupply,, uint256 totalSupplyShares) = virtualAccrueInterest(morpho, market); + (uint256 totalSupply,, uint256 totalSupplyShares) = expectedAccrueInterest(morpho, market); return supplyShares.toAssetsDown(totalSupply, totalSupplyShares); } @@ -99,7 +99,7 @@ library MorphoLib { Id id = market.id(); uint256 borrowShares = morpho.borrowShares(id, user); uint256 totalBorrowShares = morpho.totalBorrowShares(id); - (, uint256 totalBorrow,) = virtualAccrueInterest(morpho, market); + (, uint256 totalBorrow,) = expectedAccrueInterest(morpho, market); return borrowShares.toAssetsUp(totalBorrow, totalBorrowShares); } diff --git a/src/libraries/periphery/MorphoStorageLib.sol b/src/libraries/periphery/MorphoStorageLib.sol index 493d8b98a..2772207e9 100644 --- a/src/libraries/periphery/MorphoStorageLib.sol +++ b/src/libraries/periphery/MorphoStorageLib.sol @@ -30,11 +30,11 @@ library MorphoStorageLib { /* SLOT OFFSETS */ - uint256 internal constant BORROWABLE_TOKEN_SLOT_OFFSET = 0; - uint256 internal constant COLLATERAL_TOKEN_SLOT_OFFSET = 1; - uint256 internal constant ORACLE_SLOT_OFFSET = 2; - uint256 internal constant IRM_SLOT_OFFSET = 3; - uint256 internal constant LLTV_SLOT_OFFSET = 4; + uint256 internal constant BORROWABLE_TOKEN_OFFSET = 0; + uint256 internal constant COLLATERAL_TOKEN_OFFSET = 1; + uint256 internal constant ORACLE_OFFSET = 2; + uint256 internal constant IRM_OFFSET = 3; + uint256 internal constant LLTV_OFFSET = 4; /* GETTERS */ @@ -98,23 +98,23 @@ library MorphoStorageLib { return keccak256(abi.encode(authorizer, NONCE_SLOT)); } - function idToBorrowTokenSlot(Id id) internal pure returns (bytes32) { - return bytes32(uint256(keccak256(abi.encode(id, ID_TO_MARKET_SLOT))) + BORROWABLE_TOKEN_SLOT_OFFSET); + function idToBorrowableTokenSlot(Id id) internal pure returns (bytes32) { + return bytes32(uint256(keccak256(abi.encode(id, ID_TO_MARKET_SLOT))) + BORROWABLE_TOKEN_OFFSET); } function idToCollateralTokenSlot(Id id) internal pure returns (bytes32) { - return bytes32(uint256(keccak256(abi.encode(id, ID_TO_MARKET_SLOT))) + COLLATERAL_TOKEN_SLOT_OFFSET); + return bytes32(uint256(keccak256(abi.encode(id, ID_TO_MARKET_SLOT))) + COLLATERAL_TOKEN_OFFSET); } function idToOracleSlot(Id id) internal pure returns (bytes32) { - return bytes32(uint256(keccak256(abi.encode(id, ID_TO_MARKET_SLOT))) + ORACLE_SLOT_OFFSET); + return bytes32(uint256(keccak256(abi.encode(id, ID_TO_MARKET_SLOT))) + ORACLE_OFFSET); } function idToIrmSlot(Id id) internal pure returns (bytes32) { - return bytes32(uint256(keccak256(abi.encode(id, ID_TO_MARKET_SLOT))) + IRM_SLOT_OFFSET); + return bytes32(uint256(keccak256(abi.encode(id, ID_TO_MARKET_SLOT))) + IRM_OFFSET); } function idToLltvSlot(Id id) internal pure returns (bytes32) { - return bytes32(uint256(keccak256(abi.encode(id, ID_TO_MARKET_SLOT))) + LLTV_SLOT_OFFSET); + return bytes32(uint256(keccak256(abi.encode(id, ID_TO_MARKET_SLOT))) + LLTV_OFFSET); } } diff --git a/test/forge/periphery/MorphoLib.t.sol b/test/forge/periphery/MorphoLib.t.sol index 53b1abf69..92461c5fb 100644 --- a/test/forge/periphery/MorphoLib.t.sol +++ b/test/forge/periphery/MorphoLib.t.sol @@ -16,7 +16,7 @@ contract MorphoLibTest is BaseTest { _generatePendingInterest(amountSupplied, amountBorrowed, timeElapsed, fee); (uint256 virtualTotalSupply, uint256 virtualTotalBorrow, uint256 virtualTotalSupplyShares) = - IMorpho(address(morpho)).virtualAccrueInterest(market); + IMorpho(address(morpho)).expectedAccrueInterest(market); morpho.accrueInterest(market); diff --git a/test/forge/periphery/MorphoStorageLib.t.sol b/test/forge/periphery/MorphoStorageLib.t.sol index 89b238f48..33f25d437 100644 --- a/test/forge/periphery/MorphoStorageLib.t.sol +++ b/test/forge/periphery/MorphoStorageLib.t.sol @@ -10,12 +10,13 @@ contract MorphoStorageLibTest is BaseTest { using MathLib for uint256; using SharesMathLib for uint256; - function testStorage() public { + function testStorage(uint256 amountSupplied, uint256 amountBorrowed, uint256 timeElapsed, uint256 fee) public { // Prepare storage layout with non empty values. - uint256 amountSupplied = 1 ether; - uint256 amountBorrowed = 0.5 ether; - uint256 fee = 0.01 ether; + amountSupplied = bound(amountSupplied, 2, MAX_TEST_AMOUNT); + amountBorrowed = bound(amountBorrowed, 1, amountSupplied); + timeElapsed = uint32(bound(timeElapsed, 1, 1e8)); + fee = bound(fee, 1, MAX_FEE); // Set fee parameters. vm.startPrank(OWNER); @@ -68,7 +69,7 @@ contract MorphoStorageLibTest is BaseTest { slots[12] = MorphoStorageLib.isLltvEnabledSlot(LLTV); slots[13] = MorphoStorageLib.isAuthorizedSlot(authorizer, BORROWER); slots[14] = MorphoStorageLib.nonceSlot(authorizer); - slots[15] = MorphoStorageLib.idToBorrowTokenSlot(id); + slots[15] = MorphoStorageLib.idToBorrowableTokenSlot(id); slots[16] = MorphoStorageLib.idToCollateralTokenSlot(id); slots[17] = MorphoStorageLib.idToOracleSlot(id); slots[18] = MorphoStorageLib.idToIrmSlot(id); @@ -76,8 +77,8 @@ contract MorphoStorageLibTest is BaseTest { bytes32[] memory values = morpho.extsload(slots); - assertEq(abi.decode(abi.encodePacked(values[0]), (address)), morpho.owner()); - assertEq(abi.decode(abi.encodePacked(values[1]), (address)), morpho.feeRecipient()); + assertEq(abi.decode(abi.encode(values[0]), (address)), morpho.owner()); + assertEq(abi.decode(abi.encode(values[1]), (address)), morpho.feeRecipient()); assertEq(uint256(values[2]), morpho.supplyShares(id, address(this))); assertEq(uint256(values[3]), morpho.borrowShares(id, address(this))); assertEq(uint256(values[4]), morpho.collateral(id, address(this))); @@ -87,9 +88,9 @@ contract MorphoStorageLibTest is BaseTest { assertEq(uint256(values[8]), morpho.totalBorrowShares(id)); assertEq(uint256(values[9]), morpho.lastUpdate(id)); assertEq(uint256(values[10]), morpho.fee(id)); - assertEq(abi.decode(abi.encodePacked(values[11]), (bool)), morpho.isIrmEnabled(address(irm))); - assertEq(abi.decode(abi.encodePacked(values[12]), (bool)), morpho.isLltvEnabled(LLTV)); - assertEq(abi.decode(abi.encodePacked(values[13]), (bool)), morpho.isAuthorized(authorizer, BORROWER)); + assertEq(abi.decode(abi.encode(values[11]), (bool)), morpho.isIrmEnabled(address(irm))); + assertEq(abi.decode(abi.encode(values[12]), (bool)), morpho.isLltvEnabled(LLTV)); + assertEq(abi.decode(abi.encode(values[13]), (bool)), morpho.isAuthorized(authorizer, BORROWER)); assertEq(uint256(values[14]), morpho.nonce(authorizer)); ( @@ -99,10 +100,10 @@ contract MorphoStorageLibTest is BaseTest { address expectedIrm, uint256 expectedLltv ) = morpho.idToMarket(id); - assertEq(abi.decode(abi.encodePacked(values[15]), (address)), expectedBorrowableToken); - assertEq(abi.decode(abi.encodePacked(values[16]), (address)), expectedCollateralToken); - assertEq(abi.decode(abi.encodePacked(values[17]), (address)), expectedOracle); - assertEq(abi.decode(abi.encodePacked(values[18]), (address)), expectedIrm); + assertEq(abi.decode(abi.encode(values[15]), (address)), expectedBorrowableToken); + assertEq(abi.decode(abi.encode(values[16]), (address)), expectedCollateralToken); + assertEq(abi.decode(abi.encode(values[17]), (address)), expectedOracle); + assertEq(abi.decode(abi.encode(values[18]), (address)), expectedIrm); assertEq(uint256(values[19]), expectedLltv); } }