@@ -190,6 +190,8 @@ contract ChainlinkOEVMorphoWrapperIntegrationTest is
190190 }
191191
192192 function testUpdatePriceEarlyAndLiquidate_stkWELL () public {
193+ // Note: stkWELL has no market, so fee recipient should be set to treasury
194+ // The wrapper will automatically detect this and transfer instead of calling _addReserves
193195 _testLiquidation (
194196 addresses.getAddress ("CHAINLINK_stkWELL_USD_ORACLE_PROXY " ),
195197 addresses.getAddress ("STK_GOVTOKEN_PROXY " ),
@@ -206,8 +208,8 @@ contract ChainlinkOEVMorphoWrapperIntegrationTest is
206208 addresses.getAddress ("MAMO " ),
207209 addresses.getAddress ("MORPHO_CHAINLINK_MAMO_USD_ORACLE " ),
208210 0.385e18 ,
209- 50_000e18 , // More MAMO tokens
210- 500e18
211+ 250_000e18 , // Scale up collateral (5x from 50k to match WELL's economic value)
212+ 2_500e18 // Scale up seized amount proportionally (MAMO is 4x WELL price, so 10k/4 = 2.5k)
211213 );
212214 }
213215
@@ -266,14 +268,37 @@ contract ChainlinkOEVMorphoWrapperIntegrationTest is
266268 )
267269 );
268270
269- // Execute liquidation and validate
271+ // Execute liquidation
272+ _executeLiquidation (
273+ wrapper,
274+ params,
275+ loanToken,
276+ borrowAmount,
277+ seized,
278+ collToken
279+ );
280+ }
281+
282+ function _executeLiquidation (
283+ ChainlinkOEVMorphoWrapper wrapper ,
284+ MarketParams memory params ,
285+ address loanToken ,
286+ uint256 borrowAmount ,
287+ uint256 seized ,
288+ address collToken
289+ ) internal {
270290 deal (loanToken, LIQUIDATOR, borrowAmount);
271291 vm.startPrank (LIQUIDATOR);
272292 IERC20 (loanToken).approve (address (wrapper), borrowAmount);
273293
274294 uint256 liqLoanBefore = IERC20 (loanToken).balanceOf (LIQUIDATOR);
275295 uint256 liqCollBefore = IERC20 (collToken).balanceOf (LIQUIDATOR);
276296
297+ // Capture fee recipient state before
298+ address feeRecipient = wrapper.feeRecipient ();
299+ uint256 feeStateBefore = _getFeeRecipientState (feeRecipient, collToken);
300+ bool isMToken = _isFeeRecipientMToken (feeRecipient);
301+
277302 wrapper.updatePriceEarlyAndLiquidate (
278303 params,
279304 BORROWER,
@@ -282,6 +307,7 @@ contract ChainlinkOEVMorphoWrapperIntegrationTest is
282307 );
283308 vm.stopPrank ();
284309
310+ // Assertions
285311 assertEq (wrapper.cachedRoundId (), 777 );
286312 assertGt (
287313 liqLoanBefore - IERC20 (loanToken).balanceOf (LIQUIDATOR),
@@ -293,13 +319,39 @@ contract ChainlinkOEVMorphoWrapperIntegrationTest is
293319 0 ,
294320 "no collateral received "
295321 );
322+
323+ // Verify protocol fee was collected
324+ uint256 feeStateAfter = _getFeeRecipientState (feeRecipient, collToken);
296325 assertGt (
297- IERC20 (collToken).balanceOf (wrapper.feeRecipient ()),
298- 0 ,
299- "no fee collected "
326+ feeStateAfter,
327+ feeStateBefore,
328+ isMToken
329+ ? "no fee collected (reserves) "
330+ : "no fee collected (balance) "
300331 );
301332 }
302333
334+ function _isFeeRecipientMToken (
335+ address feeRecipient
336+ ) internal view returns (bool ) {
337+ try MErc20 (feeRecipient).isMToken () returns (bool _isMToken ) {
338+ return _isMToken;
339+ } catch {
340+ return false ;
341+ }
342+ }
343+
344+ function _getFeeRecipientState (
345+ address feeRecipient ,
346+ address collToken
347+ ) internal view returns (uint256 ) {
348+ if (_isFeeRecipientMToken (feeRecipient)) {
349+ return MErc20 (feeRecipient).totalReserves ();
350+ } else {
351+ return IERC20 (collToken).balanceOf (feeRecipient);
352+ }
353+ }
354+
303355 function testUpdatePriceEarlyAndLiquidate_RevertArgsZero () public {
304356 MarketParams memory params;
305357 address mUSDC = addresses.getAddress ("MOONWELL_USDC " );
0 commit comments