When killSwitch is enabled in the adapter (MYTStrategy), the adapter does not allocate funds, but the Morpho vault still transfers collateral to the adapter. Because no recovery or fallback mechanism exists, these funds become irrecoverably stuck inside the adapter contract. Disabling killSwitch and attempting deallocate does not help because no allocation took place, so there is nothing to unwind, leaving the vault with a permanent loss.
MYTStrategy::
function allocate(bytes memory data, uint256 assets, bytes4 selector, address sender)
external
onlyVault
returns (bytes32[] memory strategyIds, int256 change)
{
if (killSwitch) {
return (ids(), int256(0)); // No allocation happens, funds stuck in adapter
}
...
}
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
function testfundsStuckInAdapter() public {
// Enable kill switch
vm.prank(admin);
mytStrategy.setKillSwitch(true);
_magicDepositToVault(address(vault), user1, 150 ether);
vm.startPrank(admin);
allocator.allocate(address(mytStrategy), 100 ether);
bytes32 allocationId = mytStrategy.adapterId();
uint256 allocation = vault.allocation(allocationId);
// Now, adapter(strategy) have those funds of morpho vault, and no way to recover those from adapter
uint256 bal = IERC20(mockVaultCollateral).balanceOf(address(mytStrategy));
assertEq(bal, 100 ether);
// if try to deallocate those from adapter, then that also fails in both cases(killswitch or non-killswitch)
// allocator.deallocate(address(mytStrategy), 50 ether);
vm.stopPrank();
}