Skip to content

Latest commit

 

History

History
61 lines (43 loc) · 3.07 KB

028.md

File metadata and controls

61 lines (43 loc) · 3.07 KB

Obedient Lava Monkey

Medium

Improper Handling of Virtual Balances Allows Reserve Virtual Accounting Desynchronization

Summary

The failure to correctly update virtualUnderlyingBalance in updateInterestRatesAndVirtualBalance when virtual accounting is active will cause reserve desynchronization for reserves using virtual balances as the virtual balance can become out of sync with actual liquidity.


Root Cause

In ReserveLogic.sol, the updateInterestRatesAndVirtualBalance function adjusts virtualUnderlyingBalance only when liquidityAdded or liquidityTaken is greater than zero:

if (reserveCache.reserveConfiguration.getIsVirtualAccActive()) {
    if (liquidityAdded > 0) {
        reserve.virtualUnderlyingBalance += liquidityAdded.toUint128();
    }
    if (liquidityTaken > 0) {
        reserve.virtualUnderlyingBalance -= liquidityTaken.toUint128();
    }
}

This logic does not account for scenarios where borrowing or repayment affects the underlying liquidity but does not reflect as liquidityAdded or liquidityTaken. For example, when virtual balances are manually adjusted or updated indirectly, this omission can lead to desynchronized virtual balances. Imagine a bank keeps a "virtual ledger" of its money, separate from the actual cash in its vault. If someone borrows or repays money in a way that doesn't directly update the virtual ledger, the ledger can become out of sync with the real cash. This mismatch causes the bank to miscalculate interest rates or think it has more or less money than it actually does.


Internal Pre-conditions

  1. The reserve is configured with virtual accounting active.
  2. Borrowing or repayment indirectly affects the underlying liquidity but does not register liquidityAdded > 0 or liquidityTaken > 0.

External Pre-conditions

  1. Virtual accounting logic relies on synchronization between virtualUnderlyingBalance and actual liquidity.

Attack Path

  1. User borrows or repays indirectly affecting liquidity.
  2. Virtual balance is not updated due to the lack of direct liquidityAdded or liquidityTaken.
  3. Protocol operates on desynchronized virtual balances, leading to incorrect interest rate calculations or liquidity accounting.

Impact

The protocol reserves using virtual accounting suffer from desynchronized balances, causing incorrect interest rate calculations and liquidity mismanagement.


Mitigation

Ensure virtualUnderlyingBalance is always synchronized with actual liquidity changes by expanding the update logic:

if (reserveCache.reserveConfiguration.getIsVirtualAccActive()) {
    reserve.virtualUnderlyingBalance = calculateActualUnderlyingBalance();
}