{
    "Function": "isLiquidatable",
    "File": "contracts/MarginAccount.sol",
    "Parent Contracts": [
        "contracts/legos/HubbleBase.sol",
        "node_modules/@openzeppelin/contracts/metatx/ERC2771Context.sol",
        "node_modules/@openzeppelin/contracts/security/Pausable.sol",
        "node_modules/@openzeppelin/contracts/utils/Context.sol",
        "contracts/legos/Governable.sol",
        "node_modules/@openzeppelin/contracts/proxy/utils/Initializable.sol",
        "contracts/legos/Governable.sol",
        "contracts/Interfaces.sol"
    ],
    "High-Level Calls": [
        "IClearingHouse",
        "SafeCast",
        "SafeCast",
        "IClearingHouse"
    ],
    "Internal Calls": [
        "weightedAndSpotCollateral",
        "_min"
    ],
    "Library Calls": [
        "toUint256",
        "toUint256"
    ],
    "Low-Level Calls": [],
    "Code": "function isLiquidatable(address trader, bool includeFunding)\n        override\n        public\n        view\n        returns(IMarginAccount.LiquidationStatus _isLiquidatable, uint repayAmount, uint incentivePerDollar)\n    {\n        int vusdBal = margin[VUSD_IDX][trader];\n        if (includeFunding) {\n            vusdBal -= clearingHouse.getTotalFunding(trader);\n        }\n        if (vusdBal >= 0) { // nothing to liquidate\n            return (IMarginAccount.LiquidationStatus.NO_DEBT, 0, 0);\n        }\n\n        (uint256 notionalPosition,) = clearingHouse.getTotalNotionalPositionAndUnrealizedPnl(trader);\n        if (notionalPosition != 0) { // Liquidate positions before liquidating margin account\n            return (IMarginAccount.LiquidationStatus.OPEN_POSITIONS, 0, 0);\n        }\n\n        (int256 weighted, int256 spot) = weightedAndSpotCollateral(trader);\n        if (weighted >= 0) {\n            return (IMarginAccount.LiquidationStatus.ABOVE_THRESHOLD, 0, 0);\n        }\n\n        // _isLiquidatable = IMarginAccount.LiquidationStatus.IS_LIQUIDATABLE;\n        repayAmount = (-vusdBal).toUint256();\n        incentivePerDollar = PRECISION; // get atleast $1 worth of collateral for every $1 paid\n\n        if (spot > 0) {\n            /**\n                Liquidation scenario B, where Cw < |vUSD| < Cusd\n                => Cw - |vUSD| < 0\n                => Cw + vUSD (=weighted) < 0; since vUSD < 0\n                Max possible liquidationIncentive (for repaying |vUSD|) is Cusd\n            */\n            incentivePerDollar += _min(\n                liquidationIncentive, // incentivePerDollar = PRECISION + liquidationIncentive <= 1.1\n                // divide up all the extra dollars in proportion to repay amount\n                // note that spot value here is inclusive of the -ve vUSD value\n                spot.toUint256() * PRECISION / repayAmount\n            );\n        } /* else {\n            Since the protocol is already in deficit we don't have any money to give out as liquidationIncentive\n            Liquidation scenario C, where Cusd <= |vUSD|\n            => Cusd - |vUSD| <= 0\n            => Cusd + vUSD (=spot) <= 0; since vUSD < 0\n\n            @todo consider providing some incentive from insurance fund to execute a liquidation in this scenario.\n            That fee is basically provided so that insurance fund has to settle a lower bad debt and seize lesser amount of assets.\n            (because seized assets then need to sold/auctioned off, so that's extra work)\n        } */\n    }"
}