Back to Insights
March 30, 20265 min readen

Research:Anatomy of a Morpho vault NAV flash loan manipulation attack after the USR depeg

On March 22, 2026, the Resolv protocol suffered a private key compromise. The attacker minted 80 million unbacked USR tokens out of thin air, crashing USR from $1 to as low as $0.025. But the blast radius extended far beyond USR holders — a separate group of sophisticated actors exploited Morpho's vault mechanics to extract real value through a precision NAV manipulation attack. This article breaks down the underlying logic, step by step. 1. Understanding Morpho's two-layer architecture Befo

Research:Anatomy of a Morpho vault NAV flash loan manipulation attack after the USR depeg

On March 22, 2026, the Resolv protocol suffered a private key compromise. The attacker minted 80 million unbacked USR tokens out of thin air, crashing USR from $1 to as low as $0.025. But the blast radius extended far beyond USR holders — a separate group of sophisticated actors exploited Morpho's vault mechanics to extract real value through a precision NAV manipulation attack.

This article breaks down the underlying logic, step by step.

1. Understanding Morpho's two-layer architecture

Before we can discuss the attack, you need to understand how Morpho is structured. Without this context, nothing that follows will make sense.Morpho's world is split into two layers:

The base layer: Morpho Blue (a.k.a. Morpho Core). This is a minimalist, immutable lending protocol. Its design philosophy is "permissionless" — anyone can create a lending market, and anyone can supply, borrow, or liquidate. Each market is uniquely defined by five parameters: loan asset, collateral asset, liquidation LTV (LLTV), oracle address, and interest rate model.

Markets are fully isolated from one another.

The upper layer: MetaMorpho Vault. This is an ERC-4626 compliant vault — think of it as a "fund product." Users deposit USDC into the vault, and the vault curator allocates those funds across multiple Morpho Blue markets to earn lending interest.

Users hold vault shares, whose value appreciates as interest accrues.

The key formula — net asset value per share (NAV):NAV per share = totalAssets / totalSupply

totalAssets is the sum of the vault's supply positions across all markets (including lent-out capital, since those are "receivables"). totalSupply is the total number of shares the vault has issued. As interest accrues, totalAssets grows while totalSupply stays constant, so NAV rises — that's how depositors earn yield.

Here's the actual code:

function totalAssets() public view override returns (uint256 assets) {
for (uint256 i; i < withdrawQueue.length; ++i) {
assets += MORPHO.expectedSupplyAssets(
_marketParams(withdrawQueue[i]), address(this)
);
}
}

It iterates over every market in the vault's withdraw queue and sums up the vault's expected supply assets. Note that expectedSupplyAssets is calculated from Morpho Blue's internal accounting — as long as the protocol "believes" a loan is healthy (oracle says collateral is sufficient), it's counted at face value.

2. supply(onBehalf) — anyone can deposit on behalf of the vault

This is the first critical piece of the attack.In Morpho Blue, the supply() function takes an onBehalf parameter. The original intent was to enable third-party deposits — for example, automated strategy contracts depositing on behalf of users.

But it's completely permissionless: anyone can specify any address as onBehalf, including a vault address.

From the official Morpho docs: "Warning: Anyone can supply on behalf of the vault so the call to updateWithdrawQueue that expects a market to be empty can be griefed by a front-run."When you supply 10,000 USDC on behalf of a vault, the vault's supply position in that market increases by 10,000, and so does totalAssets. But totalSupply (total shares) doesn't change — because nobody called the vault's deposit() function.

Result: NAV per share increases.Under normal circumstances, this is equivalent to "donating" money to the vault — you're enriching all existing shareholders at your own expense. Nobody rational would do this. But under specific conditions, it can be weaponized.

3. Supply Cap = 0 does not mean safe

After the USR depeg, some vault curators urgently set the USR/USDC market's Supply Cap to 0. At the MetaMorpho Vault level, Supply Cap limits how much the allocator can deploy to a given market through the vault interface. Cap = 0 means no more capital can be routed there.Sounds like the problem is solved?The issue:

Supply Cap is a vault-layer restriction, not a Morpho Blue-layer restriction.

The vault curator controls the vault's internal _supplyMorpho() function. But supply(onBehalf=vault) interacts directly with the Morpho Blue Core contract, completely bypassing the vault's logic: supply queue, supply cap, allocator permissions — none of it applies.Re7 Labs confirmed this in their post-incident report, classifying it as a "Morpho protocol-level design issue."

4. The hardcoded oracle — bad debt's invisibility cloak

This is the second critical condition.The USR/USDC market's oracle was set to a fixed 1:1 rate. Regardless of USR's actual market price, Morpho's internal accounting permanently treats 1 USR = 1 USDC.

Why would a curator use a fixed oracle? Because USR is a "stablecoin" — normally its price fluctuates minimally. A fixed oracle avoids unnecessary liquidations from short-term liquidity-driven price noise. But when USR actually depegs, the fixed oracle becomes a disaster. Borrowers post worthless USR as collateral and walk away with full-value USDC loans, and the protocol is none the wiser.

Morpho's bad debt mechanisms completely fail here — both V1.0's instant realization and V1.1's socialized loss model require the protocol to first recognize bad debt. A hardcoded oracle means there's nothing to recognize.

5. The full attack — a five-step closed loop

With all preconditions in place, here's the complete atomic operation executed within a single transaction:

A note on the cash flow math: The supply of 14,109 USDC and the borrow of 14,109 USDC cancel out — the attacker's cash position is unchanged. The borrow isn't "extra profit" — it's recovering the funds spent on the supply.

Without borrowing back, the attacker would be down 14,109 and the attack wouldn't be profitable. The only real profit source is the 12,300 surplus from redeeming inflated shares, minus the 10,000 cost of buying USR.

6. Why the flash loan is essential

The profit mechanism is "inflate totalAssets, then claim the increase pro-rata based on share ownership." If the attacker holds 0% of shares, all of the appreciation goes to other shareholders — the attacker gets nothing.

7. Who loses money?

The 12,300 USDC the attacker extracted didn't appear from thin air. It came from the vault's real liquidity in other healthy markets.When the attacker redeems, the vault contract pulls USDC from its markets according to the withdraw queue.

The USR market has no USDC left (the attacker borrowed it all). So the redemption draws from other markets — wETH/USDC, cbBTC/USDC, and other normally functioning pools.

8. Three vulnerabilities in concert

This attack isn't a single vulnerability. It's the compounding of three design issues:

Conclusion

Morpho's minimalist design philosophy — permissionless, immutable, governance-minimized — is a strength in most scenarios. It's why the protocol accumulated billions in TVL in a short period.

But this incident demonstrates that the cost of minimalist design is shifting greater responsibility to the upper-layer participants. The protocol doesn't validate oracles, so curators must. The protocol doesn't restrict supply(onBehalf), so the vault layer needs additional safeguards.

For depositors, "choosing the right curator" matters more than "choosing Morpho." The protocol is a tool; whether the tool is safe depends on who wields it.