Vulnerability Details
collect function on NonfungiblePositionManagerMock is called in L2TokenReceiver contract. But NonfungiblePositionManagerMock doesn't implemented INonfungiblePositionManager interface. So defining collect function is missed in NonfungiblePositionManagerMock. So whenever tha function wil be called in L2TokenReceiver::collectFees then collectFees will always revert.
https://github.com/Cyfrin/2024-01-Morpheus/blob/main/contracts/mock/NonfungiblePositionManagerMock.sol#L6C1-L30C7
contract NonfungiblePositionManagerMock {
function increaseLiquidity(
INonfungiblePositionManager.IncreaseLiquidityParams calldata params
) external payable returns (uint128 liquidity, uint256 amount0, uint256 amount1) {}
function positions(
uint256 tokenId
)
external
view
returns (
uint96 nonce,
address operator,
address token0,
address token1,
uint24 fee,
int24 tickLower,
int24 tickUpper,
uint128 liquidity,
uint256 feeGrowthInside0LastX128,
uint256 feeGrowthInside1LastX128,
uint128 tokensOwed0,
uint128 tokensOwed1
)
{}
https://github.com/Cyfrin/2024-01-Morpheus/blob/main/contracts/L2TokenReceiver.sol#L122C5-L133C6
function collectFees(uint256 tokenId_) external returns (uint256 amount0_, uint256 amount1_) {
INonfungiblePositionManager.CollectParams memory params_ = INonfungiblePositionManager.CollectParams({
tokenId: tokenId_,
recipient: address(this),
amount0Max: type(uint128).max,
amount1Max: type(uint128).max
});
(amount0_, amount1_) = INonfungiblePositionManager(nonfungiblePositionManager).collect(params_);
emit FeesCollected(tokenId_, amount0_, amount1_);
}