```\nit('panprog liquidate unsuspecting user / self in 1 transaction', async () => {\n\n    function setupOracle(price: string, timestamp : number, nextTimestamp : number) {\n        const oracleVersion = {\n        price: parse6decimal(price),\n        timestamp: timestamp,\n        valid: true,\n        }\n        oracle.at.whenCalledWith(oracleVersion.timestamp).returns(oracleVersion)\n        oracle.status.returns([oracleVersion, nextTimestamp])\n        oracle.request.returns()\n    }\n\n    var riskParameter = {\n        maintenance: parse6decimal('0.2'),\n        takerFee: parse6decimal('0.00'),\n        takerSkewFee: 0,\n        takerImpactFee: 0,\n        makerFee: parse6decimal('0.00'),\n        makerImpactFee: 0,\n        makerLimit: parse6decimal('1000'),\n        efficiencyLimit: parse6decimal('0.2'),\n        liquidationFee: parse6decimal('0.50'),\n        minLiquidationFee: parse6decimal('10'),\n        maxLiquidationFee: parse6decimal('1000'),\n        utilizationCurve: {\n        minRate: parse6decimal('0.0'),\n        maxRate: parse6decimal('1.00'),\n        targetRate: parse6decimal('0.10'),\n        targetUtilization: parse6decimal('0.50'),\n        },\n        pController: {\n        k: parse6decimal('40000'),\n        max: parse6decimal('1.20'),\n        },\n        minMaintenance: parse6decimal('10'),\n        virtualTaker: parse6decimal('0'),\n        staleAfter: 14400,\n        makerReceiveOnly: false,\n    }\n    var marketParameter = {\n        fundingFee: parse6decimal('0.0'),\n        interestFee: parse6decimal('0.0'),\n        oracleFee: parse6decimal('0.0'),\n        riskFee: parse6decimal('0.0'),\n        positionFee: parse6decimal('0.0'),\n        maxPendingGlobal: 5,\n        maxPendingLocal: 3,\n        settlementFee: parse6decimal('0'),\n        makerRewardRate: parse6decimal('0'),\n        longRewardRate: parse6decimal('0'),\n        shortRewardRate: parse6decimal('0'),\n        makerCloseAlways: false,\n        takerCloseAlways: false,\n        closed: false,\n    }\n        \n    await market.connect(owner).updateRiskParameter(riskParameter);\n    await market.connect(owner).updateParameter(marketParameter);\n\n    setupOracle('100', TIMESTAMP, TIMESTAMP + 100);\n\n    var collateral = parse6decimal('1000')\n    dsu.transferFrom.whenCalledWith(userB.address, market.address, collateral.mul(1e12)).returns(true)\n    await market.connect(userB).update(userB.address, parse6decimal('10.000'), 0, 0, collateral, false)\n\n    var collateral = parse6decimal('100')\n    dsu.transferFrom.whenCalledWith(user.address, market.address, collateral.mul(1e12)).returns(true)\n    await market.connect(user).update(user.address, 0, parse6decimal('1.000'), 0, collateral, false)\n\n    // settle\n    setupOracle('100', TIMESTAMP + 100, TIMESTAMP + 200);\n    await market.connect(userB).update(userB.address, parse6decimal('10.000'), 0, 0, 0, false)\n    await market.connect(user).update(user.address, 0, parse6decimal('1.000'), 0, 0, false)\n\n    // withdraw\n    var collateral = parse6decimal('800')\n    dsu.transfer.whenCalledWith(userB.address, collateral.mul(1e12)).returns(true)\n    await market.connect(userB).update(userB.address, parse6decimal('2.000'), 0, 0, collateral.mul(-1), false)\n\n    // liquidate unsuspecting user\n    setupOracle('100.01', TIMESTAMP + 150, TIMESTAMP + 200);\n    const EXPECTED_LIQUIDATION_FEE = parse6decimal('100.01')\n    dsu.transfer.whenCalledWith(liquidator.address, EXPECTED_LIQUIDATION_FEE.mul(1e12)).returns(true)\n    dsu.balanceOf.whenCalledWith(market.address).returns(COLLATERAL.mul(1e12))\n    await market.connect(liquidator).update(userB.address, 0, 0, 0, EXPECTED_LIQUIDATION_FEE.mul(-1), true)\n\n    setupOracle('100.01', TIMESTAMP + 200, TIMESTAMP + 300);\n    await market.connect(userB).update(userB.address, 0, 0, 0, 0, false)\n\n    var info = await market.locals(userB.address);\n    var pos = await market.positions(userB.address);\n    console.log("Liquidated maker: collateral = " + info.collateral + " maker = " + pos.maker);\n\n})\n```\n