Skip to content
This repository was archived by the owner on Jan 25, 2026. It is now read-only.

Creamy Indigo Dachshund - realizeRestakerInterest() mints unbacked debt leading to protocol insolvency #667

@sherlock-admin2

Description

@sherlock-admin2

Creamy Indigo Dachshund

High

realizeRestakerInterest() mints unbacked debt leading to protocol insolvency

Summary

The realizeRestakerInterest() function updates internal debt and borrow state based on accrued restaking rewards. However, this function fails to verify whether there is actual yield available in the vault to support the update. As a result, it can mint synthetic protocol debt backed by nothing — leading to systemic insolvency and diluted capital. The flaw affects the core reserve mechanics and can be leveraged to inflate liabilities and compromise solvency across the system.

Root Cause

Debt is realized without confirming asset availability.

The protocol records unrealized restaker interest over time. When a user triggers realizeRestakerInterest(), the function finalizes the interest by increasing:

  • VaultStorage.totalBorrows
  • reservesData[_asset].debt

But the code does not check that there are actually enough funds in the vault to honor this "realized" interest:

$.totalBorrows += realization;
$.reservesData[_asset].debt += realization;

This can mint phantom debt that does not correspond to any yield — fundamentally breaking the 1:1 asset-debt assumption and putting the protocol underwater.

Internal Pre-conditions

  • A restaker deposits a large sum to accumulate unrealizedRestakerInterest
  • The protocol's yield for that asset is delayed or not yet available
  • Vault availableBalance(_asset) is insufficient to support the realization

External Pre-conditions

  • A restaker deposits a large sum to accumulate unrealizedRestakerInterest
  • The protocol's yield for that asset is delayed or not yet available
  • Vault availableBalance(_asset) is insufficient to support the realization

Attack Path

Exploitation Loop:

  1. Attacker stakes a large amount of capital
  2. Waits until unrealizedRestakerInterest accrues
  3. Calls realizeRestakerInterest()
  4. Internal state now treats this amount as owed to the restaker
  5. No check is performed against actual vault liquidity
  6. Protocol reports inflated borrow levels and reserve debt
  7. Liquidation math and pricing logic are now incorrect
  8. Protocol becomes underwater without realizing it

Impact

Protocol-Wide Insolvency Risk

  • Minted Debt Without Yield: Dilutes the backing of capToken and reserve assets
  • Incorrect Borrowing Math: Liquidators and interest rate logic use totalBorrows, which is now corrupted
  • Silent Insolvency: Protocol continues operating with inflated liabilities and incorrect collateral ratios

Accounting Contamination

  • availableBalance() becomes misleading
  • Borrower health factors are skewed
  • Interest rate curve adjusts to wrong utilization numbers

Liquidation Risk

  • Underlying collateral appears worse than it is (bad for borrowers)
  • Liquidation math triggers too early or not at all (bad for protocol)

PoC

function testPhantomDebtViaRealizeInterest() public {
    // Step 1: Restaker deposits into protocol
    stake(10_000_000e18);  // 10M asset

    // Step 2: Wait for interest to accrue
    warp(block.timestamp + 7 days);

    // Step 3: Realize interest
    uint256 preVaultBalance = vaultBalance();
    uint256 preDebt = totalDebt();

    realizeRestakerInterest(asset);  // Does not check if vault has enough

    // Step 4: Assert phantom debt created
    assert(totalDebt() > preDebt);
    assert(vaultBalance() == preVaultBalance);  // No yield actually added

    // Optional: Simulate redemption or borrow to drain funds
}

Mitigation

Insert Debt realization backing check before any update to totalBorrows or reserve.debt

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions