diff --git a/src/Morpho.sol b/src/Morpho.sol index 0f24d1a9f..4874b7dd3 100644 --- a/src/Morpho.sol +++ b/src/Morpho.sol @@ -445,6 +445,14 @@ contract Morpho is IMorpho { /* INTEREST MANAGEMENT */ + /// @inheritdoc IMorpho + function accrueInterest(MarketParams memory marketParams) external { + Id id = marketParams.id(); + require(market[id].lastUpdate != 0, ErrorsLib.MARKET_NOT_CREATED); + + _accrueInterest(marketParams, id); + } + /// @dev Accrues interest for the given market `marketParams`. /// @dev Assumes that the inputs `marketParams` and `id` match. function _accrueInterest(MarketParams memory marketParams, Id id) internal { diff --git a/src/interfaces/IMorpho.sol b/src/interfaces/IMorpho.sol index 02aa4e204..9f6b2cf5d 100644 --- a/src/interfaces/IMorpho.sol +++ b/src/interfaces/IMorpho.sol @@ -295,6 +295,9 @@ interface IMorpho { /// @param signature The signature. function setAuthorizationWithSig(Authorization calldata authorization, Signature calldata signature) external; + /// @notice Accrues interest for the given market `marketParams`. + function accrueInterest(MarketParams memory marketParams) external; + /// @notice Returns the data stored on the different `slots`. function extSloads(bytes32[] memory slots) external view returns (bytes32[] memory); } diff --git a/test/forge/BaseTest.sol b/test/forge/BaseTest.sol index 3a59787a0..ff185e04c 100644 --- a/test/forge/BaseTest.sol +++ b/test/forge/BaseTest.sol @@ -385,12 +385,6 @@ contract BaseTest is Test { return bound(lltv, 0, WAD - 1); } - function _accrueInterest(MarketParams memory market) internal { - collateralToken.setBalance(address(this), 1); - morpho.supplyCollateral(market, 1, address(this), hex""); - morpho.withdrawCollateral(market, 1, address(this), address(10)); - } - function neq(MarketParams memory a, MarketParams memory b) internal pure returns (bool) { return (Id.unwrap(a.id()) != Id.unwrap(b.id())); } diff --git a/test/forge/integration/AccrueInterestIntegrationTest.sol b/test/forge/integration/AccrueInterestIntegrationTest.sol index 25b91098b..3b91564f7 100644 --- a/test/forge/integration/AccrueInterestIntegrationTest.sol +++ b/test/forge/integration/AccrueInterestIntegrationTest.sol @@ -8,6 +8,13 @@ contract AccrueInterestIntegrationTest is BaseTest { using MorphoLib for IMorpho; using SharesMathLib for uint256; + function testAccrueInterestMarketNotCreated(MarketParams memory marketParamsFuzz) public { + vm.assume(neq(marketParamsFuzz, marketParams)); + + vm.expectRevert(bytes(ErrorsLib.MARKET_NOT_CREATED)); + morpho.accrueInterest(marketParamsFuzz); + } + function testAccrueInterestNoTimeElapsed(uint256 amountSupplied, uint256 amountBorrowed) public { uint256 collateralPrice = oracle.price(); uint256 amountCollateral; @@ -28,7 +35,7 @@ contract AccrueInterestIntegrationTest is BaseTest { uint256 totalSupplyBeforeAccrued = morpho.totalSupplyAssets(id); uint256 totalSupplySharesBeforeAccrued = morpho.totalSupplyShares(id); - _accrueInterest(marketParams); + morpho.accrueInterest(marketParams); assertEq(morpho.totalBorrowAssets(id), totalBorrowBeforeAccrued, "total borrow"); assertEq(morpho.totalSupplyAssets(id), totalSupplyBeforeAccrued, "total supply"); @@ -49,7 +56,7 @@ contract AccrueInterestIntegrationTest is BaseTest { uint256 totalSupplyBeforeAccrued = morpho.totalSupplyAssets(id); uint256 totalSupplySharesBeforeAccrued = morpho.totalSupplyShares(id); - _accrueInterest(marketParams); + morpho.accrueInterest(marketParams); assertEq(morpho.totalBorrowAssets(id), totalBorrowBeforeAccrued, "total borrow"); assertEq(morpho.totalSupplyAssets(id), totalSupplyBeforeAccrued, "total supply"); @@ -86,12 +93,9 @@ contract AccrueInterestIntegrationTest is BaseTest { uint256 expectedAccruedInterest = totalBorrowBeforeAccrued.wMulDown(borrowRate.wTaylorCompounded(blocks * BLOCK_TIME)); - collateralToken.setBalance(address(this), 1); - morpho.supplyCollateral(marketParams, 1, address(this), hex""); vm.expectEmit(true, true, true, true, address(morpho)); emit EventsLib.AccrueInterest(id, borrowRate, expectedAccruedInterest, 0); - // Accrues interest. - morpho.withdrawCollateral(marketParams, 1, address(this), address(this)); + morpho.accrueInterest(marketParams); assertEq(morpho.totalBorrowAssets(id), totalBorrowBeforeAccrued + expectedAccruedInterest, "total borrow"); assertEq(morpho.totalSupplyAssets(id), totalSupplyBeforeAccrued + expectedAccruedInterest, "total supply"); @@ -151,12 +155,9 @@ contract AccrueInterestIntegrationTest is BaseTest { params.totalSupplySharesBeforeAccrued ); - collateralToken.setBalance(address(this), 1); - morpho.supplyCollateral(marketParams, 1, address(this), hex""); vm.expectEmit(true, true, true, true, address(morpho)); emit EventsLib.AccrueInterest(id, params.borrowRate, params.expectedAccruedInterest, params.feeShares); - // Accrues interest. - morpho.withdrawCollateral(marketParams, 1, address(this), address(this)); + morpho.accrueInterest(marketParams); assertEq( morpho.totalSupplyAssets(id), diff --git a/test/forge/libraries/periphery/MorphoBalancesLibTest.sol b/test/forge/libraries/periphery/MorphoBalancesLibTest.sol index 516bb0847..5b942f090 100644 --- a/test/forge/libraries/periphery/MorphoBalancesLibTest.sol +++ b/test/forge/libraries/periphery/MorphoBalancesLibTest.sol @@ -21,7 +21,7 @@ contract MorphoBalancesLibTest is BaseTest { uint256 virtualTotalBorrowShares ) = morpho.expectedMarketBalances(marketParams); - _accrueInterest(marketParams); + morpho.accrueInterest(marketParams); assertEq(virtualTotalSupplyAssets, morpho.totalSupplyAssets(id), "total supply assets"); assertEq(virtualTotalBorrowAssets, morpho.totalBorrowAssets(id), "total borrow assets"); @@ -36,7 +36,7 @@ contract MorphoBalancesLibTest is BaseTest { uint256 expectedTotalSupply = morpho.expectedTotalSupply(marketParams); - _accrueInterest(marketParams); + morpho.accrueInterest(marketParams); assertEq(expectedTotalSupply, morpho.totalSupplyAssets(id)); } @@ -48,7 +48,7 @@ contract MorphoBalancesLibTest is BaseTest { uint256 expectedTotalBorrow = morpho.expectedTotalBorrow(marketParams); - _accrueInterest(marketParams); + morpho.accrueInterest(marketParams); assertEq(expectedTotalBorrow, morpho.totalBorrowAssets(id)); } @@ -63,7 +63,7 @@ contract MorphoBalancesLibTest is BaseTest { uint256 expectedTotalSupplyShares = morpho.expectedTotalSupplyShares(marketParams); - _accrueInterest(marketParams); + morpho.accrueInterest(marketParams); assertEq(expectedTotalSupplyShares, morpho.totalSupplyShares(id)); } @@ -75,7 +75,7 @@ contract MorphoBalancesLibTest is BaseTest { uint256 expectedSupplyBalance = morpho.expectedSupplyBalance(marketParams, address(this)); - _accrueInterest(marketParams); + morpho.accrueInterest(marketParams); uint256 actualSupplyBalance = morpho.supplyShares(id, address(this)).toAssetsDown( morpho.totalSupplyAssets(id), morpho.totalSupplyShares(id) @@ -91,7 +91,7 @@ contract MorphoBalancesLibTest is BaseTest { uint256 expectedBorrowBalance = morpho.expectedBorrowBalance(marketParams, address(this)); - _accrueInterest(marketParams); + morpho.accrueInterest(marketParams); uint256 actualBorrowBalance = morpho.borrowShares(id, address(this)).toAssetsUp( morpho.totalBorrowAssets(id), morpho.totalBorrowShares(id)