Are you an LLM? Read llms.txt for a summary of the docs, or llms-full.txt for the full context.
Skip to content

Emergency Procedures (Vaults V2)

This document outlines procedures for handling emergency situations in Morpho Vaults V2. These actions should be executed with extreme care, as they can have significant consequences for the vault and its depositors.

Before proceeding, ensure you are familiar with Roles & Capabilities, Timelocks, and Adapters.

Quick Reference

ActionTimelocked?Who Can Execute
Revoke any pending timelocked actionNoCurator, Sentinel
Decrease absolute/relative caps to 0NoCurator, Sentinel
Deallocate funds to idleNoAllocator, Sentinel
Force deallocate (in-kind redemption)NoAnyone (permissionless, subject to penalty)
Remove allocator role (setIsAllocator)Yes (configurable)Curator via submit
Remove adapter (removeAdapter)YesCurator via submit
Burn shares (adapter-level, MarketV1AdapterV2)Yes (adapter timelock)Curator via adapter submit

Unsafe Market: Soft Deprecation

Use this procedure when a specific market (or all markets sharing a collateral type) is deemed too risky, but the adapter itself is functioning correctly. The adapter remains active — you are only restricting and exiting the specific market.

This is the most common emergency action and should be the default response when a risk concern is identified at the market level rather than the adapter or protocol level.

Procedure

Step 1 — Revoke Pending Cap Increases for the Affected Id(s)

If there are pending cap increases for the market-level or collateral-level id, the Sentinel or Curator should call revoke(bytes) to cancel them.

// Revoke a pending cap increase on a specific market id
bytes memory pendingData = abi.encodeCall(IVaultV2.increaseAbsoluteCap, (marketIdData, newCap));
vault.revoke(pendingData);
Step 2 — Decrease the Market or Collateral Cap to Zero

The Curator or Sentinel calls decreaseAbsoluteCap and/or decreaseRelativeCap for the specific id associated with the affected market or collateral. This is an instant action — it is explicitly exempt from timelocks.

To deprecate a single market:

// idData targets the specific market
// e.g. keccak256(abi.encode("this/marketParams", adapterAddress, marketParams))
vault.decreaseAbsoluteCap(marketIdData, 0);
vault.decreaseRelativeCap(marketIdData, 0);

To deprecate all markets sharing a collateral type:

// idData targets the collateral
// e.g. keccak256(abi.encode("collateralToken", collateralTokenAddress))
vault.decreaseAbsoluteCap(collateralIdData, 0);
vault.decreaseRelativeCap(collateralIdData, 0);
Step 3 — Reallocate Liquidity Out of the Affected Market

The Allocator or Sentinel calls deallocate to withdraw assets from the affected market. These assets can be:

  • Moved as idle assets in the vault.
  • Reallocated into other markets within the same adapter (via a subsequent allocate call), if those markets are healthy and have available cap room.
  • Deposited into the Liquidity Adapter, if it has available cap room.
// Deallocate from the affected market into vault idle assets
vault.deallocate(adapter, affectedMarketData, assets);
 
// Optionally reallocate into a healthy market on the same adapter
vault.allocate(adapter, healthyMarketData, assets);

If the market is illiquid, this may need to be done in stages as liquidity becomes available. In this case, monitoring should be set up to deallocate progressively.


Unsafe Adapter: Soft Deprecation

Use this procedure when an adapter is deemed too risky for continued allocation, but all contracts are still functioning correctly and funds can be withdrawn normally.

Procedure

Step 1 — Revoke Pending Cap Increases

If there are any pending cap increases for ids associated with the adapter, the Sentinel or Curator should call revoke(bytes) on the vault to cancel them.

// Revoke a pending absolute cap increase
bytes memory pendingData = abi.encodeCall(IVaultV2.increaseAbsoluteCap, (idData, newCap));
vault.revoke(pendingData);
Step 2 — Set Caps to Zero

The Curator or Sentinel calls decreaseAbsoluteCap and decreaseRelativeCap for all ids associated with the adapter, setting them to 0. This prevents any new allocations to the adapter.

vault.decreaseAbsoluteCap(idData, 0);
vault.decreaseRelativeCap(idData, 0);
Step 3 — Deallocate Liquidity to Idle

The Allocator or Sentinel calls deallocate on the vault to withdraw all available assets from the adapter back to idle. If the underlying market is illiquid, this may need to be done in stages as liquidity becomes available.

vault.deallocate(adapter, data, assets);
Step 4 — Remove the Adapter

Once the adapter's allocation reaches zero, the Curator calls submit to propose removeAdapter. This action is timelocked. After the timelock expires, anyone can execute the removal.

// Submit removal (timelocked)
vault.submit(abi.encodeCall(IVaultV2.removeAdapter, (adapterAddress)));
 
// After timelock expires, execute
vault.removeAdapter(adapterAddress);

Market Reverts: Hard Deprecation

Use this procedure when an underlying market is malfunctioning (e.g., its functions consistently revert), making it impossible to withdraw funds normally. This action involves accepting the loss of any capital stuck in the market.

MorphoMarketV1AdapterV2 — Burn Shares

The MorphoMarketV1AdapterV2 has its own independent timelock system. Forced market removal happens at the adapter level via burnShares, which zeroes out the adapter's internal share accounting for a specific market.

Step 1 — Set Caps to Zero

As with soft deprecation, the Curator or Sentinel should immediately decrease all caps to zero for ids associated with the market.

Step 2 — Submit burnShares (Timelocked at Adapter Level)

The Curator calls submit on the adapter itself (not the vault) to propose burning the shares for the broken market.

// Submit to the adapter (not the vault)
adapter.submit(abi.encodeCall(IMorphoMarketV1AdapterV2.burnShares, (marketId)));

The mandatory waiting period must elapse. During this time, the Sentinel or Curator can revoke via the adapter's revoke function if needed.

Step 3 — Execute burnShares

After the adapter timelock expires, anyone can execute the burn.

adapter.burnShares(marketId);
Step 4 — Sync Vault Accounting

Deallocate 0 from the vault to update its internal allocation tracking.

vault.deallocate(adapter, data, 0);

MorphoVaultV1Adapter

For the MorphoVaultV1Adapter, forced removal happens at the vault level since this adapter wraps an entire Vault V1 position rather than individual markets. In this scenario, follow the procedure in V1 Emergency Actions.

Impact on Depositors

Morpho Vault V2 implements automatic loss socialization: when the adapter's realAssets() reports a value lower than previously recorded totalAssets, the vault updates its accounting downward, and the loss is reflected proportionally in the share price for all depositors. For a detailed breakdown of how this accounting update is computed, see Managing Bad Debt.

If the underlying adapter wraps a Vault V1.1, note that V1.1 does not realize bad debt internally — so the Morpho Vault V2 will also not reflect those specific losses.


Allocator Compromise

If an Allocator is compromised or acting maliciously, the Curator should act to remove the role and correct any misallocations. The Allocator can only operate within the bounds set by the Curator (enabled adapters and caps), so the blast radius is limited to misallocation within the allowed set.

Procedure

Step 1 — Remove the Allocator Role

The Curator calls submit to propose setIsAllocator(compromisedAddress, false).

vault.submit(abi.encodeCall(IVaultV2.setIsAllocator, (compromisedAddress, false)));
 
// If timelock is 0, execute immediately
vault.setIsAllocator(compromisedAddress, false);

If the setIsAllocator timelock is non-zero, proceed to Step 2 while waiting.

Step 2 — Set Caps to Zero

The Sentinel (or Curator) should immediately decrease all caps to zero. This is instant (cap decreases are exempt from timelocks) and neutralizes the allocator regardless of whether the role removal is timelocked.

vault.decreaseAbsoluteCap(idData, 0);
vault.decreaseRelativeCap(idData, 0);
Step 3 — Correct Misallocations

A trusted Allocator or the Curator should deallocate from any wrongly allocated positions and reallocate according to the vault's intended strategy.

vault.deallocate(adapter, data, assets);

Once the compromised allocator is removed, the Curator re-establishes caps and assigns a new allocator.


Curator Compromise

If the Curator begins acting maliciously (submitting caps for unsafe adapters or markets, adding untrusted markets or caps, changing fees or gates), the Owner and Sentinel must coordinate a response.

Procedure

Step 1 — Owner Replaces the Curator (Instant)

The Owner immediately calls setCurator to transfer control to a new, trusted address. This is not timelocked — the Owner can execute this instantly.

vault.setCurator(newTrustedCurator);

This instantly strips the compromised address of all Curator capabilities.

Step 2 — Sentinel Revokes All Pending Actions (Instant)

The Sentinel must call revoke on every pending timelocked action submitted by the compromised curator. In V2, revoke(bytes) can cancel any pending timelocked action — adapter additions, cap increases, fee changes, gate changes, allocator changes, timelock decreases, etc.

vault.revoke(pendingMaliciousData);
Step 3 — Assess Accepted Malicious Actions

If any malicious changes were executed before they could be revoked:

  • Malicious adapter was added: The new Curator follows the Soft Deprecation procedure to safely exit. Set caps to zero, deallocate all funds, then submit removeAdapter.
  • Caps were increased on unsafe ids: The new Curator or Sentinel instantly decreases caps to zero.
  • Fees were changed: The new Curator submits corrected fee values (timelocked).
  • Gates were changed: The new Curator submits corrected gate values (timelocked).

Adapter-Level Remediation (MorphoMarketV1AdapterV2)

If the vault uses MorphoMarketV1AdapterV2, the adapter has its own timelock system and checks IVaultV2(parentVault).curator() for authorization. Replacing the curator at the vault level automatically revokes the compromised address's access to adapter-level submit calls.

However, any actions the compromised curator already submitted to the adapter remain pending. The new curator (or Sentinel) should revoke those at the adapter level as well:

adapter.revoke(pendingAdapterData);

Owner Compromise

Owner compromise is the most severe scenario. In Morpho Vault V2, the Owner's powers are intentionally limited — they can only set the Curator and Sentinels. They cannot directly modify caps, adapters, fees, or allocations. However, a compromised Owner can appoint a malicious Curator, which cascades into a Curator compromise scenario.

Depositors must exit the vault before malicious configuration changes take effect. The vault should be considered permanently compromised.

Procedure

Step 1 — Sentinel Blocks Immediate Damage (Instant)

If the compromised Owner sets a malicious Curator who begins submitting harmful proposals, the Sentinel (if not yet replaced) can revoke all pending actions.

The Sentinel should also proactively:

  • Decrease all caps to zero (preventing new allocations).
  • Deallocate all funds to idle (moving funds to the safest position).
Step 2 — Depositors Exit Within the Timelock Window

All depositors should withdraw their funds before any malicious timelocked actions expire. The timelock is the depositors' primary defense.

Step 3 — Last Resort: forceDeallocate

If the vault lacks idle liquidity for normal withdrawals, depositors can use the permissionless forceDeallocate to move assets from adapters to idle, then withdraw.


Sentinel Compromise

Sentinel compromise is the least severe role compromise, because the Sentinel can only perform risk-reducing actions: revoking pending actions, decreasing caps, and deallocating.

Impact

A compromised Sentinel could:

  • Revoke legitimate pending proposals (denial of service, not loss of funds).
  • Decrease caps to zero (forces vault to idle, no loss of funds).
  • Deallocate funds to idle (moves everything to idle, no loss of funds).

Procedure

The Owner calls setIsSentinel(compromisedAddress, false) to remove the compromised sentinel and appoint a new one.

vault.setIsSentinel(compromisedAddress, false);
vault.setIsSentinel(newSentinel, true);

The Curator then re-submits any legitimate proposals that were revoked by the compromised sentinel.