For the MorphoYearnOGWETH vault, MORPHO portion of the earned yield will be lost since some percentage of the total APY is paid out in MOR tokens.
Vulnerability Details
// SPDX-License-Identifier: MITpragmasolidity0.8.28;import {MYTStrategy}from"../../MYTStrategy.sol";import {IMYTStrategy}from"../../interfaces/IMYTStrategy.sol";import {TokenUtils}from"../../libraries/TokenUtils.sol";.../** * @title MorphoYearnOGWETHStrategy * @notice This strategy is used to allocate and deallocate weth to the Morpho Yearn OG WETH vault on Mainnet */contractMorphoYearnOGWETHStrategyisMYTStrategy{ WETH publicimmutable weth; IERC4626 publicimmutable vault;eventMorphoYearnOGWETHStrategyDebugLog(stringmessage, uint256value);constructor(address_myt,StrategyParamsmemory_params,address_vault,address_weth,address_permit2Address)MYTStrategy(_myt, _params, _permit2Address, _weth){ weth =WETH(_weth); vault =IERC4626(_vault);require(vault.asset()== _weth,"Vault asset != WETH");}// @note seenfunction_allocate(uint256amount)internaloverridereturns(uint256){require(TokenUtils.safeBalanceOf(address(weth),address(this))>= amount,"Strategy balance is less than amount"); TokenUtils.safeApprove(address(weth),address(vault), amount); vault.deposit(amount,address(this));return amount;}function_deallocate(uint256amount)internaloverridereturns(uint256){ vault.withdraw(amount,address(this),address(this));uint256 wethBalanceBefore = TokenUtils.safeBalanceOf(address(weth),address(this));uint256 wethBalanceAfter = TokenUtils.safeBalanceOf(address(weth),address(this));uint256 wethRedeemed = wethBalanceAfter - wethBalanceBefore;if(wethRedeemed < amount){emitStrategyDeallocationLoss("Strategy deallocation loss.", amount, wethRedeemed);}require(wethRedeemed + wethBalanceBefore >= amount,"Strategy balance is less than the amount needed");require(TokenUtils.safeBalanceOf(address(weth),address(this))>= amount,"Strategy balance is less than the amount needed"); TokenUtils.safeApprove(address(weth),msg.sender, amount);return amount;}...}
The MorphoYearnOGWETH contract we interact with on Ethereum mainnet has an APY of 3.97% per year (3.8% Native APY, 0.17% MORPHO APY). In that, there is a 0.19% performance fee charged to users. Now, the net APY wil be 3.79% i.e Morpho will take 0.19% from the Native Yield of 3.8% which means the Native APY will be 3.61% and then Morpho APY is 0.17% which results in the total APY of ~3.79%
Now, Morpho suppliers in this Yearn OG WETH 0xE89371eAaAC6D46d4C3ED23453241987916224FC vault will get two rewards.
Reward 1 will be distributed in WETH tokens
Reward 2 will be distributed in MORPHO tokens
You can check the breakdown here at the Vault page in the Morpho App: https://app.morpho.org/ethereum/vault/0xE89371eAaAC6D46d4C3ED23453241987916224FC/yearn-og-weth
The problem is that in the MorphoYearnOGWETHStrategy Alchemix is deploying, there is nowhere they setup:
The MORPHO URD CONTRACT which resides here onchain for MORPHO tokens: 0x330eefa8a787552DC5cAd3C3cA644844B1E61Ddb
Thus, MORPHO URD contract's claim() function will not be possible to be called from the contract. That is only one part of the issue.
The second part of the issue is that, these MORPHO tokens are sent to the account which in this case will be the MorphoYearnOGWETHStrategy address as that will be the address computed in the merkle reward root for the URD contract by Morpho protocol.
As a result of this, even if the Alchemix team were to obtain a valid proof and then call the URD's claim() function from another address (which is possible by the way to claim on behalf of someone), these tokens are in fact sent to the account which in this case is the MorphoYearnOGWETHStrategy address.
Thus, they will be locked inside the contract and cannot be claimed.
You can check the claim function of the URD here: https://etherscan.io/address/0x330eefa8a787552dc5cad3c3ca644844b1e61ddb#code#F1#L136
Impact Details
A part of the yield earned (MORPHO) will be stuck inside the strategy contract and cannot be retrived. From my forked test case of allocating 1k WETH to the Morpho Yearn OG vault on Morpho, the relative amount stuck will be 0.17% of the total yield which amounts to 1.7 WETH and is 3417 MORPHO tokens.
At current MORPHO prices, that is about USD 6800.
In the MorphoYearnOGWETHStrategy, we should:
Add a new variable to keep track of the URD
Add a new function to claim and also to send the received MORPHO tokens out.
We can do something similar to:
Then, set the address and implement a function send out the MORPHO tokens.