Unupdated totalBorrow After BigBang Liquidation
During the liquidation process, BigBang only reduces the user's `userBorrowPart[user]`, but fails to update the global `totalBorrow`. Consequently, all subsequent debt calculations are incorrect.\\nCurrently, the implementation relies on the `BBLiquidation._updateBorrowAndCollateralShare()` method to calculate user debt repayment and collateral collection. The code snippet is as follows:\\n```\\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\\nThe methods mentioned above update the user-specific variables `userBorrowPart[user]` and `userCollateralShare[user]` within the `_updateBorrowAndCollateralShare()` method. Additionally, the global variable `totalCollateralShare` is updated within the `_liquidateUser()` method.\\nHowever, there's another crucial global variable, `totalBorrow`, which remains unaltered throughout the entire liquidation process.\\nFailure to update `totalBorrow` during liquidation will result in incorrect subsequent loan-related calculations.\\nNote: SGL Liquidation has the same issues
```\\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// Remove the line below\\n       (uint256 borrowAmount,, uint256 collateralShare) =\\n// Add the line below\\n       (uint256 borrowAmount,uint256 borrowPart, uint256 collateralShare) =\\n            _updateBorrowAndCollateralShare(user, maxBorrowPart, minLiquidationBonus, _exchangeRate);\\n        totalCollateralShare = totalCollateralShare > collateralShare ? totalCollateralShare // Remove the line below\\n collateralShare : 0;\\n// Add the line below\\n       totalBorrow.elastic // Remove the line below\\n= borrowAmount.toUint128();\\n// Add the line below\\n       totalBorrow.base // Remove the line below\\n= borrowPart.toUint128();\\n```\\n
The lack of an update to `totalBorrow` during liquidation leads to inaccuracies in subsequent loan-related calculations. For instance, this affects interest accumulation and the amount of interest due.
```\\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