```\n    function _liquidateUser(\n        address user,\n        uint256 maxBorrowPart,\n        IMarketLiquidatorReceiver _liquidatorReceiver,\n        bytes calldata _liquidatorReceiverData,\n        uint256 _exchangeRate,\n        uint256 minLiquidationBonus\n    ) private {\n        uint256 callerReward = _getCallerReward(user, _exchangeRate);\n\n        (uint256 borrowAmount,, uint256 collateralShare) =\n          _updateBorrowAndCollateralShare(user, maxBorrowPart, minLiquidationBonus, _exchangeRate);\n      totalCollateralShare = totalCollateralShare > collateralShare ? totalCollateralShare - collateralShare : 0;\n        uint256 borrowShare = yieldBox.toShare(assetId, borrowAmount, true);\n\n        (uint256 returnedShare,) =\n            _swapCollateralWithAsset(collateralShare, _liquidatorReceiver, _liquidatorReceiverData);\n        if (returnedShare < borrowShare) revert AmountNotValid();\n\n        (uint256 feeShare, uint256 callerShare) = _extractLiquidationFees(returnedShare, borrowShare, callerReward);\n\n        IUsdo(address(asset)).burn(address(this), borrowAmount);\n\n        address[] memory _users = new address[](1);\n        _users[0] = user;\n        emit Liquidated(msg.sender, _users, callerShare, feeShare, borrowAmount, collateralShare);\n    }\n\n    function _updateBorrowAndCollateralShare(\n        address user,\n        uint256 maxBorrowPart,\n        uint256 minLiquidationBonus, // min liquidation bonus to accept (default 0)\n        uint256 _exchangeRate\n    ) private returns (uint256 borrowAmount, uint256 borrowPart, uint256 collateralShare) {\n        if (_exchangeRate == 0) revert ExchangeRateNotValid();\n\n        // get collateral amount in asset's value\n        uint256 collateralPartInAsset = (\n            yieldBox.toAmount(collateralId, userCollateralShare[user], false) * EXCHANGE_RATE_PRECISION\n        ) / _exchangeRate;\n\n        // compute closing factor (liquidatable amount)\n        uint256 borrowPartWithBonus =\n            computeClosingFactor(userBorrowPart[user], collateralPartInAsset, FEE_PRECISION_DECIMALS);\n\n        // limit liquidable amount before bonus to the current debt\n        uint256 userTotalBorrowAmount = totalBorrow.toElastic(userBorrowPart[user], true);\n        borrowPartWithBonus = borrowPartWithBonus > userTotalBorrowAmount ? userTotalBorrowAmount : borrowPartWithBonus;\n\n        // check the amount to be repaid versus liquidator supplied limit\n        borrowPartWithBonus = borrowPartWithBonus > maxBorrowPart ? maxBorrowPart : borrowPartWithBonus;\n        borrowAmount = borrowPartWithBonus;\n\n        // compute part units, preventing rounding dust when liquidation is full\n        borrowPart = borrowAmount == userTotalBorrowAmount\n            ? userBorrowPart[user]\n            : totalBorrow.toBase(borrowPartWithBonus, false);\n        if (borrowPart == 0) revert Solvent();\n\n        if (liquidationBonusAmount > 0) {\n            borrowPartWithBonus = borrowPartWithBonus + (borrowPartWithBonus * liquidationBonusAmount) / FEE_PRECISION;\n        }\n\n        if (collateralPartInAsset < borrowPartWithBonus) {\n            if (collateralPartInAsset <= userTotalBorrowAmount) {\n                revert BadDebt();\n            }\n            // If current debt is covered by collateral fully\n            // then there is some liquidation bonus,\n            // so liquidation can proceed if liquidator's minimum is met\n            if (minLiquidationBonus > 0) {\n                // `collateralPartInAsset > borrowAmount` as `borrowAmount <= userTotalBorrowAmount`\n                uint256 effectiveBonus = ((collateralPartInAsset - borrowAmount) * FEE_PRECISION) / borrowAmount;\n                if (effectiveBonus < minLiquidationBonus) {\n                    revert InsufficientLiquidationBonus();\n                }\n                collateralShare = userCollateralShare[user];\n            } else {\n                revert InsufficientLiquidationBonus();\n            }\n        } else {\n            collateralShare =\n                yieldBox.toShare(collateralId, (borrowPartWithBonus * _exchangeRate) / EXCHANGE_RATE_PRECISION, false);\n            if (collateralShare > userCollateralShare[user]) {\n                revert NotEnoughCollateral();\n            }\n        }\n\n      userBorrowPart[user] -= borrowPart;\n      userCollateralShare[user] -= collateralShare;\n    }\n```\n