Vulnerability: rebalance process incase of selling the collateral, could revert because of underflow calculation
Severity: medium

Description:
rebalance process, will try to sell the collateral in case of peg-down. However, the process can revert because the calculation can underflow.\\nInside `rebalance()` call, if `BuyUSSDSellCollateral()` is triggered, it will try to sell the current collateral to `baseAsset`. The asset that will be sold (amountToSellUnits) first calculated. Then swap it to `baseAsset` via uniswap. However, when subtracting `amountToBuyLeftUSD`, it with result of `(IERC20Upgradeable(baseAsset).balanceOf(USSD) - amountBefore)`. There is no guarantee `amountToBuyLeftUSD` always bigger than `(IERC20Upgradeable(baseAsset).balanceOf(USSD) - amountBefore)`.\\nThis causing the call could revert in case `(IERC20Upgradeable(baseAsset).balanceOf(USSD) - amountBefore)` > `amountToBuyLeftUSD`.\\nThere are two branch where `amountToBuyLeftUSD -= (IERC20Upgradeable(baseAsset).balanceOf(USSD) - amountBefore)` is performed :\\nIncase `collateralval > amountToBuyLeftUSD`\\n`collateralval` is calculated using oracle price, thus the result of swap not guaranteed to reflect the proportion of `amountToBuyLefUSD` against `collateralval` ratio, and could result in returning `baseAsset` larger than expected. And potentially `(IERC20Upgradeable(baseAsset).balanceOf(USSD) - amountBefore)` > `amountToBuyLeftUSD`\\n```\\n        uint256 collateralval = IERC20Upgradeable(collateral[i].token).balanceOf(USSD) * 1e18 / (10**IERC20MetadataUpgradeable(collateral[i].token).decimals()) * collateral[i].oracle.getPriceUSD() / 1e18;\\n        if (collateralval > amountToBuyLeftUSD) {\\n          // sell a portion of collateral and exit\\n          if (collateral[i].pathsell.length > 0) {\\n            uint256 amountBefore = IERC20Upgradeable(baseAsset).balanceOf(USSD);\\n            uint256 amountToSellUnits = IERC20Upgradeable(collateral[i].token).balanceOf(USSD) * ((amountToBuyLeftUSD * 1e18 / collateralval) / 1e18) / 1e18;\\n            IUSSD(USSD).UniV3SwapInput(collateral[i].pathsell, amountToSellUnits);\\n            amountToBuyLeftUSD -= (IERC20Upgradeable(baseAsset).balanceOf(USSD) - amountBefore);\\n            DAItosell += (IERC20Upgradeable(baseAsset).balanceOf(USSD) - amountBefore);\\n          } else {\\n```\\n\\nIncase `collateralval < amountToBuyLeftUSD`\\nThis also can't guarantee `(IERC20Upgradeable(baseAsset).balanceOf(USSD) - amountBefore)` < `amountToBuyLeftUSD`.\\n```\\n          if (collateralval >= amountToBuyLeftUSD / 20) {\\n            uint256 amountBefore = IERC20Upgradeable(baseAsset).balanceOf(USSD);\\n            // sell all collateral and move to next one\\n            IUSSD(USSD).UniV3SwapInput(collateral[i].pathsell, IERC20Upgradeable(collateral[i].token).balanceOf(USSD));\\n            amountToBuyLeftUSD -= (IERC20Upgradeable(baseAsset).balanceOf(USSD) - amountBefore);\\n            DAItosell += (IERC20Upgradeable(baseAsset).balanceOf(USSD) - amountBefore);\\n          }\\n```\\n

Impact:
Rebalance process can revert caused by underflow calculation.

Recommended mitigation:
Check if `(IERC20Upgradeable(baseAsset).balanceOf(USSD) - amountBefore)` > `amountToBuyLeftUSD`, in that case, just set `amountToBuyLeftUSD` to 0.\\n```\\n          // rest of code\\n            uint baseAssetChange = IERC20Upgradeable(baseAsset).balanceOf(USSD) - amountBefore);\\n            if (baseAssetChange > amountToBuyLeftUSD) {\\n                amountToBuyLeftUSD = 0;\\n            } else {\\n                amountToBuyLeftUSD -= baseAssetChange;\\n           }\\n            DAItosell += baseAssetChange;\\n          // rest of code\\n```\\n