<!-- canonical: https://0xsimao.com/findings/fuji-finance-handling-someone-debt-differently -->

# Handling someone else repaying debt for the BorrowingVault could be done differently

Low/Info · Three Sigma · Lending aggregator · 6th May, 2023

Finding 3S-FUJI-L01 of the Fuji Finance security review.

- Report: /reports/fuji-finance
- Source: https://cdn.sanity.io/files/qoqld077/staging/32181a28eac3175d15fb8924d249bb0d91ca350c.pdf

---

### Description

In _convertDebtToShares(...), if totalDebt(...) is 0, it reverts. This means that, if
someone decides to repay the full vault debt, this function would always revert. The current
measure taken is pausing the vault and then borrowing a debt amount equal to the debt
shares. This leads to a temporary halting of the vault and it may require rebalancing the
providers to enable borrowing all the debt from the same provider (if the debt was
distributed among many providers).

### Recommendation

The Openzeppelin ERC4626 implementation, instead of placing totalAssets(...) in the
denominator (here equivalent to totalDebt(...)), places totalAssets(...) + 1 (also
adds 1 when converting shares to assets). The yield vault could also use this logic, although
I don't think it's possible for the totalAssets(...) to be 0 and the shares different from 0.
This would fix this problem, take a look at the following example
There are 10000 shares and 10000 assets.
User repays 10000 assets (directly at provider(s)), and now the supply is 10000 and
totalDebt is 0.

Some user wants to borrow 100 debt:
shares = debt * supply / (totalAssets + 1) = 100 * 10_000 / 1 = 1_000_000
if this user tries to pay back the debt
debt = shares * (totalAssets + 1) / supply = 1_000_000 * 101 / 1_010_000 = 100
which adds up correctly
if another user wants to repay their debt, the calculation would be
shares = 100, supply = 10000, assets = 0
debt = shares * (totalAssets + 1) / supply = 100 * 1 / 10000 = 0
which means their debt would have been paid by the attacker. It would only increase if they
borrow more, which would work correctly, as shown in the previous example.

### Status

Addressed here: [Fujicracy/fuji-v2#640](https://github.com/Fujicracy/fuji-v2/pull/640)

---

Related findings:

- [DoSed withdrawals due to `ManagedLeveragedVault::executeWithdrawalEpoch()` repaying debt above limit](https://0xsimao.com/findings/beraborrow-i-withdrawals-withdrawal-epoch-debt): Beraborrow Managed Dens
- [Hints on withdrawal may fail as the ICR changes between claiming collateral surplus and repaying debt](https://0xsimao.com/findings/beraborrow-i-hints-withdrawal-collateral-debt): Beraborrow Managed Dens
- [Liquidations will leave dust when repaying expired maturities, making it impossible to clear bad debt putting the protocol at a risk of insolvency](https://0xsimao.com/findings/exactly-protocol-update-staking-contract-ii-liquidations-dust-debt-insolvency): Exactly Protocol Update - Staking Contract
- [Malicious user can call `borrowing::calculateCumulativeRate()` any number of times to inflate debt rate as `lastEventTime` is not updated](https://0xsimao.com/findings/autonomint-calculate-times-inflate-debt): Autonomint
