<!-- canonical: https://0xsimao.com/findings/beraborrow-i-debt-unwind-requested-inaccurate -->

# `ManagedLeveragedVault::getDebtToUnwindAndCollRequested()` is inaccurate when there are surplus tokens

Low/Info · Sherlock · CDP stablecoin · 25th April, 2025

Finding L-8 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::getDebtToUnwindAndCollRequested()` is called on chain after the modifier `claimCollateralSurplus` is called, so it is updated, but offchain this modifier was not called and the view function is off.

## Vulnerability Detail

`ManagedLeveragedVault::getDebtToUnwindAndCollRequested()` returns the debt to unwind and coll requested, but doesn't include the coll surplus as a view function offchain:
```solidity
function getDebtToUnwindAndCollRequested(uint256 _epoch) public view returns (uint256 debtToUnwind, uint256 collVaultSharesRequested, uint256 shareFee) {
    BoycoVaultStorage storage b$ = _getBoycoVaultStorage();
    ManagedLeveragedVaultStorage storage $ = _getManagedLeveragedVaultStorage();

    uint256 totalShares = $.reports[_epoch].totalShares;

    if (totalShares == 0) revert AmountZero();

    uint256 requestedAssets;
    (requestedAssets, shareFee) = _previewRedeem(totalShares);

    collVaultSharesRequested = _assetsToCollVaultShares(requestedAssets);

    (uint256 collVaultShares, uint256 debt) = IDenManager(b$.denManager).getDenCollAndDebt(address(this));

    // Find proportional debt unwind to collateral, so that ICR is unchanged, we assume an already pretty close ICR
    // If we were to responsabilize withdrawers to targetICR with a current deviated denICR, it would only responsabilize them to pay the slippage/borrow costs
    // Instead, we responsabilize both withdrawers and depositors, only using `increaseLeverage` and `decreaseLeverage`, which socializes losses
    debtToUnwind = debt * collVaultSharesRequested / collVaultShares; /// @dev Check `collVaultSharesRequested` can't be > `collVaultShares`
}
```
Essentially when it is called offchain `collVaultShares` doesn't include the surplus balance, but on chain it will always include it.

## Impact

View function is incorrect.

## Code Snippet

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

## Tool Used

Manual Review

## Recommendation

Include the surplus balance if it exists.

---

Related findings:

- [BorrowingVault, if the debt/assets ratio falls too much, liquidators could choose to repay debt equal to the assets at a discount](https://0xsimao.com/findings/fuji-finance-debt-falls-choose-repay): Fuji Finance
- [Handling someone else repaying debt for the BorrowingVault could be done differently](https://0xsimao.com/findings/fuji-finance-handling-someone-debt-differently): Fuji Finance
- [It's possible for debt to be stuck in the LoopedVault when rebalancing from Aave to Morpho](https://0xsimao.com/findings/yieldoor-iii-debt-stuck-aave-morpho): Yieldoor LoopedVault Update
- [ATokens can be swept of the `PreDepositVault`](https://0xsimao.com/findings/gaib-tokens-swept-pre-deposit): GAIB Pre-Vaults
