A borrower/lender or liquidator will fail to withdraw the collateral assets due to reaching a gas limit
Within the TellerV2#submitBid(), there is no limitation that how many collateral assets a borrower can assign into the `_collateralInfo` array parameter.\\nThis lead to some bad scenarios like this due to reaching gas limit:\\nA borrower or a lender fail to withdraw the collateral assets when the loan would not be liquidated.\\nA liquidator will fail to withdraw the collateral assets when the loan would be liquidated.\\n```\\nstruct Collateral {\\n    CollateralType _collateralType;\\n    uint256 _amount;\\n    uint256 _tokenId;\\n    address _collateralAddress;\\n}\\n```\\n\\n```\\n    /**\\n     * Since collateralInfo is mapped (address assetAddress => Collateral) that means\\n     * that only a single tokenId per nft per loan can be collateralized.\\n     * Ex. Two bored apes cannot be used as collateral for a single loan.\\n     */\\n    struct CollateralInfo {\\n        EnumerableSetUpgradeable.AddressSet collateralAddresses;\\n        mapping(address => Collateral) collateralInfo;\\n    }\\n```\\n\\n```\\n    // bidIds -> validated collateral info\\n    mapping(uint256 => CollateralInfo) internal _bidCollaterals;\\n```\\n\\n```\\n    function submitBid(\\n        address _lendingToken,\\n        uint256 _marketplaceId,\\n        uint256 _principal,\\n        uint32 _duration,\\n        uint16 _APR,\\n        string calldata _metadataURI,\\n        address _receiver,\\n        Collateral[] calldata _collateralInfo /// @audit\\n    ) public override whenNotPaused returns (uint256 bidId_) {\\n        // rest of code\\n        bool validation = collateralManager.commitCollateral(\\n            bidId_,\\n            _collateralInfo /// @audit \\n        );\\n        // rest of code\\n```\\n\\n```\\n    /**\\n     * @notice Checks the validity of a borrower's multiple collateral balances and commits it to a bid.\\n     * @param _bidId The id of the associated bid.\\n     * @param _collateralInfo Additional information about the collateral assets.\\n     * @return validation_ Boolean indicating if the collateral balances were validated.\\n     */\\n    function commitCollateral(\\n        uint256 _bidId,\\n        Collateral[] calldata _collateralInfo  /// @audit\\n    ) public returns (bool validation_) {\\n        address borrower = tellerV2.getLoanBorrower(_bidId);\\n        (validation_, ) = checkBalances(borrower, _collateralInfo);\\n\\n        if (validation_) {\\n            for (uint256 i; i < _collateralInfo.length; i++) {    \\n                Collateral memory info = _collateralInfo[i];\\n                _commitCollateral(_bidId, info);  /// @audit\\n            }\\n        }\\n    }\\n```\\n\\n```\\n    /**\\n     * @notice Checks the validity of a borrower's collateral balance and commits it to a bid.\\n     * @param _bidId The id of the associated bid.\\n     * @param _collateralInfo Additional information about the collateral asset.\\n     */\\n    function _commitCollateral(\\n        uint256 _bidId,\\n        Collateral memory _collateralInfo\\n    ) internal virtual {\\n        CollateralInfo storage collateral = _bidCollaterals[_bidId];\\n        collateral.collateralAddresses.add(_collateralInfo._collateralAddress);\\n        collateral.collateralInfo[\\n            _collateralInfo._collateralAddress\\n        ] = _collateralInfo;  /// @audit\\n        // rest of code\\n```\\n\\n```\\n    /**\\n     * @notice Withdraws deposited collateral from the created escrow of a bid that has been successfully repaid.\\n     * @param _bidId The id of the bid to withdraw collateral for.\\n     */\\n    function withdraw(uint256 _bidId) external {\\n        BidState bidState = tellerV2.getBidState(_bidId);\\n        if (bidState == BidState.PAID) {\\n            _withdraw(_bidId, tellerV2.getLoanBorrower(_bidId)); /// @audit \\n        } else if (tellerV2.isLoanDefaulted(_bidId)) {\\n            _withdraw(_bidId, tellerV2.getLoanLender(_bidId));  /// @audit \\n           // rest of code\\n```\\n\\n```\\n    /**\\n     * @notice Sends the deposited collateral to a liquidator of a bid.\\n     * @notice Can only be called by the protocol.\\n     * @param _bidId The id of the liquidated bid.\\n     * @param _liquidatorAddress The address of the liquidator to send the collateral to.\\n     */\\n    function liquidateCollateral(uint256 _bidId, address _liquidatorAddress)\\n        external\\n        onlyTellerV2\\n    {\\n        if (isBidCollateralBacked(_bidId)) {\\n            BidState bidState = tellerV2.getBidState(_bidId);\\n            require(\\n                bidState == BidState.LIQUIDATED,\\n                "Loan has not been liquidated"\\n            );\\n            _withdraw(_bidId, _liquidatorAddress);  /// @audit\\n        }\\n    }\\n```\\n\\n```\\n    /**\\n     * @notice Withdraws collateral to a given receiver's address.\\n     * @param _bidId The id of the bid to withdraw collateral for.\\n     * @param _receiver The address to withdraw the collateral to.\\n     */\\n    function _withdraw(uint256 _bidId, address _receiver) internal virtual {\\n        for (\\n            uint256 i;\\n            i < _bidCollaterals[_bidId].collateralAddresses.length(); /// @audit\\n            i++\\n        ) {\\n            // Get collateral info\\n            Collateral storage collateralInfo = _bidCollaterals[_bidId]\\n                .collateralInfo[\\n                    _bidCollaterals[_bidId].collateralAddresses.at(i)\\n                ];\\n            // Withdraw collateral from escrow and send it to bid lender\\n            ICollateralEscrowV1(_escrows[_bidId]).withdraw(   /// @audit\\n                collateralInfo._collateralAddress,\\n                collateralInfo._amount,\\n                _receiver\\n            );\\n```\\n\\nHowever, within the TellerV2#submitBid(), there is no limitation that how many collateral assets a borrower can assign into the `_collateralInfo` array parameter.\\nThis lead to a bad scenario like below:\\n① A borrower assign too many number of the collateral assets (ERC20/ERC721/ERC1155) into the `_collateralInfo` array parameter when the borrower call the TellerV2#submitBid() to submit a bid.\\n② Then, a lender accepts the bid via calling the TellerV2#lenderAcceptBid()\\n③ Then, a borrower or a lender try to withdraw the collateral, which is not liquidated, by calling the CollateralManager#withdraw(). Or, a liquidator try to withdraw the collateral, which is liquidated, by calling the CollateralManager#liquidateCollateral()\\n④ But, the transaction of the CollateralManager#withdraw() or the CollateralManager#liquidateCollateral() will be reverted in the for-loop of the CollateralManager#_withdraw() because that transaction will reach a gas limit.
Within the TellerV2#submitBid(), consider adding a limitation about how many collateral assets a borrower can assign into the `_collateralInfo` array parameter.
Due to reaching gas limit, some bad scenarios would occur like this:\\nA borrower or a lender fail to withdraw the collateral assets when the loan would not be liquidated.\\nA liquidator will fail to withdraw the collateral assets when the loan would be liquidated.
```\\nstruct Collateral {\\n    CollateralType _collateralType;\\n    uint256 _amount;\\n    uint256 _tokenId;\\n    address _collateralAddress;\\n}\\n```\\n