diff --git a/src/MetaMorpho.sol b/src/MetaMorpho.sol index b64f6656..8f26222c 100644 --- a/src/MetaMorpho.sol +++ b/src/MetaMorpho.sol @@ -472,14 +472,14 @@ contract MetaMorpho is ERC4626, ERC20Permit, Ownable2Step, Multicall, IMetaMorph function maxRedeem(address owner) public view override(IERC4626, ERC4626) returns (uint256) { (uint256 assets, uint256 newTotalSupply, uint256 newTotalAssets) = _maxWithdraw(owner); - return _convertToSharesWithFeeAccrued(assets, newTotalSupply, newTotalAssets, Math.Rounding.Floor); + return _convertToSharesWithTotals(assets, newTotalSupply, newTotalAssets, Math.Rounding.Floor); } /// @inheritdoc IERC4626 function deposit(uint256 assets, address receiver) public override(IERC4626, ERC4626) returns (uint256 shares) { uint256 newTotalAssets = _accrueFee(); - shares = _convertToSharesWithFeeAccrued(assets, totalSupply(), newTotalAssets, Math.Rounding.Floor); + shares = _convertToSharesWithTotals(assets, totalSupply(), newTotalAssets, Math.Rounding.Floor); _deposit(_msgSender(), receiver, assets, shares); } @@ -487,7 +487,7 @@ contract MetaMorpho is ERC4626, ERC20Permit, Ownable2Step, Multicall, IMetaMorph function mint(uint256 shares, address receiver) public override(IERC4626, ERC4626) returns (uint256 assets) { uint256 newTotalAssets = _accrueFee(); - assets = _convertToAssetsWithFeeAccrued(shares, totalSupply(), newTotalAssets, Math.Rounding.Ceil); + assets = _convertToAssetsWithTotals(shares, totalSupply(), newTotalAssets, Math.Rounding.Ceil); _deposit(_msgSender(), receiver, assets, shares); } @@ -501,7 +501,7 @@ contract MetaMorpho is ERC4626, ERC20Permit, Ownable2Step, Multicall, IMetaMorph // Do not call expensive `maxWithdraw` and optimistically withdraw assets. - shares = _convertToSharesWithFeeAccrued(assets, totalSupply(), newTotalAssets, Math.Rounding.Ceil); + shares = _convertToSharesWithTotals(assets, totalSupply(), newTotalAssets, Math.Rounding.Ceil); _withdraw(_msgSender(), receiver, owner, assets, shares); } @@ -515,7 +515,7 @@ contract MetaMorpho is ERC4626, ERC20Permit, Ownable2Step, Multicall, IMetaMorph // Do not call expensive `maxRedeem` and optimistically redeem shares. - assets = _convertToAssetsWithFeeAccrued(shares, totalSupply(), newTotalAssets, Math.Rounding.Floor); + assets = _convertToAssetsWithTotals(shares, totalSupply(), newTotalAssets, Math.Rounding.Floor); _withdraw(_msgSender(), receiver, owner, assets, shares); } @@ -548,7 +548,7 @@ contract MetaMorpho is ERC4626, ERC20Permit, Ownable2Step, Multicall, IMetaMorph (feeShares, newTotalAssets) = _accruedFeeShares(); newTotalSupply = totalSupply() + feeShares; - assets = _convertToAssetsWithFeeAccrued(balanceOf(owner), newTotalSupply, newTotalAssets, Math.Rounding.Floor); + assets = _convertToAssetsWithTotals(balanceOf(owner), newTotalSupply, newTotalAssets, Math.Rounding.Floor); assets -= _staticWithdrawMorpho(assets); } @@ -557,7 +557,7 @@ contract MetaMorpho is ERC4626, ERC20Permit, Ownable2Step, Multicall, IMetaMorph function _convertToShares(uint256 assets, Math.Rounding rounding) internal view override returns (uint256) { (uint256 feeShares, uint256 newTotalAssets) = _accruedFeeShares(); - return _convertToSharesWithFeeAccrued(assets, totalSupply() + feeShares, newTotalAssets, rounding); + return _convertToSharesWithTotals(assets, totalSupply() + feeShares, newTotalAssets, rounding); } /// @inheritdoc ERC4626 @@ -565,14 +565,12 @@ contract MetaMorpho is ERC4626, ERC20Permit, Ownable2Step, Multicall, IMetaMorph function _convertToAssets(uint256 shares, Math.Rounding rounding) internal view override returns (uint256) { (uint256 feeShares, uint256 newTotalAssets) = _accruedFeeShares(); - return _convertToAssetsWithFeeAccrued(shares, totalSupply() + feeShares, newTotalAssets, rounding); + return _convertToAssetsWithTotals(shares, totalSupply() + feeShares, newTotalAssets, rounding); } - /// @dev Returns the amount of shares that the vault would exchange for the amount of `assets` provided, in an ideal - /// scenario where all the conditions are met. - /// @dev It assumes the performance fee has been accrued and thus takes into account `newTotalSupply` and - /// `newTotalAssets`. - function _convertToSharesWithFeeAccrued( + /// @dev Returns the amount of shares that the vault would exchange for the amount of `assets` provided. + /// @dev It assumes that the arguments `newTotalSupply` and `newTotalAssets` are up to date. + function _convertToSharesWithTotals( uint256 assets, uint256 newTotalSupply, uint256 newTotalAssets, @@ -581,10 +579,9 @@ contract MetaMorpho is ERC4626, ERC20Permit, Ownable2Step, Multicall, IMetaMorph return assets.mulDiv(newTotalSupply + 10 ** _decimalsOffset(), newTotalAssets + 1, rounding); } - /// @dev Returns the amount of assets that the Vault would exchange for the amount of `shares` provided, in an ideal - /// scenario where all the conditions are met. - /// @dev It assumes that fees have been accrued and taking into account in `newTotalSupply` and `newTotalAssets`. - function _convertToAssetsWithFeeAccrued( + /// @dev Returns the amount of assets that the vault would exchange for the amount of `shares` provided. + /// @dev It assumes that the arguments `newTotalSupply` and `newTotalAssets` are up to date. + function _convertToAssetsWithTotals( uint256 shares, uint256 newTotalSupply, uint256 newTotalAssets, @@ -828,9 +825,8 @@ contract MetaMorpho is ERC4626, ERC20Permit, Ownable2Step, Multicall, IMetaMorph uint256 feeAssets = totalInterest.mulDiv(fee, WAD); // The fee assets is subtracted from the total assets in this calculation to compensate for the fact // that total assets is already increased by the total interest (including the fee assets). - feeShares = feeAssets.mulDiv( - totalSupply() + 10 ** _decimalsOffset(), newTotalAssets - feeAssets + 1, Math.Rounding.Floor - ); + feeShares = + _convertToSharesWithTotals(feeAssets, totalSupply(), newTotalAssets - feeAssets, Math.Rounding.Floor); } } }