Vulnerability: function lockCapital() doesn't filter the expired protections first and code may lock more funds than required and expired defaulted protections may funded
Severity: medium

Description:
when a lending loan defaults, then function `lockCapital()` get called in the ProtectionPool to lock required funds for the protections bought for that lending pool, but code doesn't filter the expired protections first and they may be expired protection in the active protection array that are not excluded and this would cause code to lock more fund and pay fund for expired defaulted protections and protection sellers would lose more funds.\\nThis `lockCapital()` code:\\n```\\n  function lockCapital(address _lendingPoolAddress)\\n    external\\n    payable\\n    override\\n    onlyDefaultStateManager\\n    whenNotPaused\\n    returns (uint256 _lockedAmount, uint256 _snapshotId)\\n  {\\n    /// step 1: Capture protection pool's current investors by creating a snapshot of the token balance by using ERC20Snapshot in SToken\\n    _snapshotId = _snapshot();\\n\\n    /// step 2: calculate total capital to be locked\\n    LendingPoolDetail storage lendingPoolDetail = lendingPoolDetails[\\n      _lendingPoolAddress\\n    ];\\n\\n    /// Get indexes of active protection for a lending pool from the storage\\n    EnumerableSetUpgradeable.UintSet\\n      storage activeProtectionIndexes = lendingPoolDetail\\n        .activeProtectionIndexes;\\n\\n    /// Iterate all active protections and calculate total locked amount for this lending pool\\n    /// 1. calculate remaining principal amount for each loan protection in the lending pool.\\n    /// 2. for each loan protection, lockedAmt = min(protectionAmt, remainingPrincipal)\\n    /// 3. total locked amount = sum of lockedAmt for all loan protections\\n    uint256 _length = activeProtectionIndexes.length();\\n    for (uint256 i; i < _length; ) {\\n      /// Get protection info from the storage\\n      uint256 _protectionIndex = activeProtectionIndexes.at(i);\\n      ProtectionInfo storage protectionInfo = protectionInfos[_protectionIndex];\\n\\n      /// Calculate remaining principal amount for a loan protection in the lending pool\\n      uint256 _remainingPrincipal = poolInfo\\n        .referenceLendingPools\\n        .calculateRemainingPrincipal(\\n          _lendingPoolAddress,\\n          protectionInfo.buyer,\\n          protectionInfo.purchaseParams.nftLpTokenId\\n        );\\n\\n      /// Locked amount is minimum of protection amount and remaining principal\\n      uint256 _protectionAmount = protectionInfo\\n        .purchaseParams\\n        .protectionAmount;\\n      uint256 _lockedAmountPerProtection = _protectionAmount <\\n        _remainingPrincipal\\n        ? _protectionAmount\\n        : _remainingPrincipal;\\n\\n      _lockedAmount += _lockedAmountPerProtection;\\n\\n      unchecked {\\n        ++i;\\n      }\\n    }\\n\\n    unchecked {\\n      /// step 3: Update total locked & available capital in storage\\n      if (totalSTokenUnderlying < _lockedAmount) {\\n        /// If totalSTokenUnderlying < _lockedAmount, then lock all available capital\\n        _lockedAmount = totalSTokenUnderlying;\\n        totalSTokenUnderlying = 0;\\n      } else {\\n        /// Reduce the total sToken underlying amount by the locked amount\\n        totalSTokenUnderlying -= _lockedAmount;\\n      }\\n    }\\n  }\\n```\\n\\nAs you can see code loops through active protection array for that lending pool and calculates required locked amount but it doesn't call `_accruePremiumAndExpireProtections()` to make sure active protections doesn't include any expired protections. if function `_accruePremiumAndExpireProtections()` doesn't get called for a while, then there would be possible that some of the protections are expired and they are still in the active protection array. This would cause code to calculated more locked amount and also pay fund for those expired defaulted protections too from protection sellers. (also when calculating the required token payment for the protection code doesn't check the expiration too in the other functions that are get called by the `lockCapital()`, the expire check doesn't exists in inner function too)

Impact:
see summery

Recommended mitigation:
call `_accruePremiumAndExpireProtections()` for the defaulted pool to filter out the expired protections.