From afd4c929b8641064f0c13c313d30ff05977d8e2e Mon Sep 17 00:00:00 2001 From: patrick Date: Thu, 8 Dec 2022 16:04:01 -0500 Subject: [PATCH 1/3] Add Compound error return --- src/compound/MorphoGovernance.sol | 5 ++++- src/compound/PositionsManager.sol | 18 ++++++++++++++---- test/compound/TestGovernance.t.sol | 2 +- 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/src/compound/MorphoGovernance.sol b/src/compound/MorphoGovernance.sol index 1839d02fd..3099a79dd 100644 --- a/src/compound/MorphoGovernance.sol +++ b/src/compound/MorphoGovernance.sol @@ -127,6 +127,9 @@ abstract contract MorphoGovernance is MorphoUtils { /// @notice Thrown when the address is the zero address. error ZeroAddress(); + /// @notice Throws back Compound errors. + error CompoundError(uint256 errorCode); + /// UPGRADE /// /// @notice Initializes the Morpho contract. @@ -440,7 +443,7 @@ abstract contract MorphoGovernance is MorphoUtils { address[] memory marketToEnter = new address[](1); marketToEnter[0] = _poolToken; uint256[] memory results = comptroller.enterMarkets(marketToEnter); - if (results[0] != 0) revert MarketCreationFailedOnCompound(); + if (results[0] != 0) revert CompoundError(results[0]); // Same initial index as Compound. uint256 initialIndex; diff --git a/src/compound/PositionsManager.sol b/src/compound/PositionsManager.sol index 2d2086617..aa34fefde 100644 --- a/src/compound/PositionsManager.sol +++ b/src/compound/PositionsManager.sol @@ -179,6 +179,9 @@ contract PositionsManager is IPositionsManager, MatchingEngine { /// @notice Thrown when someone tries to liquidate but the liquidation with this asset as debt is paused. error LiquidateBorrowIsPaused(); + /// @notice Throws back Compound errors. + error CompoundError(uint256 errorCode); + /// STRUCTS /// // Struct to avoid stack too deep. @@ -926,7 +929,8 @@ contract PositionsManager is IPositionsManager, MatchingEngine { ICEther(_poolToken).mint{value: _amount}(); } else { _underlyingToken.safeApprove(_poolToken, _amount); - if (ICToken(_poolToken).mint(_amount) != 0) revert MintOnCompoundFailed(); + uint256 errorCode = ICToken(_poolToken).mint(_amount); + if (errorCode != 0) revert CompoundError(errorCode); } } @@ -936,7 +940,10 @@ contract PositionsManager is IPositionsManager, MatchingEngine { function _withdrawFromPool(address _poolToken, uint256 _amount) internal { // Withdraw only what is possible. The remaining dust is taken from the contract balance. _amount = CompoundMath.min(ICToken(_poolToken).balanceOfUnderlying(address(this)), _amount); - if (ICToken(_poolToken).redeemUnderlying(_amount) != 0) revert RedeemOnCompoundFailed(); + + uint256 errorCode = ICToken(_poolToken).redeemUnderlying(_amount); + if (errorCode != 0) revert CompoundError(errorCode); + if (_poolToken == cEth) IWETH(address(wEth)).deposit{value: _amount}(); // Turn the ETH received in wETH. } @@ -944,7 +951,9 @@ contract PositionsManager is IPositionsManager, MatchingEngine { /// @param _poolToken The address of the pool token. /// @param _amount The amount of token (in underlying). function _borrowFromPool(address _poolToken, uint256 _amount) internal { - if ((ICToken(_poolToken).borrow(_amount) != 0)) revert BorrowOnCompoundFailed(); + uint256 errorCode = ICToken(_poolToken).borrow(_amount); + if (errorCode != 0) revert CompoundError(errorCode); + if (_poolToken == cEth) IWETH(address(wEth)).deposit{value: _amount}(); // Turn the ETH received in wETH. } @@ -969,7 +978,8 @@ contract PositionsManager is IPositionsManager, MatchingEngine { ICEther(_poolToken).repayBorrow{value: _amount}(); } else { _underlyingToken.safeApprove(_poolToken, _amount); - if (ICToken(_poolToken).repayBorrow(_amount) != 0) revert RepayOnCompoundFailed(); + uint256 errorCode = ICToken(_poolToken).repayBorrow(_amount); + if (errorCode != 0) revert CompoundError(errorCode); } } } diff --git a/test/compound/TestGovernance.t.sol b/test/compound/TestGovernance.t.sol index c3f647811..3ac17e899 100644 --- a/test/compound/TestGovernance.t.sol +++ b/test/compound/TestGovernance.t.sol @@ -20,7 +20,7 @@ contract TestGovernance is TestSetup { function testShouldRevertWhenCreatingMarketWithAnImproperMarket() public { Types.MarketParameters memory marketParams = Types.MarketParameters(3_333, 0); - hevm.expectRevert(abi.encodeWithSignature("MarketCreationFailedOnCompound()")); + hevm.expectRevert(abi.encodeWithSignature("CompoundError(uint256)", 9)); morpho.createMarket(address(supplier1), marketParams); } From 3f2d0b91c9971cf1e5eb28a38f7da9e8211f1cc1 Mon Sep 17 00:00:00 2001 From: patrick Date: Sat, 10 Dec 2022 11:31:22 -0500 Subject: [PATCH 2/3] Remove unused errors --- src/compound/MorphoGovernance.sol | 3 --- src/compound/PositionsManager.sol | 12 ------------ 2 files changed, 15 deletions(-) diff --git a/src/compound/MorphoGovernance.sol b/src/compound/MorphoGovernance.sol index 3099a79dd..f455b028b 100644 --- a/src/compound/MorphoGovernance.sol +++ b/src/compound/MorphoGovernance.sol @@ -112,9 +112,6 @@ abstract contract MorphoGovernance is MorphoUtils { /// ERRORS /// - /// @notice Thrown when the creation of a market failed on Compound. - error MarketCreationFailedOnCompound(); - /// @notice Thrown when the input is above the max basis points value (100%). error ExceedsMaxBasisPoints(); diff --git a/src/compound/PositionsManager.sol b/src/compound/PositionsManager.sol index aa34fefde..815e66036 100644 --- a/src/compound/PositionsManager.sol +++ b/src/compound/PositionsManager.sol @@ -125,18 +125,6 @@ contract PositionsManager is IPositionsManager, MatchingEngine { /// @notice Thrown when the amount repaid during the liquidation is above what is allowed to be repaid. error AmountAboveWhatAllowedToRepay(); - /// @notice Thrown when the borrow on Compound failed. - error BorrowOnCompoundFailed(); - - /// @notice Thrown when the redeem on Compound failed . - error RedeemOnCompoundFailed(); - - /// @notice Thrown when the repay on Compound failed. - error RepayOnCompoundFailed(); - - /// @notice Thrown when the mint on Compound failed. - error MintOnCompoundFailed(); - /// @notice Thrown when user is not a member of the market. error UserNotMemberOfMarket(); From 303288cd303484d1171a36aabf25e60315c758eb Mon Sep 17 00:00:00 2001 From: patrick Date: Mon, 12 Dec 2022 17:15:17 -0500 Subject: [PATCH 3/3] Implement comments --- src/compound/MorphoGovernance.sol | 8 ++++---- src/compound/PositionsManager.sol | 23 ++++++++++++++++------- test/compound/TestGovernance.t.sol | 2 +- 3 files changed, 21 insertions(+), 12 deletions(-) diff --git a/src/compound/MorphoGovernance.sol b/src/compound/MorphoGovernance.sol index f455b028b..08b8659c3 100644 --- a/src/compound/MorphoGovernance.sol +++ b/src/compound/MorphoGovernance.sol @@ -112,6 +112,9 @@ abstract contract MorphoGovernance is MorphoUtils { /// ERRORS /// + /// @notice Thrown when the creation of a market failed on Compound and kicks back Compound error code. + error MarketCreationFailedOnCompound(uint256 errorCode); + /// @notice Thrown when the input is above the max basis points value (100%). error ExceedsMaxBasisPoints(); @@ -124,9 +127,6 @@ abstract contract MorphoGovernance is MorphoUtils { /// @notice Thrown when the address is the zero address. error ZeroAddress(); - /// @notice Throws back Compound errors. - error CompoundError(uint256 errorCode); - /// UPGRADE /// /// @notice Initializes the Morpho contract. @@ -440,7 +440,7 @@ abstract contract MorphoGovernance is MorphoUtils { address[] memory marketToEnter = new address[](1); marketToEnter[0] = _poolToken; uint256[] memory results = comptroller.enterMarkets(marketToEnter); - if (results[0] != 0) revert CompoundError(results[0]); + if (results[0] != 0) revert MarketCreationFailedOnCompound(results[0]); // Same initial index as Compound. uint256 initialIndex; diff --git a/src/compound/PositionsManager.sol b/src/compound/PositionsManager.sol index 815e66036..f43c27fe4 100644 --- a/src/compound/PositionsManager.sol +++ b/src/compound/PositionsManager.sol @@ -125,6 +125,18 @@ contract PositionsManager is IPositionsManager, MatchingEngine { /// @notice Thrown when the amount repaid during the liquidation is above what is allowed to be repaid. error AmountAboveWhatAllowedToRepay(); + /// @notice Thrown when the borrow on Compound failed and throws back the Compound error code. + error BorrowOnCompoundFailed(uint256 errorCode); + + /// @notice Thrown when the redeem on Compound failed and throws back the Compound error code. + error RedeemOnCompoundFailed(uint256 errorCode); + + /// @notice Thrown when the repay on Compound failed and throws back the Compound error code. + error RepayOnCompoundFailed(uint256 errorCode); + + /// @notice Thrown when the mint on Compound failed and throws back the Compound error code. + error MintOnCompoundFailed(uint256 errorCode); + /// @notice Thrown when user is not a member of the market. error UserNotMemberOfMarket(); @@ -167,9 +179,6 @@ contract PositionsManager is IPositionsManager, MatchingEngine { /// @notice Thrown when someone tries to liquidate but the liquidation with this asset as debt is paused. error LiquidateBorrowIsPaused(); - /// @notice Throws back Compound errors. - error CompoundError(uint256 errorCode); - /// STRUCTS /// // Struct to avoid stack too deep. @@ -918,7 +927,7 @@ contract PositionsManager is IPositionsManager, MatchingEngine { } else { _underlyingToken.safeApprove(_poolToken, _amount); uint256 errorCode = ICToken(_poolToken).mint(_amount); - if (errorCode != 0) revert CompoundError(errorCode); + if (errorCode != 0) revert MintOnCompoundFailed(errorCode); } } @@ -930,7 +939,7 @@ contract PositionsManager is IPositionsManager, MatchingEngine { _amount = CompoundMath.min(ICToken(_poolToken).balanceOfUnderlying(address(this)), _amount); uint256 errorCode = ICToken(_poolToken).redeemUnderlying(_amount); - if (errorCode != 0) revert CompoundError(errorCode); + if (errorCode != 0) revert RedeemOnCompoundFailed(errorCode); if (_poolToken == cEth) IWETH(address(wEth)).deposit{value: _amount}(); // Turn the ETH received in wETH. } @@ -940,7 +949,7 @@ contract PositionsManager is IPositionsManager, MatchingEngine { /// @param _amount The amount of token (in underlying). function _borrowFromPool(address _poolToken, uint256 _amount) internal { uint256 errorCode = ICToken(_poolToken).borrow(_amount); - if (errorCode != 0) revert CompoundError(errorCode); + if (errorCode != 0) revert BorrowOnCompoundFailed(errorCode); if (_poolToken == cEth) IWETH(address(wEth)).deposit{value: _amount}(); // Turn the ETH received in wETH. } @@ -967,7 +976,7 @@ contract PositionsManager is IPositionsManager, MatchingEngine { } else { _underlyingToken.safeApprove(_poolToken, _amount); uint256 errorCode = ICToken(_poolToken).repayBorrow(_amount); - if (errorCode != 0) revert CompoundError(errorCode); + if (errorCode != 0) revert RepayOnCompoundFailed(errorCode); } } } diff --git a/test/compound/TestGovernance.t.sol b/test/compound/TestGovernance.t.sol index 3ac17e899..d5cc187d0 100644 --- a/test/compound/TestGovernance.t.sol +++ b/test/compound/TestGovernance.t.sol @@ -20,7 +20,7 @@ contract TestGovernance is TestSetup { function testShouldRevertWhenCreatingMarketWithAnImproperMarket() public { Types.MarketParameters memory marketParams = Types.MarketParameters(3_333, 0); - hevm.expectRevert(abi.encodeWithSignature("CompoundError(uint256)", 9)); + hevm.expectRevert(abi.encodeWithSignature("MarketCreationFailedOnCompound(uint256)", 9)); morpho.createMarket(address(supplier1), marketParams); }