<!-- canonical: https://0xsimao.com/findings/beraborrow-i-lost-withdrawals-managed-den -->

# Lost withdrawals due to `ManagedLeveragedVault::openDen()` using all `asset()` balance

Crit/High · Sherlock · CDP stablecoin · 25th April, 2025

Finding H-1 of the Beraborrow Managed Dens security review.

- Protocol: https://www.beraborrow.com/
- Report: /reports/beraborrow-i
- Source: https://1570492309-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FffzDCMBDa391vIMqruBP%2Fuploads%2FUKDtjc6Dkn6P6i35j5H1%2FManaged%20Leverage%20Vaults%20v0%20private%20audit%20Sherlock.pdf?alt=media&token=c7304efa-8040-4ed0-9a98-dc949af28a85

---

## Summary

`ManagedLeveragedVault::openDen()` picks up all `asset()` and converts to collateral. However, some of these assets may be reserved for withdrawals, in which case the tracking would be completely off.

## Vulnerability Detail

`ManagedLeveragedVault::executeWithdrawalEpoch()` converts collateral vault shares to assets and leaves them in the contract.
```solidity
function executeWithdrawalEpoch(
    ExecuteWithdrawalParams calldata params
) external onlyOwner nonReentrant claimCollateralSurplus(params.upperHint, params.lowerHint) {
    BoycoVaultStorage storage b$ = _getBoycoVaultStorage();

    _checkEpoch(params.epoch);

    CollDebt memory cd = _getCollVaultSharesAndDebtToUnwind(params.epoch);

    b$.borrowerOperations.adjustDen({
        denManager: b$.denManager,
        account: address(this),
        _maxFeePercentage: params.maxFeePercentage,
        _collDeposit: 0,
        _collWithdrawal: cd.collVaultSharesToWithdraw,
        _debtChange: cd.debtToUnwind,
        _isDebtIncrease: false,
        _upperHint: params.upperHint,
        _lowerHint: params.lowerHint
    });

    /// @dev Have assets sitting on the contract for `withdrawFromEpoch` to claim
    uint256 assets = _rebalance(
            RebalanceParams({
                sentCurrency: address(b$.collVault),
                sentAmount: cd.collVaultSharesToWithdraw,
                receivedCurrency: asset(),
                ext: params.unwrapParams
            })
        );
    ...
}
```

`ManagedLeveragedVault::openDen()` picks up all `asset()` available, including the ones reserved for withdrawal.
```solidity
function openDen(
    uint256 _maxFeePercentage,
    uint256 _minCollVaultShares,
    address _upperHint,
    address _lowerHint
) external onlyOwner {
    BoycoVaultStorage storage b$ = _getBoycoVaultStorage();

    IDenManager denManager = IDenManager(b$.denManager);

    uint256 status = denManager.getDenStatus(address(this));
    if (DenStatus(status) != DenStatus.active) revert AlreadyOpened();

    uint256 collVaultShares;
    uint256 assetsAmount = IERC20(asset()).balanceOf(address(this));
    if (assetsAmount != 0) {
        IERC20(asset()).approve(address(b$.collVault), assetsAmount);
        collVaultShares = b$.collVault.deposit(assetsAmount, address(this));
        if (collVaultShares < _minCollVaultShares) revert VaultSlippage(_minCollVaultShares, collVaultShares);
    }
    ...
}
```

## Impact

DoSed withdrawals, loss of funds as the shares/assets ratio will be off because the shares were already burned.

## Code Snippet

https://github.com/sherlock-audit/2025-04-beraborrow-vault-update/pull/1/files#diff-2d972f52027e0ba1065b2de2b424416244bfef9e2a79d2604e1687867f72c91eR521

## Tool Used

Manual Review

## Recommendation

Include the reserved assets for withdrawal in the calculation.

---

Related findings:

- [DarkpoolAssetManager::Split() into 2 equal amounts leads to lost funds](https://0xsimao.com/findings/singularity-darkpool-split-equal-amounts): Singularity
- [DoSed liquidations as `PrizeVault::liquidatableBalanceOf()` does not take into account the `mintLimit` when the token out is the asset](https://0xsimao.com/findings/pooltogether-the-prize-layer-for-defi-liquidations-prize-liquidatable-mint): PoolTogether Prize Layer
- [Withdrawing all `lv` before expiry will lead to lost funds in the Vault](https://0xsimao.com/findings/cork-protocol-withdrawing-expiry-lost-funds): Cork Protocol
- [Changing providers might lead to lost assets in BorrowingVault and YieldVault](https://0xsimao.com/findings/fuji-finance-changing-providers-lost-yield): Fuji Finance
