diff --git a/contracts/mainnet/connectors/morpho-blue/events.sol b/contracts/mainnet/connectors/morpho-blue/events.sol index 24ec7f1b..a9229c87 100644 --- a/contracts/mainnet/connectors/morpho-blue/events.sol +++ b/contracts/mainnet/connectors/morpho-blue/events.sol @@ -1,60 +1,140 @@ //SPDX-License-Identifier: MIT pragma solidity ^0.7.0; pragma experimental ABIEncoderV2; +import "./interface.sol"; contract Events { - event LogSupply( - address loanToken, + event LogSupplyAssets( + MarketParams marketParams, uint256 assets, uint256 shares, - address onBehalf, - bytes data, uint256 getId, uint256 setId ); - event LogSupplyCollateral( - address loanToken, - address poolTokenAddress, - uint256 amount, - uint256 maxGasForMatching, - uint256 getId, - uint256 setId - ); - - event LogBorrow( - address loanToken, - uint256 amounts, - uint256 shares, + event LogSupplyAssetsOnBehalf( + MarketParams marketParams, + uint256 assets, + uint256 shares, address onBehalf, uint256 getId, uint256 setId ); - event LogWithdraw( - address loanToken, + event LogSupplySharesOnBehalf( + MarketParams marketParams, + uint256 assets, + uint256 shares, + address onBehalf, + uint256 getId, + uint256 setId + ); + + event LogSupplyCollateral( + MarketParams marketParams, + uint256 assets, + uint256 getId, + uint256 setId + ); + + event LogSupplyCollateralOnBehalf( + MarketParams marketParams, + uint256 assets, + address onBehalf, + uint256 getId, + uint256 setId + ); + + event LogBorrow( + MarketParams marketParams, uint256 amounts, uint256 shares, + uint256 getId, + uint256 setId + ); + + event LogBorrowOnBehalf( + MarketParams marketParams, + uint256 amounts, + uint256 shares, + address onBehalf, + address reciever, + uint256 getId, + uint256 setId + ); + + event LogBorrowShares( + MarketParams marketParams, + uint256 amounts, + uint256 shares, + address onBehalf, + address reciever, + uint256 getId, + uint256 setId + ); + + event LogWithdraw( + MarketParams marketParams, + uint256 amounts, + uint256 getId, + uint256 setId + ); + + event LogWithdrawOnBehalf( + MarketParams marketParams, + uint256 amounts, + address onBehalf, + uint256 getId, + uint256 setId + ); + + event LogWithdrawSharesOnBehalf( + MarketParams marketParams, + uint256 shares, address onBehalf, uint256 getId, uint256 setId ); event LogWithdrawCollateral( - address loanToken, + MarketParams marketParams, + uint256 amounts, + uint256 getId, + uint256 setId + ); + + event LogWithdrawCollateralOnBehalf( + MarketParams marketParams, uint256 amounts, address onBehalf, + address reciever, uint256 getId, uint256 setId ); event LogPayback( - address loanToken, + MarketParams marketParams, + uint256 amounts, + uint256 shares, + uint256 getId, + uint256 setId + ); + + event LogPaybackOnBehalf( + MarketParams marketParams, + uint256 amounts, + uint256 shares, + address onBehalf, + uint256 getId, + uint256 setId + ); + + event LogPaybackShares( + MarketParams marketParams, uint256 amounts, uint256 shares, address onBehalf, - bytes data, uint256 getId, uint256 setId ); diff --git a/contracts/mainnet/connectors/morpho-blue/helpers.sol b/contracts/mainnet/connectors/morpho-blue/helpers.sol index 2b71103c..2fe360f4 100644 --- a/contracts/mainnet/connectors/morpho-blue/helpers.sol +++ b/contracts/mainnet/connectors/morpho-blue/helpers.sol @@ -10,29 +10,98 @@ import "../../common/interfaces.sol"; abstract contract Helpers is Stores, Basic { IMorpho public constant MORPHO_BLUE = - IMorpho(0x777777c9898D384F785Ee44Acfe945efDFf5f3E0); + IMorpho(0x777777c9898D384F785Ee44Acfe945efDFf5f3E0); // TODO: Update + uint256 internal constant MARKET_PARAMS_BYTES_LENGTH = 5 * 32; + /// @dev The number of virtual assets of 1 enforces a conversion rate between shares and assets when a market is + /// empty. + uint256 internal constant VIRTUAL_ASSETS = 1; + /// @dev The number of virtual shares has been chosen low enough to prevent overflows, and high enough to ensure + /// high precision computations. + uint256 internal constant VIRTUAL_SHARES = 1e6; + + /// @notice Handles Eth to Weth conversion if assets are provided. function _performEthToWethConversion( - address _tokenAddress, - uint256 _amount, - uint256 _getId - ) internal returns (TokenInterface _tokenContract, uint256 _amt, bool _isMax) { - _amt = getUint(_getId, _amount); - _isMax = _amt == uint256(-1); + MarketParams memory _marketParams, + uint256 _assets, + address _onBehalf, + uint256 _getId, + bool _isCollateral, + bool _isRepay + ) internal returns (TokenInterface _tokenContract, uint256 _amt) { + _amt = getUint(_getId, _assets); + bool _isEth = _isCollateral ? _marketParams.collateralToken == ethAddr : _marketParams.loanToken == ethAddr; - if (_tokenAddress == ethAddr) { - _tokenContract = TokenInterface(wethAddr); - if (_amt == uint256(-1)) _amt = address(this).balance; - convertEthToWeth(true, _tokenContract, _amt); - } else { - _tokenContract = TokenInterface(_tokenAddress); - if (_amt == uint256(-1)) _amt = _tokenContract.balanceOf(address(this)); + // Set the correct token contract + _tokenContract = _isEth ? TokenInterface(wethAddr) : TokenInterface(_marketParams.loanToken); + + // Check for max value + if (_assets == type(uint256).max) { + uint256 _maxAvailable = _isEth ? address(this).balance : _tokenContract.balanceOf(address(this)); + if (_isRepay) { + uint256 _amtDebt = getPaybackBalance(_marketParams, _onBehalf); + _amt = min(_maxAvailable, _amtDebt); + } else { + _amt = _maxAvailable; + } + } + + // Perform conversion if necessary + if (_isEth) { + convertEthToWeth(true, _tokenContract, _amt); } } - uint256 internal constant MARKET_PARAMS_BYTES_LENGTH = 5 * 32; + /// @notice Handles Eth to Weth conversion if shares are provided. + function _performEthToWethSharesConversion( + MarketParams memory _marketParams, + uint256 _shares, + address _onBehalf, + uint256 _getId, + bool _isRepay + ) internal returns (TokenInterface _tokenContract, uint256 _assets) { + uint256 _shareAmt = getUint(_getId, _shares); + bool _isEth = _marketParams.loanToken == ethAddr; + + // Set the token contract based on whether the loan token is ETH + _tokenContract = _isEth ? TokenInterface(wethAddr) : TokenInterface(_marketParams.loanToken); + + // Handle the max share case or normal share conversion + if (_isRepay && _shares == type(uint256).max) { + uint256 _maxAvailable = _isEth ? address(this).balance : _tokenContract.balanceOf(address(this)); + _assets = min(_maxAvailable, getPaybackBalance(_marketParams, _onBehalf)); + } else { + bytes32 _id = id(_marketParams); + _assets = _toAssetsUp(_shareAmt, MORPHO_BLUE.market(_id).totalSupplyAssets, MORPHO_BLUE.market(_id).totalSupplyShares); + } + + // Perform ETH to WETH conversion if necessary + if (_isEth) { + convertEthToWeth(true, _tokenContract, _assets); + } + } + + /// @notice Helper function to find the minimum of two values + function min(uint256 a, uint256 b) internal pure returns (uint256) { + return a < b ? a : b; + } + + /// @notice Returns the payback balance in assets. + function getPaybackBalance(MarketParams memory _marketParams, address _onBehalf) internal view returns(uint256 _assets) { + bytes32 _id = id(_marketParams); + + uint256 _shareAmt = MORPHO_BLUE.position(_id, _onBehalf).supplyShares; + + _assets = + _toAssetsUp( + _shareAmt, + MORPHO_BLUE.market(_id).totalSupplyAssets, + MORPHO_BLUE.market(_id).totalSupplyShares + ); + + } /// @notice Returns the id of the market `marketParams`. function id(MarketParams memory marketParams) internal pure returns (bytes32 marketParamsId) { @@ -40,4 +109,14 @@ abstract contract Helpers is Stores, Basic { marketParamsId := keccak256(marketParams, MARKET_PARAMS_BYTES_LENGTH) } } + + /// @notice Calculates the value of `shares` quoted in assets, rounding up. + function _toAssetsUp(uint256 _shares, uint256 _totalAssets, uint256 _totalShares) internal pure returns (uint256) { + return _mulDivUp(_shares, _totalAssets + VIRTUAL_ASSETS, _totalShares + VIRTUAL_SHARES); + } + + /// @notice Returns (`x` * `y`) / `d` rounded up. + function _mulDivUp(uint256 x, uint256 y, uint256 d) internal pure returns (uint256) { + return (x * y + (d - 1)) / d; + } } diff --git a/contracts/mainnet/connectors/morpho-blue/interface.sol b/contracts/mainnet/connectors/morpho-blue/interface.sol index 68e9bb62..31f7695e 100644 --- a/contracts/mainnet/connectors/morpho-blue/interface.sol +++ b/contracts/mainnet/connectors/morpho-blue/interface.sol @@ -2,8 +2,6 @@ pragma solidity ^0.7.0; pragma experimental ABIEncoderV2; -// type Id is bytes32; - struct MarketParams { address loanToken; address collateralToken; @@ -20,6 +18,19 @@ struct Position { uint128 collateral; } +/// @dev Warning: `totalSupplyAssets` does not contain the accrued interest since the last interest accrual. +/// @dev Warning: `totalBorrowAssets` does not contain the accrued interest since the last interest accrual. +/// @dev Warning: `totalSupplyShares` does not contain the additional shares accrued by `feeRecipient` since the last +/// interest accrual. +struct Market { + uint128 totalSupplyAssets; + uint128 totalSupplyShares; + uint128 totalBorrowAssets; + uint128 totalBorrowShares; + uint128 lastUpdate; + uint128 fee; +} + interface IMorpho { function createMarket(MarketParams memory marketParams) external; @@ -61,5 +72,7 @@ interface IMorpho { function withdrawCollateral(MarketParams memory marketParams, uint256 assets, address onBehalf, address receiver) external; function position(bytes32 id, address user) external view returns(Position memory); + + function market(bytes32 id) external view returns(Market memory); } diff --git a/contracts/mainnet/connectors/morpho-blue/main.sol b/contracts/mainnet/connectors/morpho-blue/main.sol index 8ce5508a..e4dce09d 100644 --- a/contracts/mainnet/connectors/morpho-blue/main.sol +++ b/contracts/mainnet/connectors/morpho-blue/main.sol @@ -7,27 +7,17 @@ import "./events.sol"; abstract contract MorphoBlue is Helpers, Events { - /// @notice Creates the market `marketParams`. - /// @param marketParams The market to supply assets to. - function createMarket(MarketParams memory marketParams) external { - MORPHO_BLUE.createMarket(marketParams); - } - /** - * @dev Supplying a large amount can revert for overflow. - * @notice Supplies `assets` or `shares` on behalf of `onBehalf`, optionally calling back the caller's `onMorphoSupply` function with the given `data`. - * @param _marketParams The market to supply assets to.(For ETH of loanToken in _marketParams: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) + * @dev Supply ETH/ERC20 Token for lending. + * @notice Supplies assets to Morpho Blue for lending. + * @param _marketParams The market to supply assets to. (For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) * @param _assets The amount of assets to supply. - * @param _shares The amount of shares to mint. - * @param _data Arbitrary data to pass to the `onMorphoSupply` callback. Pass empty data if not needed. * @param _getId ID to retrieve amt. * @param _setId ID stores the amount of tokens deposited. */ function supply( MarketParams memory _marketParams, uint256 _assets, - uint256 _shares, - bytes calldata _data, uint256 _getId, uint256 _setId ) @@ -35,47 +25,46 @@ abstract contract MorphoBlue is Helpers, Events { payable returns (string memory _eventName, bytes memory _eventParam) { + // Final assets amount and token contract ( - TokenInterface _tokenContract, - uint256 _amt, - ) = _performEthToWethConversion(_marketParams.loanToken, _assets, _getId); + TokenInterface _tokenContract, // Loan token contract + uint256 _amt + ) = _performEthToWethConversion(_marketParams, _assets, address(this), _getId, false, false); + // Approving loan token for supplying approve(_tokenContract, address(MORPHO_BLUE), _amt); + + // Updating token addresses _marketParams.loanToken = address(_tokenContract); + _marketParams.collateralToken = _marketParams.collateralToken == ethAddr ? wethAddr : _marketParams.collateralToken; - (_assets, _shares) = MORPHO_BLUE.supply(_marketParams, _assets, _shares, address(this), _data); + (, uint256 _shares) = MORPHO_BLUE.supply(_marketParams, _amt, 0, address(this), new bytes(0)); setUint(_setId, _amt); - _eventName = "LogSupply(address,uint256,uint256,address,bytes,uint256,uint256)"; + _eventName = "LogSupplyAssets((address,address,address,address,unit256),unit256,unit256,unit256,unit256)"; _eventParam = abi.encode( - _marketParams.loanToken, + _marketParams, _assets, _shares, - address(this), - _data, _getId, _setId ); } /** - * @dev Supplying a large amount can revert for overflow. - * @notice Supplies `assets` or `shares` on behalf of `onBehalf`, optionally calling back the caller's `onMorphoSupply` function with the given `data`. - * @param _marketParams 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE native token is not allowed in this mode cause of failing in withdraw of WETH. + * @dev Supply ETH/ERC20 Token for lending. + * @notice Supplies assets to Morpho Blue for lending. + * @param _marketParams The market to supply assets to.(For ETH of loanToken in _marketParams: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) * @param _assets The amount of assets to supply. - * @param _shares The amount of shares to mint. - * @param _onBehalf The address that will own the increased supply position. - * @param _data Arbitrary data to pass to the `onMorphoSupply` callback. Pass empty data if not needed. + * @param _onBehalf The address that will get the shares. * @param _getId ID to retrieve amt. * @param _setId ID stores the amount of tokens deposited. */ function supplyOnBehalf( MarketParams memory _marketParams, uint256 _assets, - uint256 _shares, address _onBehalf, - bytes calldata _data, uint256 _getId, uint256 _setId ) @@ -83,21 +72,120 @@ abstract contract MorphoBlue is Helpers, Events { payable returns (string memory _eventName, bytes memory _eventParam) { - uint256 _amt = getUint(_getId, _assets); + // Final assets amount and token contract + ( + TokenInterface _tokenContract, // Loan token contract + uint256 _amt + ) = _performEthToWethConversion(_marketParams, _assets, _onBehalf, _getId, false, false); - approve(TokenInterface(_marketParams.loanToken), address(MORPHO_BLUE), _amt); + // Approving loan token for supplying + approve(_tokenContract, address(MORPHO_BLUE), _amt); + + // Updating token addresses + _marketParams.loanToken = address(_tokenContract); + _marketParams.collateralToken = _marketParams.collateralToken == ethAddr ? wethAddr : _marketParams.collateralToken; - (_assets, _shares) = MORPHO_BLUE.supply(_marketParams, _assets, _shares, _onBehalf, _data); + (, uint256 _shares) = MORPHO_BLUE.supply(_marketParams, _amt, 0, _onBehalf, new bytes(0)); setUint(_setId, _amt); - _eventName = "LogSupply(address,uint256,uint256,address,bytes,uint256,uint256)"; + _eventName = "LogSupplyAssetsOnBehalf((address,address,address,address,unit256),uint256,uint256,address,uint256,uint256)"; _eventParam = abi.encode( - _marketParams.loanToken, + _marketParams, _assets, _shares, _onBehalf, - _data, + _getId, + _setId + ); + } + + /** + * @dev Supply ETH/ERC20 Token for lending. + * @notice Supplies assets for a perfect share amount to Morpho Blue for lending. + * @param _marketParams The market to supply assets to. (For ETH of loanToken in _marketParams: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) + * @param _shares The amount of shares to mint. + * @param _onBehalf The address that will get the shares. + * @param _getId ID to retrieve amt. + * @param _setId ID stores the amount of tokens deposited. + */ + function supplySharesOnBehalf( + MarketParams memory _marketParams, + uint256 _shares, + address _onBehalf, + uint256 _getId, + uint256 _setId + ) + external + payable + returns (string memory _eventName, bytes memory _eventParam) + { + // Final converted assets amount for approval and token contract + ( + TokenInterface _tokenContract, // Loan token contract + uint256 _amt + ) = _performEthToWethSharesConversion(_marketParams, _shares, _onBehalf, _getId, false); + + // Approving loan token for supplying + approve(_tokenContract, address(MORPHO_BLUE), _amt); + + // Updating token addresses + _marketParams.loanToken = address(_tokenContract); + _marketParams.collateralToken = _marketParams.collateralToken == ethAddr ? wethAddr : _marketParams.collateralToken; + + (uint256 _assets, ) = MORPHO_BLUE.supply(_marketParams, _amt, _shares, _onBehalf, new bytes(0)); + + setUint(_setId, _amt); + + _eventName = "LogSupplySharesOnBehalf((address,address,address,address,unit256),uint256,uint256,address,uint256,uint256)"; + _eventParam = abi.encode( + _marketParams, + _assets, + _shares, + _onBehalf, + _getId, + _setId + ); + } + + /** + * @notice Supply ETH/ERC20 Token for collateralization. + * @param _marketParams The market to supply assets to. (For ETH of loanToken in _marketParams: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) + * @param _assets The amount of assets to supply. + * @param _getId ID to retrieve amt. + * @param _setId ID stores the amount of tokens deposited. + */ + function supplyCollateral( + MarketParams memory _marketParams, + uint256 _assets, + uint256 _getId, + uint256 _setId + ) + external + payable + returns (string memory _eventName, bytes memory _eventParam) + { + // Final assets amount and token contract + ( + TokenInterface _tokenContract, // Collateral token contract + uint256 _amt + ) = _performEthToWethConversion(_marketParams, _assets, address(this), _getId, true, false); + + // Approving collateral token + approve(_tokenContract, address(MORPHO_BLUE), _amt); + + // Updating token addresses + _marketParams.collateralToken = address(_tokenContract); + _marketParams.loanToken = _marketParams.loanToken == ethAddr ? wethAddr : _marketParams.loanToken; + + MORPHO_BLUE.supplyCollateral(_marketParams, _amt, address(this), new bytes(0)); + + setUint(_setId, _amt); + + _eventName = "LogSupplyCollateral((address,address,address,address,unit256),uint256,uint256,uint256)"; + _eventParam = abi.encode( + _marketParams, + _assets, _getId, _setId ); @@ -107,50 +195,7 @@ abstract contract MorphoBlue is Helpers, Events { * @notice Supplies `assets` of collateral on behalf of `onBehalf`, optionally calling back the caller's `onMorphoSupplyCollateral` function with the given `data`. * @param _marketParams The market to supply assets to.(For ETH of loanToken in _marketParams: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) * @param _assets The amount of assets to supply. - * @param _data Arbitrary data to pass to the `onMorphoSupply` callback. Pass empty data if not needed. - * @param _getId ID to retrieve amt. - * @param _setId ID stores the amount of tokens deposited. - */ - function supplyCollateral( - MarketParams memory _marketParams, - uint256 _assets, - bytes calldata _data, - uint256 _getId, - uint256 _setId - ) - external - payable - returns (string memory _eventName, bytes memory _eventParam) - { - ( - TokenInterface _tokenContract, - uint256 _amt, - ) = _performEthToWethConversion(_marketParams.loanToken, _assets, _getId); - - approve(_tokenContract, address(MORPHO_BLUE), _amt); - _marketParams.loanToken = address(_tokenContract); - - MORPHO_BLUE.supplyCollateral(_marketParams, _assets, address(this), _data); - - setUint(_setId, _amt); - - _eventName = "LogSupplyCollateral(address,uint256,address,bytes,uint256,uint256)"; - _eventParam = abi.encode( - _marketParams.loanToken, - _assets, - address(this), - _data, - _getId, - _setId - ); - } - - /** - * @notice Supplies `assets` of collateral on behalf of `onBehalf`, optionally calling back the caller's `onMorphoSupplyCollateral` function with the given `data`. - * @param _marketParams 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE native token is not allowed in this mode cause of failing in withdraw of WETH. - * @param _assets The amount of assets to supply. - * @param _onBehalf The address that will own the increased supply position. - * @param _data Arbitrary data to pass to the `onMorphoSupply` callback. Pass empty data if not needed. + * @param _onBehalf The address that will get the shares. * @param _getId ID to retrieve amt. * @param _setId ID stores the amount of tokens deposited. */ @@ -158,7 +203,51 @@ abstract contract MorphoBlue is Helpers, Events { MarketParams memory _marketParams, uint256 _assets, address _onBehalf, - bytes calldata _data, + uint256 _getId, + uint256 _setId + ) + external + payable + returns (string memory _eventName, bytes memory _eventParam) + { + // Final assets amount and token contract + ( + TokenInterface _tokenContract, // Collateral token contract + uint256 _amt + ) = _performEthToWethConversion(_marketParams, _assets, _onBehalf, _getId, true, false); + + // Approving collateral token + approve(_tokenContract, address(MORPHO_BLUE), _amt); + + // Updating token addresses + _marketParams.collateralToken = address(_tokenContract); + _marketParams.loanToken = _marketParams.loanToken == ethAddr ? wethAddr : _marketParams.loanToken; + + MORPHO_BLUE.supplyCollateral(_marketParams, _amt, _onBehalf, new bytes(0)); + + setUint(_setId, _amt); + + _eventName = "LogSupplyCollateralOnBehalf((address,address,address,address,unit256),uint256,address,uint256,uint256)"; + _eventParam = abi.encode( + _marketParams, + _assets, + _onBehalf, + _getId, + _setId + ); + } + + /** + * @notice Handles the withdrawal of collateral by a user from a specific market of a specific amount. + * @dev The market to withdraw assets from. (For ETH of loanToken in _marketParams: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) + * @param _marketParams The market to withdraw assets from. + * @param _assets The amount of assets to withdraw. + * @param _getId ID to retrieve amt. + * @param _setId ID stores the amount of tokens deposited. + */ + function withdrawCollateral( + MarketParams memory _marketParams, + uint256 _assets, uint256 _getId, uint256 _setId ) @@ -168,29 +257,38 @@ abstract contract MorphoBlue is Helpers, Events { { uint256 _amt = getUint(_getId, _assets); - approve(TokenInterface(_marketParams.loanToken), address(MORPHO_BLUE), _amt); + // Updating token addresses + bool _collateralIsEth = _marketParams.collateralToken == ethAddr; + _marketParams.collateralToken = _collateralIsEth ? wethAddr : _marketParams.collateralToken; + _marketParams.loanToken = _marketParams.loanToken == ethAddr ? wethAddr : _marketParams.loanToken; - MORPHO_BLUE.supplyCollateral(_marketParams, _assets, _onBehalf, _data); + // If amount is max, fetch collateral value from Morpho's contract + if (_assets == type(uint256).max) { + bytes32 _id = id(_marketParams); + Position memory _pos = MORPHO_BLUE.position(_id, address(this)); + _amt = _pos.collateral; + } + + MORPHO_BLUE.withdrawCollateral(_marketParams, _amt, address(this), address(this)); + + convertWethToEth(_collateralIsEth, TokenInterface(wethAddr), _amt); setUint(_setId, _amt); - _eventName = "LogSupplyCollateral(address,uint256,address,bytes,uint256,uint256)"; + _eventName = "LogWithdrawCollateral((address,address,address,address,unit256),uint256,uint256,uint256)"; _eventParam = abi.encode( - _marketParams.loanToken, - _assets, - _onBehalf, - _data, + _marketParams, + _amt, _getId, _setId ); } /** - * @notice Supplies `assets` or `shares` on behalf of `onBehalf`, optionally calling back the caller's `onMorphoSupply` function with the given `data`. - * @dev Supplying a large amount can revert for overflow. - * @dev 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE native token is not allowed in this mode cause of failing in withdraw of WETH. - * @param _marketParams The market to supply assets to. - * @param _assets The amount of assets to supply. + * @notice Handles the withdrawal of collateral by a user from a specific market of a specific amount. + * @dev The market to withdraw assets from. (For ETH of loanToken in _marketParams: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) + * @param _marketParams The market to withdraw assets from. + * @param _assets The amount of assets to withdraw. * @param _onBehalf The address that already deposited position. * @param _getId ID to retrieve amt. * @param _setId ID stores the amount of tokens deposited. @@ -199,6 +297,7 @@ abstract contract MorphoBlue is Helpers, Events { MarketParams memory _marketParams, uint256 _assets, address _onBehalf, + address _receiver, uint256 _getId, uint256 _setId ) @@ -206,140 +305,47 @@ abstract contract MorphoBlue is Helpers, Events { payable returns (string memory _eventName, bytes memory _eventParam) { - uint256 _amt = getUint(_getId, _assets); - if (_amt == uint256(-1)) { + + // Updating token addresses + bool _collateralIsEth = _marketParams.collateralToken == ethAddr; + _marketParams.collateralToken = _collateralIsEth ? wethAddr : _marketParams.collateralToken; + _marketParams.loanToken = _marketParams.loanToken == ethAddr ? wethAddr : _marketParams.loanToken; + + if (_amt == type(uint256).max) { bytes32 _id = id(_marketParams); Position memory _pos = MORPHO_BLUE.position(_id, _onBehalf); _amt = _pos.collateral; } - MORPHO_BLUE.withdrawCollateral(_marketParams, _amt, _onBehalf, address(this)); + MORPHO_BLUE.withdrawCollateral(_marketParams, _amt, _onBehalf, _receiver); + + if(_receiver == address(this)) convertWethToEth(_collateralIsEth, TokenInterface(wethAddr), _amt); setUint(_setId, _amt); - _eventName = "LogWithdrawCollateral(address,uint256,address,uint256,uint256)"; + _eventName = "LogWithdrawCollateralOnBehalf((address,address,address,address,unit256),uint256,address,address,uint256,uint256)"; _eventParam = abi.encode( - _marketParams.loanToken, + _marketParams, _amt, _onBehalf, + _receiver, _getId, _setId ); } /** - * @notice Supplies `assets` or `shares` on behalf of `onBehalf`, optionally calling back the caller's `onMorphoSupply` function with the given `data`. - * @dev Supplying a large amount can revert for overflow. - * @dev The market to supply assets to.(For ETH of loanToken in _marketParams: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) - * @param _marketParams The market to supply assets to. - * @param _assets The amount of assets to supply. - * @param _shares The amount of shares to mint. - * @param _getId ID to retrieve amt. - * @param _setId ID stores the amount of tokens deposited. - */ - function withdrawCollateral( - MarketParams memory _marketParams, - uint256 _assets, - uint256 _shares, - uint256 _getId, - uint256 _setId - ) - external - payable - returns (string memory _eventName, bytes memory _eventParam) - { - uint256 _amt; - ( - TokenInterface _tokenContract, - , - bool _isMax - ) = _performEthToWethConversion(_marketParams.loanToken, _assets, _getId); - if (_isMax) { - bytes32 _id = id(_marketParams); - Position memory _pos = MORPHO_BLUE.position(_id, address(this)); - _amt = _pos.collateral; - } - address originToken = _marketParams.loanToken; - _marketParams.loanToken = address(_tokenContract); - - MORPHO_BLUE.withdrawCollateral(_marketParams, _amt, address(this), address(this)); - - convertWethToEth(originToken == ethAddr, TokenInterface(wethAddr), _amt); - - setUint(_setId, _amt); - - _eventName = "LogWithdraw(address,uint256,uint256,address,uint256,uint256)"; - _eventParam = abi.encode( - _marketParams.loanToken, - _amt, - _shares, - address(this), - _getId, - _setId - ); - } - - /** - * @notice Supplies `assets` or `shares` on behalf of `onBehalf`, optionally calling back the caller's `onMorphoSupply` function with the given `data`. - * @dev Supplying a large amount can revert for overflow. - * @dev 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE native token is not allowed in this mode cause of failing in withdraw of WETH. - * @param _marketParams The market to supply assets to. - * @param _assets The amount of assets to supply. - * @param _shares The amount of shares to mint. - * @param _onBehalf The address that already deposited position. - * @param _getId ID to retrieve amt. - * @param _setId ID stores the amount of tokens deposited. - */ - function withdrawOnBehalf( - MarketParams memory _marketParams, - uint256 _assets, - uint256 _shares, - address _onBehalf, - uint256 _getId, - uint256 _setId - ) - external - payable - returns (string memory _eventName, bytes memory _eventParam) - { - - uint256 _amt = getUint(_getId, _assets); - bool _isMax; - if (_amt == uint256(-1)) { - _amt = TokenInterface(_marketParams.loanToken).balanceOf(_onBehalf); - _isMax = true; - } - - MORPHO_BLUE.withdraw(_marketParams, (_isMax ? 0 : _amt), (_isMax ? _amt : _shares), _onBehalf, address(this)); - - setUint(_setId, _amt); - - _eventName = "LogWithdraw(address,uint256,uint256,address,uint256,uint256)"; - _eventParam = abi.encode( - _marketParams.loanToken, - _amt, - _shares, - _onBehalf, - _getId, - _setId - ); - } - - /** - * @notice Supplies `assets` or `shares` on behalf of `onBehalf`, optionally calling back the caller's `onMorphoSupply` function with the given `data`. - * @dev Supplying a large amount can revert for overflow. - * @dev The market to supply assets to.(For ETH of loanToken in _marketParams: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) - * @param _marketParams The market to supply assets to. - * @param _assets The amount of assets to supply. - * @param _shares The amount of shares to mint. + * @notice Handles the withdrawal of supply. + * @dev The market to withdraw assets from.(For ETH of loanToken in _marketParams: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) + * @param _marketParams The market to withdraw assets from. + * @param _assets The amount of assets to withdraw. * @param _getId ID to retrieve amt. * @param _setId ID stores the amount of tokens deposited. */ function withdraw( MarketParams memory _marketParams, uint256 _assets, - uint256 _shares, uint256 _getId, uint256 _setId ) @@ -347,46 +353,45 @@ abstract contract MorphoBlue is Helpers, Events { payable returns (string memory _eventName, bytes memory _eventParam) { + uint256 _amt = getUint(_getId, _assets); + bool _isEth = _marketParams.loanToken == ethAddr; + _marketParams.loanToken = _isEth ? wethAddr : _marketParams.loanToken; + _marketParams.collateralToken = _marketParams.collateralToken == ethAddr ? wethAddr : _marketParams.collateralToken; - ( - TokenInterface _tokenContract, - uint256 _amt, - bool _isMax - ) = _performEthToWethConversion(_marketParams.loanToken, _assets, _getId); - address originToken = _marketParams.loanToken; - _marketParams.loanToken = address(_tokenContract); + if (_amt == type(uint256).max) { + bytes32 _id = id(_marketParams); + Position memory _pos = MORPHO_BLUE.position(_id, address(this)); + uint256 _shares = _pos.supplyShares; + _amt = _toAssetsUp(_shares, MORPHO_BLUE.market(_id).totalSupplyAssets, MORPHO_BLUE.market(_id).totalSupplyShares); + } - (_assets, _shares) = MORPHO_BLUE.withdraw(_marketParams, (_isMax ? 0 : _amt), (_isMax ? _amt : _shares), address(this), address(this)); + MORPHO_BLUE.withdraw(_marketParams, _amt, 0, address(this), address(this)); - convertWethToEth(originToken == ethAddr, TokenInterface(wethAddr), _amt); + convertWethToEth(_isEth, TokenInterface(wethAddr), _amt); setUint(_setId, _amt); - _eventName = "LogWithdraw(address,uint256,uint256,address,uint256,uint256)"; + _eventName = "LogWithdraw((address,address,address,address,unit256),uint256,uint256,uint256)"; _eventParam = abi.encode( - _marketParams.loanToken, + _marketParams, _amt, - _shares, - address(this), _getId, _setId ); } /** - * @notice Borrows `assets` or `shares` on behalf of `onBehalf` to `receiver`. receiver should be address(this) - * @dev 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE native token is not allowed in this mode cause of failing in withdraw of WETH. - * @param _marketParams The market to supply assets to. - * @param _assets The amount of assets to supply. - * @param _shares The amount of shares to mint. - * @param _onBehalf The address that will own the borrow position. + * @notice Handles the withdrawal of a specified amount of assets by a user from a specific market. + * @dev The market to withdraw assets from. (For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) + * @param _marketParams The parameters of the market. + * @param _assets The amount of assets the user is withdrawing. + * @param _onBehalf The address who's position to withdraw from. * @param _getId ID to retrieve amt. - * @param _setId ID stores the amount of tokens borrowed. + * @param _setId ID stores the amount of tokens deposited. */ - function borrowOnBehalf( + function withdrawOnBehalf( MarketParams memory _marketParams, uint256 _assets, - uint256 _shares, address _onBehalf, uint256 _getId, uint256 _setId @@ -396,14 +401,303 @@ abstract contract MorphoBlue is Helpers, Events { returns (string memory _eventName, bytes memory _eventParam) { uint256 _amt = getUint(_getId, _assets); + _marketParams.loanToken = _marketParams.loanToken == ethAddr ? wethAddr : _marketParams.loanToken; + _marketParams.collateralToken = _marketParams.collateralToken == ethAddr ? wethAddr : _marketParams.collateralToken; - (_assets, _shares) = MORPHO_BLUE.borrow(_marketParams, _amt, _shares, _onBehalf, address(this)); + if (_amt == type(uint256).max) { + bytes32 _id = id(_marketParams); + Position memory _pos = MORPHO_BLUE.position(_id, _onBehalf); + uint256 _shares = _pos.supplyShares; + _amt = _toAssetsUp(_shares, MORPHO_BLUE.market(_id).totalSupplyAssets, MORPHO_BLUE.market(_id).totalSupplyShares); + } + + MORPHO_BLUE.withdraw(_marketParams, _amt, 0, _onBehalf, address(this)); setUint(_setId, _amt); - _eventName = "LogBorrow(address,uint256,uint256,address,uint256,uint256)"; + _eventName = "LogWithdrawOnBehalf((address,address,address,address,unit256),uint256,address,uint256,uint256)"; _eventParam = abi.encode( - _marketParams.loanToken, + _marketParams, + _amt, + _onBehalf, + _getId, + _setId + ); + } + + /** + * @notice Handles the withdrawal of a specified amount of assets by a user from a specific market. + * @dev The market to withdraw assets from. (For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) + * @param _marketParams The parameters of the market. + * @param _shares The amount of shares the user is withdrawing. + * @param _onBehalf The address who's position to withdraw from. + * @param _getId ID to retrieve amt. + * @param _setId ID stores the amount of tokens deposited. + */ + function withdrawSharesOnBehalf( + MarketParams memory _marketParams, + uint256 _shares, + address _onBehalf, + uint256 _getId, + uint256 _setId + ) + external + payable + returns (string memory _eventName, bytes memory _eventParam) + { + uint256 _shareAmt = getUint(_getId, _shares); + _marketParams.loanToken = _marketParams.loanToken == ethAddr ? wethAddr : _marketParams.loanToken; + _marketParams.collateralToken = _marketParams.collateralToken == ethAddr ? wethAddr : _marketParams.collateralToken; + + if (_shareAmt == type(uint256).max) { + bytes32 _id = id(_marketParams); + Position memory _pos = MORPHO_BLUE.position(_id, _onBehalf); + _shareAmt = _pos.supplyShares; + } + + MORPHO_BLUE.withdraw(_marketParams, 0, _shareAmt, _onBehalf, address(this)); + + setUint(_setId, _shareAmt); + + _eventName = "LogWithdrawSharesOnBehalf((address,address,address,address,unit256),uint256,address,uint256,uint256)"; + _eventParam = abi.encode( + _marketParams, + _shareAmt, + _onBehalf, + _getId, + _setId + ); + } + + /** + * @notice Borrows assets. + * @dev The market to borrow assets from.(For ETH of loanToken in _marketParams: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) + * @param _marketParams The market to borrow assets from. + * @param _assets The amount of assets to borrow. + * @param _getId ID to retrieve amt. + * @param _setId ID stores the amount of tokens borrowed. + */ + function borrow( + MarketParams memory _marketParams, + uint256 _assets, + uint256 _getId, + uint256 _setId + ) + external + payable + returns (string memory _eventName, bytes memory _eventParam) + { + uint256 _amt = getUint(_getId, _assets); + bool _isETH = _marketParams.loanToken == ethAddr; + + _marketParams.loanToken = _isETH ? wethAddr : _marketParams.loanToken; + _marketParams.collateralToken = _marketParams.collateralToken == ethAddr ? wethAddr : _marketParams.collateralToken; + + (, uint256 _shares) = MORPHO_BLUE.borrow(_marketParams, _amt, 0, address(this), address(this)); + + convertWethToEth(_isETH, TokenInterface(wethAddr), _amt); + + setUint(_setId, _amt); + + _eventName = "LogBorrow((address,address,address,address,unit256),uint256,uint256,uint256,uint256)"; + _eventParam = abi.encode( + _marketParams, + _amt, + _shares, + _getId, + _setId + ); + } + + /** + * @notice Borrows `assets` on behalf of `onBehalf` to `receiver`. + * @dev The market to borrow assets from. (For ETH of loanToken in _marketParams: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) + * @param _marketParams The market to borrow assets from. + * @param _assets The amount of assets to borrow. + * @param _onBehalf The address that will recieve the borrowing assets and own the borrow position. + * @param _receiver The address that will recieve the borrowed assets. + * @param _getId ID to retrieve amt. + * @param _setId ID stores the amount of tokens borrowed. + */ + function borrowOnBehalf( + MarketParams memory _marketParams, + uint256 _assets, + address _onBehalf, + address _receiver, + uint256 _getId, + uint256 _setId + ) + external + payable + returns (string memory _eventName, bytes memory _eventParam) + { + uint256 _amt = getUint(_getId, _assets); + bool _isETH = _marketParams.loanToken == ethAddr; + + _marketParams.loanToken = _isETH ? wethAddr : _marketParams.loanToken; + _marketParams.collateralToken = _marketParams.collateralToken == ethAddr ? wethAddr : _marketParams.collateralToken; + + (, uint256 _shares) = MORPHO_BLUE.borrow(_marketParams, _amt, 0, _onBehalf, _receiver); + + if (_receiver == address(this)) convertWethToEth(_isETH, TokenInterface(wethAddr), _amt); + + setUint(_setId, _amt); + + _eventName = "LogBorrowOnBehalf((address,address,address,address,unit256),uint256,uint256,address,address,uint256,uint256)"; + _eventParam = abi.encode( + _marketParams, + _amt, + _shares, + _onBehalf, + _receiver, + _getId, + _setId + ); + } + + /** + * @notice Borrows `shares` on behalf of `onBehalf` to `receiver`. + * @dev The market to borrow assets from. (For ETH of loanToken in _marketParams: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) + * @param _marketParams The market to borrow assets from. + * @param _shares The amount of shares to mint. + * @param _onBehalf The address that will own the borrow position. + * @param _receiver The address that will recieve the borrowed assets. + * @param _getId ID to retrieve shares amt. + * @param _setId ID stores the amount of tokens borrowed. + */ + function borrowOnBehalfShares( + MarketParams memory _marketParams, + uint256 _shares, + address _onBehalf, + address _receiver, + uint256 _getId, + uint256 _setId + ) + external + payable + returns (string memory _eventName, bytes memory _eventParam) + { + uint256 _shareAmt = getUint(_getId, _shares); + bool _isETH = _marketParams.loanToken == ethAddr; + + _marketParams.loanToken = _isETH ? wethAddr : _marketParams.loanToken; + _marketParams.collateralToken = _marketParams.collateralToken == ethAddr ? wethAddr : _marketParams.collateralToken; + + (uint256 _assets, ) = MORPHO_BLUE.borrow(_marketParams, 0, _shareAmt, _onBehalf, _receiver); + + if (_receiver == address(this)) convertWethToEth(_isETH, TokenInterface(wethAddr), _assets); + + setUint(_setId, _assets); + + _eventName = "LogBorrowShares((address,address,address,address,unit256),uint256,uint256,address,address,uint256,uint256)"; + _eventParam = abi.encode( + _marketParams, + _assets, + _shareAmt, + _onBehalf, + _receiver, + _getId, + _setId + ); + } + + /** + * @notice Repays assets. + * @dev The market to repay assets to. (For ETH of loanToken in _marketParams: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) + * @param _marketParams The market to repay assets to. + * @param _assets The amount of assets to repay. + * @param _getId ID to retrieve amt. + * @param _setId ID stores the amount of tokens repaid. + */ + function repay( + MarketParams memory _marketParams, + uint256 _assets, + uint256 _getId, + uint256 _setId + ) + external + payable + returns (string memory _eventName, bytes memory _eventParam) + { + // Final assets amount and token contract + ( + TokenInterface _tokenContract, + uint256 _amt // Assets final amount to repay + ) = _performEthToWethConversion(_marketParams, _assets, address(this), _getId, false, true); + + // Approving loan token for repaying + approve(_tokenContract, address(MORPHO_BLUE), _amt); + + // Updating token addresses + _marketParams.loanToken = address(_tokenContract); + _marketParams.collateralToken = _marketParams.collateralToken == ethAddr ? wethAddr : _marketParams.collateralToken; + + (, uint256 _shares) = MORPHO_BLUE.repay( + _marketParams, + _amt, + 0, + address(this), + new bytes(0) + ); + + setUint(_setId, _amt); + + _eventName = "LogPayback((address,address,address,address,unit256),uint256,uint256,uint256,uint256)"; + _eventParam = abi.encode( + _marketParams, + _assets, + _shares, + _getId, + _setId + ); + } + + /** + * @notice Repays assets on behalf. + * @dev The market to repay assets to. (For ETH of loanToken in _marketParams: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) + * @param _marketParams The market to repay assets to. + * @param _assets The amount of assets to repay. + * @param _onBehalf The address whose loan will be repaid. + * @param _getId ID to retrieve amt. + * @param _setId ID stores the amount of tokens repaid. + */ + function repayOnBehalf( + MarketParams memory _marketParams, + uint256 _assets, + address _onBehalf, + uint256 _getId, + uint256 _setId + ) + external + payable + returns (string memory _eventName, bytes memory _eventParam) + { + // Final assets amount and token contract + ( + TokenInterface _tokenContract, + uint256 _amt // Assets final amount to repay + ) = _performEthToWethConversion(_marketParams, _assets, _onBehalf, _getId, false, true); + + // Approving loan token for repaying + approve(_tokenContract, address(MORPHO_BLUE), _amt); + + // Updating token addresses + _marketParams.loanToken = address(_tokenContract); + _marketParams.collateralToken = _marketParams.collateralToken == ethAddr ? wethAddr : _marketParams.collateralToken; + + (, uint256 _shares) = MORPHO_BLUE.repay( + _marketParams, + _amt, + 0, + _onBehalf, + new bytes(0) + ); + + setUint(_setId, _amt); + + _eventName = "LogPaybackOnBehalf((address,address,address,address,unit256),uint256,uint256,address,uint256,uint256)"; + _eventParam = abi.encode( + _marketParams, _assets, _shares, _onBehalf, @@ -413,118 +707,18 @@ abstract contract MorphoBlue is Helpers, Events { } /** - * @notice Borrows `assets` or `shares`. receiver should be address(this) - * @dev The market to supply assets to.(For ETH of loanToken in _marketParams: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) - * @param _marketParams The market to supply assets to. - * @param _assets The amount of assets to supply. - * @param _shares The amount of shares to mint. + * @notice Repays shares on behalf. + * @dev The market to repay assets to. (For ETH of loanToken in _marketParams: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) + * @param _marketParams The market to repay assets to. + * @param _shares The amount of shares to burn. + * @param _onBehalf The address whose loan will be repaid. * @param _getId ID to retrieve amt. - * @param _setId ID stores the amount of tokens borrowed. + * @param _setId ID stores the amount of tokens repaid. */ - function borrow( + function repayOnBehalfShares( MarketParams memory _marketParams, - uint256 _assets, - uint256 _shares, - uint256 _getId, - uint256 _setId - ) - external - payable - returns (string memory _eventName, bytes memory _eventParam) - { - ( - TokenInterface _tokenContract, - uint256 _amt, - ) = _performEthToWethConversion(_marketParams.loanToken, _assets, _getId); - - address _oldLoanToken = _marketParams.loanToken; - _marketParams.loanToken = address(_tokenContract); - - (_assets, _shares) = MORPHO_BLUE.borrow(_marketParams, _amt, _shares, address(this), address(this)); - - convertWethToEth(_oldLoanToken == ethAddr, TokenInterface(wethAddr), _amt); - - setUint(_setId, _amt); - - _eventName = "LogBorrow(address,uint256,uint256,address,uint256,uint256)"; - _eventParam = abi.encode( - _marketParams.loanToken, - _assets, - _shares, - address(this), - _getId, - _setId - ); - } - - /** - * @notice Repays `assets` or `shares`. - * @dev The market to supply assets to.(For ETH of loanToken in _marketParams: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) - * @param _marketParams The market to supply assets to. - * @param _assets The amount of assets to supply. - * @param _shares The amount of shares to mint. - * @param _data Arbitrary data to pass to the `onMorphoRepay` callback. Pass empty data if not needed. - * @param _getId ID to retrieve amt. - * @param _setId ID stores the amount of tokens borrowed. - */ - function repay( - MarketParams memory _marketParams, - uint256 _assets, - uint256 _shares, - bytes memory _data, - uint256 _getId, - uint256 _setId - ) - external - payable - returns (string memory _eventName, bytes memory _eventParam) - { - ( - TokenInterface _tokenContract, - uint256 _amt, - bool _isMax - ) = _performEthToWethConversion(_marketParams.loanToken, _assets, _getId); - - address _oldLoanToken = _marketParams.loanToken; - _marketParams.loanToken = address(_tokenContract); - - approve(TokenInterface(_marketParams.loanToken), address(MORPHO_BLUE), _amt); - - (_assets, _shares) = MORPHO_BLUE.repay(_marketParams, (_isMax ? 0 : _amt), (_isMax ? _amt : _shares), address(this), _data); - - convertWethToEth(_oldLoanToken == ethAddr, TokenInterface(wethAddr), _amt); - - setUint(_setId, _amt); - - _eventName = "LogPayback(address,uint256,uint256,address,bytes,uint256,uint256)"; - _eventParam = abi.encode( - _marketParams.loanToken, - _assets, - _shares, - address(this), - _data, - _getId, - _setId - ); - } - - /** - * @notice Repays `assets` or `shares` on behalf of `onBehalf`, optionally calling back the caller's `onMorphoReplay` function with the given `data`. - * @dev 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE native token is not allowed in this mode cause of failing in withdraw of WETH. - * @param _marketParams The market to supply assets to. - * @param _assets The amount of assets to supply. - * @param _shares The amount of shares to mint. - * @param _onBehalf The address that will own the borrow position. - * @param _data Arbitrary data to pass to the `onMorphoRepay` callback. Pass empty data if not needed. - * @param _getId ID to retrieve amt. - * @param _setId ID stores the amount of tokens borrowed. - */ - function repayOnBehalf( - MarketParams memory _marketParams, - uint256 _assets, uint256 _shares, address _onBehalf, - bytes memory _data, uint256 _getId, uint256 _setId ) @@ -532,26 +726,30 @@ abstract contract MorphoBlue is Helpers, Events { payable returns (string memory _eventName, bytes memory _eventParam) { - uint256 _amt = getUint(_getId, _assets); - bool _isMax; - if (_amt == uint256(-1)) { - _amt = TokenInterface(_marketParams.loanToken).balanceOf(_onBehalf); - _isMax = true; - } + // Final assets amount and token contract + ( + TokenInterface _tokenContract, + uint256 _assetsAmt // Assets final amount to repay + ) = _performEthToWethSharesConversion(_marketParams, _shares, _onBehalf, _getId, true); - approve(TokenInterface(_marketParams.loanToken), address(MORPHO_BLUE), _amt); + approve(_tokenContract, address(MORPHO_BLUE), _assetsAmt); - (_assets, _shares) = MORPHO_BLUE.repay(_marketParams, (_isMax ? 0 : _amt), (_isMax ? _amt : _shares), address(this), _data); + (uint256 _assets, ) = MORPHO_BLUE.repay( + _marketParams, + _assetsAmt, + 0, + _onBehalf, + new bytes(0) + ); - setUint(_setId, _amt); + setUint(_setId, _assets); - _eventName = "LogPayback(address,uint256,uint256,address,bytes,uint256,uint256)"; + _eventName = "LogPaybackShares((address,address,address,address,unit256),uint256,uint256,address,uint256,uint256)"; _eventParam = abi.encode( - _marketParams.loanToken, + _marketParams, _assets, _shares, - address(this), - _data, + _onBehalf, _getId, _setId );