Malicious seller forced break lockCapital()
Malicious burn nft causes failure to lockCapital() ，seller steady earn PremiumAmount, buyer will be lost compensation\\nWhen the status of the lendingPool changes from Active to Late, the protocol will call ProtectionPool.lockCapital() to lock amount lockCapital() will loop through the active protections to calculate the `lockedAmount`. The code is as follows:\\n```\\n  function lockCapital(address _lendingPoolAddress)\\n    external\\n    payable\\n    override\\n    onlyDefaultStateManager\\n    whenNotPaused\\n    returns (uint256 _lockedAmount, uint256 _snapshotId)\\n  {\\n// rest of code.\\n    uint256 _length = activeProtectionIndexes.length();\\n    for (uint256 i; i < _length; ) {\\n// rest of code\\n      uint256 _remainingPrincipal = poolInfo\\n        .referenceLendingPools\\n        .calculateRemainingPrincipal(            //<----------- calculate Remaining Principal\\n          _lendingPoolAddress,\\n          protectionInfo.buyer,\\n          protectionInfo.purchaseParams.nftLpTokenId\\n        );\\n```\\n\\nThe important thing inside is to calculate the _remainingPrincipal by `referenceLendingPools.calculateRemainingPrincipal()`\\n```\\n  function calculateRemainingPrincipal(\\n    address _lendingPoolAddress,\\n    address _lender,\\n    uint256 _nftLpTokenId\\n  ) public view override returns (uint256 _principalRemaining) {\\n// rest of code\\n\\n    if (_poolTokens.ownerOf(_nftLpTokenId) == _lender) {   //<------------call ownerOf()\\n      IPoolTokens.TokenInfo memory _tokenInfo = _poolTokens.getTokenInfo(\\n        _nftLpTokenId\\n      );\\n\\n// rest of code.\\n      if (\\n        _tokenInfo.pool == _lendingPoolAddress &&\\n        _isJuniorTrancheId(_tokenInfo.tranche)\\n      ) {\\n        _principalRemaining =\\n          _tokenInfo.principalAmount -\\n          _tokenInfo.principalRedeemed;\\n      }\\n    }\\n  }\\n```\\n\\nGoldfinchAdapter.calculateRemainingPrincipal() The current implementation will first determine if the ownerOf the NFTID is _lender\\nThere is a potential problem here, if the NFTID has been burned, the ownerOf() will be directly revert, which will lead to calculateRemainingPrincipal() revert,and lockCapital() revert and can't change status from active to late\\nLet's see whether Goldfinch's implementation supports burn(NFTID), and whether ownerOf(NFTID) will revert\\nPoolTokens has burn() method , if principalRedeemed==principalAmount you can burn it\\n```\\ncontract PoolTokens is IPoolTokens, ERC721PresetMinterPauserAutoIdUpgradeSafe, HasAdmin, IERC2981 {\\n// rest of code..\\n  function burn(uint256 tokenId) external virtual override whenNotPaused {\\n    TokenInfo memory token = _getTokenInfo(tokenId);\\n    bool canBurn = _isApprovedOrOwner(_msgSender(), tokenId);\\n    bool fromTokenPool = _validPool(_msgSender()) && token.pool == _msgSender();\\n    address owner = ownerOf(tokenId);\\n    require(canBurn || fromTokenPool, "ERC721Burnable: caller cannot burn this token");\\n    require(token.principalRedeemed == token.principalAmount, "Can only burn fully redeemed tokens");\\n    _destroyAndBurn(tokenId);\\n    emit TokenBurned(owner, token.pool, tokenId);\\n  }\\n```\\n\\n2.ownerOf() if nftid don't exists will revert with message "ERC721: owner query for nonexistent token"\\n```\\ncontract ERC721UpgradeSafe is\\n  Initializable,\\n  ContextUpgradeSafe,\\n  ERC165UpgradeSafe,\\n  IERC721,\\n  IERC721Metadata,\\n  IERC721Enumerable\\n{\\n// rest of code\\n  function ownerOf(uint256 tokenId) public view override returns (address) {\\n    return _tokenOwners.get(tokenId, "ERC721: owner query for nonexistent token");\\n  }\\n```\\n\\nIf it can't changes to late, Won't lock the fund, seller steady earn PremiumAmount\\nSo there are two risks\\nnormal buyer gives NFTID to burn(), he does not know that it will affect all protection of the lendingPool\\nMalicious seller can buy a protection first, then burn it, so as to force all protection of the lendingPool to expire and get the PremiumAmount maliciously. buyer unable to obtain compensation\\nSuggested try catch for _poolTokens.ownerOf() If revert, it is assumed that the lender is not the owner
try catch for _poolTokens.ownerOf() If revert, it is assumed that the lender is not the owner
buyer will be lost compensation
```\\n  function lockCapital(address _lendingPoolAddress)\\n    external\\n    payable\\n    override\\n    onlyDefaultStateManager\\n    whenNotPaused\\n    returns (uint256 _lockedAmount, uint256 _snapshotId)\\n  {\\n// rest of code.\\n    uint256 _length = activeProtectionIndexes.length();\\n    for (uint256 i; i < _length; ) {\\n// rest of code\\n      uint256 _remainingPrincipal = poolInfo\\n        .referenceLendingPools\\n        .calculateRemainingPrincipal(            //<----------- calculate Remaining Principal\\n          _lendingPoolAddress,\\n          protectionInfo.buyer,\\n          protectionInfo.purchaseParams.nftLpTokenId\\n        );\\n```\\n