MEDIUM severity: [ASTRO-24] Wrong rebalance implementation. **Severity:** Medium

**Path:** Crate.sol

**Description:** When a user withdraws their assets or shares using the `withdraw()` or `redeem()` functions, the pool is not being rebalanced. Therefore, if the case of another user also wants to withdraw, they may end up withdrawing the wrong amount of...

Vulnerable code:
function _withdraw(
        uint256 _amount,
        uint256 _shares,
        uint256 _minAmountOut,
        uint256 _deadline,
        address _receiver,
        address _owner
    ) internal nonReentrant returns (uint256 recovered) {
        if (_amount == 0 || _shares == 0) revert AmountZero();

        // We spend the allowance if the msg.sender isn't the receiver
        if (msg.sender != _owner) {
            _spendAllowance(_owner, msg.sender, _shares);
        }

        // Check for rounding error since we round down in previewRedeem.
        if (convertToAssets(_shares) == 0)
            revert IncorrectAssetAmount(convertToAssets(_shares));

        // We burn the tokens
        _burn(_owner, _shares);

        // Allows to take a withdraw fee
        _amount = (_amount * (MAX_BPS - withdrawFee)) / MAX_BPS;

        if (liquidityPoolEnabled) {
            // We don't take into account the eventual slippage, since it will
            // be paid to the depositoors
            liquidityPool.debt -= Math.min(_amount, liquidityPool.debt);
            try
                liquidityPool.swap.swapVirtualToAsset(
                    _amount,
                    _minAmountOut,
                    _deadline,
                    _receiver
                )
            returns (uint256 dy) {
                recovered = dy;
            } catch {
                // if the swap fails, we send the funds available
                asset.safeTransfer(_receiver, _amount);
                recovered = _amount;
            }
        } else {
            // If the liquidity pool is not enabled, we send the funds available
            // This allows for the bootstrapping of the pool at start
            asset.safeTransfer(_receiver, _amount);
            recovered = _amount;
        }

        if (_minAmountOut > 0 && recovered < _minAmountOut)
            revert IncorrectAssetAmount(recovered);

        emit Withdraw(msg.sender, _receiver, _owner, _amount, _shares);
        return (recovered);
    }

    // !SECTION

    /*//////////////////////////////////////////////////////////////
                        // SECTION LIQUIDITY MANAGEMENT
    //////////////////////////////////////////////////////////////*/

    // TODO: Should this function be whitelisted?
    /// @notice Rebalance the Liquidity pool using idle funds and liquid strats
    function rebalanceLiquidityPool()
        public
        whenNotPaused
        returns (uint256 earned)
    {
        // Reverts if we the LP is not enabled
        if (!liquidityPoolEnabled) revert LiquidityPoolNotSet();

        // We check if we have enough funds to rebalance
        uint256 toSwap = _getAmountToSwap(
            asset.balanceOf(address(this)),
            liquidityPool
        );

        if (toSwap == 0) revert NoFundsToRebalance();
        uint256 recovered = liquidityPool.swap.swapAssetToVirtual(
            toSwap,
            block.timestamp + 100
        );
        liquidityPool.debt += recovered;
        earned = recovered - Math.min(toSwap, recovered);

        emit LiquidityRebalanced(recovered, earned);
        emit SharePriceUpdated(sharePrice(), block.timestamp);
    }