<!-- canonical: https://0xsimao.com/findings/fuji-finance-rebalancer-drain-rebalancing-loop -->

# REBALANCER_ROLE can drain funds by rebalancing in a loop in the BorrowingVault

Crit/High · Three Sigma · Lending aggregator · 6th May, 2023

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

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

---

### Description

The rebalancer in the borrowing vault receives a fee for providing debtAsset to repay the
originating provider and send to the destination provider. A malicious provider could use this
to profit, for example max fee = 10 / 10000 = 1 / 1000 = 0.001 100_000 debt -> 100_100 100_100 deby -> 100200.1 and so on…
For this attack, the attacker only needs to pay a flashloan fee once (or have the initial
funds available).

### Recommendation

The likelihood of this attack is reduced because the rebalancer is a privileged role, but
maybe adding a timelock to the rebalancing function would be a good measure so that the
chief can disallow a rebalancer if they behave maliciously, before they profit too much from
this exploit.

### Status

Acknowledged with the following statement:
The issue identified is acknowledged by the Fuji team, however, the team will implement the
following security measures at the BorrowingVault at a later stage. The rationale to delay
the fixes is that the team does not consider this issue an imminent user risk considering
that only the RebalancerManager contract should have the REBALANCER role. In addition the
BorrowingVault bytecode size is near limits and additional logic is not possible until a
major refactor. The future measures that will be considered are:
1.
Restricting the REBALANCER_ROLE to only contract implementations. This action will
reduce the chance of a compromised EOA account.
2. Adding a non-reentrant restriction to the rebalance(...) function. This action will
restrict the looping optionality that is described in this issue.

---

Related findings:

- [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
- [BasicVault::_redeem() burns newAmount but redeems amount, allowing attackers to drain the vault](https://0xsimao.com/findings/mitosis-redeem-burns-redeems-drain): Mitosis
- [Admin new issuance or user calling `Vault::redeemExpiredLv()` after `Psm::redeemWithCt()` will lead to stuck funds when trying to withdraw](https://0xsimao.com/findings/cork-protocol-issuance-redeem-stuck-withdraw): Cork Protocol
- [Users will steal excess funds from the Vault due to `VaultPoolLib::redeem()` not always decreasing `self.withdrawalPool.raBalance` and `self.withdrawalPool.paBalance`](https://0xsimao.com/findings/cork-protocol-steal-excess-redeem-withdrawal): Cork Protocol
