All incidents

Morpho-Pendle flash-loan liquidation MEV captures undercollateralized spread

Share
Feb 04, 2026 13:46 UTCMEVGain: 71,682.85 USDCManually checked2 exploit txWindow: 2m 24s
Estimated Impact
71,682.85 USDC
Label
MEV
Exploit Tx
2
Addresses
2
Attack Window
2m 24s
Feb 04, 2026 13:46 UTC → Feb 04, 2026 13:49 UTC

Exploit Transactions

TX 1Ethereum
0xee2b216b7d649513dc8ba102e130d3d86d189b393a0d5f387e479be3dbda799d
Feb 04, 2026 13:46 UTCExplorer
TX 2Ethereum
0x047fcfa2cfb51879f19769dd25e2768be42985f9c2d8f483f2a0c18703834061
Feb 04, 2026 13:49 UTCExplorer

Victim Addresses

0xE5B2FAbF3b2000eB6b03Bb4EbeA80fABC6159cF0Ethereum
0xcbfdbae49883e378752ff3f64bf8d89562912da6Ethereum

Loss Breakdown

71,682.85USDC

Similar Incidents

Root Cause Analysis

Morpho-Pendle flash-loan liquidation MEV captures undercollateralized spread

1. Incident Overview TL;DR

On Ethereum mainnet block 24,383,881 and 24,383,893, an unprivileged adversary cluster used Morpho Blue USDC flash loans together with PendleRouterV4 and PendleMarketV6 to unwind two large Pendle LP positions that were backing debt-like strategies. In transaction 0xee2b216b... and transaction 0x047fcfa2..., the attackers deployed short-lived orchestrator contracts that immediately called Morpho::flashLoan on a USDC market, routed the borrowed USDC and NUSD through adapters and Pendle SY contracts, and then used PendleMarketV6 to burn LP held by vault-like victim addresses 0xE5B2FAbF3b2000eB6b03Bb4EbeA80fABC6159cF0 and 0xcbfdbae49883e378752ff3f64bf8d89562912da6. The resulting SY/PT flows were swapped back into USDC, the flash loans were repaid with fees, and residual USDC balances of 25,774,896,133 and 45,907,952,190 units accrued to adversary EOAs 0x53695b... and 0x1f3606..., for a combined net profit of 71,682,848,323 USDC units after gas.

The root cause is not a contract bug in Morpho or Pendle. Instead, it is an ACT-style, permissionless MEV liquidation/unwind opportunity created by the combination of: (1) Morpho’s public flash-loan primitive; (2) Pendle’s public router and market functions (burn, swapExactPtForSy) that allow LP representing third-party exposure to be burned by anyone who can pull the LP into the market; and (3) victim strategies that left large Pendle LP positions available to be unwound via these public paths.

2. Key Background

The incident involves interactions between Morpho Blue, a generalized lending protocol, and Pendle, a protocol for tokenizing yield and providing interest-rate/LP exposure via SY (standardized yield) and PT (principal token) markets.

On the lending side, Morpho Blue exposes a flash-loan interface for supported loan tokens (here USDC). Morpho’s verified source (src/Morpho.sol in the collected artifacts) shows that flashLoan transfers loan tokens out to an IMorphoFlashLoanCallback implementer and requires that the callback repay amount + fee before the call completes. Morpho tracks positions by market and borrower and enforces health-factor and repayment invariants, but does not restrict which unprivileged caller may initiate a flash loan.

On the AMM side, PendleMarketV6 implements an automated market maker over an SY/PT pair and issues LP tokens representing proportional claims on reserves. The collected Pendle source (PendleMarketV6.sol under the Pendle repository in the seed artifacts) shows that LP is minted via mint and burned via burn, and that internal accounting variables totalPt and totalSy are updated only in a small set of functions that change reserves (mint, burn, swapExactPtForSy, swapSyForExactPt, skim). Invariants ensure that the contract’s token balances are at least as large as these tracked totals.

Two Pendle markets are relevant:

  • REUSDSY market at 0xf5929a1c332ceab7918a4593a43db2b9ac20095f, with SY token PendleREUSDSY at 0x9487bd5a3b16ecb5f3184453e3ee75b800141648.
  • NUSD SY market at 0x6d520a943a4da0784917a2e71defe95248a1daa1, with SY token PendleERC20WithAdapterAndSupplyCapSY at 0x29ac34026c369d21fe3b2c7735ec986e2880b347.

In both markets, vault-like contracts (the victim addresses 0xE5B2... and 0xcbfdba...) held large LP positions. These LP tokens represented collateralized exposure within broader strategies, but from Pendle’s perspective they were standard ERC‑20 balances that could be transferred by an approved router and then burned via PendleMarketV6::burn, with the resulting SY/PT routed to arbitrary receivers.

The adversary exploited this structural setup by composing:

  • Morpho flash loans of USDC from the USDC market at 0xbbbbbbbbbb9cc5e90e3b3af64bdaf62c37eeffcb.
  • DEX and adapter contracts (0x169a5eff..., 0x1b6bb412...) to align assets with the target SY contracts.
  • PendleRouterV4 proxy at 0x888888888889758f76e7103c6cbf23abbf58f946, which routes to Pendle facets that handle SY deposits, LP interactions, and swaps.
  • PendleMarketV6 instances for REUSDSY and NUSD SY markets, where LP transfers, burns, and PT/SY swaps occur.

All of these components are permissionless and callable by any unprivileged EOA or contract. The incident is therefore best understood as a deterministic liquidation/unwind MEV opportunity in which a sophisticated searcher uses flash liquidity to rapidly unwind LP-backed positions and capture residual value, rather than as an exploit of broken accounting or access control.

3. Vulnerability Analysis & Root Cause Summary

The vulnerability is an economic design issue: large, debt-backed Pendle LP positions were left accessible to public routers in such a way that any searcher with access to Morpho flash loans could unwind those positions, repay associated debt, and capture the remaining value as profit. There is no evidence of reentrancy, unchecked math, underflow, or misconfigured access control in Morpho or Pendle; both protocols behave according to their intended invariants.

At a high level, the adversary’s strategy is:

  1. Use Morpho Blue to obtain a large flash loan of USDC in a single transaction.
  2. Swap the USDC (and NUSD where needed) into the SY assets corresponding to the target Pendle markets via DEX adapters and PendleRouterV4.
  3. Use PendleRouterV4 to transfer victim-held LP tokens from the victim vaults into PendleMarketV6 and call PendleMarketV6::burn (and swapExactPtForSy in one market), thereby realizing the SY/PT value of the LP and routing it to adversary-controlled receivers.
  4. Swap the resulting SY/PT back into USDC, repay the Morpho flash loan plus fee, and keep the residual USDC as profit.

The root cause can be summarized as:

  • Root cause category: MEV (economic ACT opportunity), not a protocol bug.
  • Invariant context: Morpho enforces full repayment of flash loans (amount + fee) and health factors; Pendle enforces reserve accounting via totalPt/totalSy and balance checks in burn and swap functions.
  • Breakpoints: The economic breakpoint where victim value is reallocated occurs when victim LP is transferred into the Pendle markets and burned. At that point, the victim’s LP position is irrevocably retired, and the resulting SY/PT flows, routed by router/callback logic, are ultimately converted into USDC that remains with the adversary.

4. Detailed Root Cause Analysis

4.1 Invariants and Code-Level Mechanism

The key victim-side code is PendleMarketV6’s burn and swapExactPtForSy functions, as captured in the collected Pendle source:

function burn(
    address receiverSy,
    address receiverPt,
    uint256 netLpToBurn
) external nonReentrant returns (uint256 netSyOut, uint256 netPtOut) {
    MarketState memory market = readState(msg.sender);

    _burn(address(this), netLpToBurn);

    (netSyOut, netPtOut) = market.removeLiquidity(netLpToBurn);

    if (receiverSy != address(this)) IERC20(SY).safeTransfer(receiverSy, netSyOut);
    if (receiverPt != address(this)) IERC20(PT).safeTransfer(receiverPt, netPtOut);

    _writeState(market);

    emit Burn(receiverSy, receiverPt, netLpToBurn, netSyOut, netPtOut);
}

function swapExactPtForSy(
    address receiver,
    uint256 exactPtIn,
    bytes calldata data
) external nonReentrant notExpired returns (uint256 netSyOut, uint256 netSyFee) {
    MarketState memory market = readState(msg.sender);
    PYIndex index = YT.newIndex();

    uint256 netSyToReserve;
    (netSyOut, netSyFee, netSyToReserve) = market.swapExactPtForSy(index, exactPtIn, block.timestamp);

    if (receiver != address(this)) IERC20(SY).safeTransfer(receiver, netSyOut);
    IERC20(SY).safeTransfer(market.treasury, netSyToReserve);

    _writeState(market);

    if (data.length > 0) {
        IPMarketSwapCallback(msg.sender).swapCallback(exactPtIn.neg(), netSyOut.Int(), data);
    }

    if (_selfBalance(PT) < market.totalPt.Uint())
        revert Errors.MarketInsufficientPtReceived(_selfBalance(PT), market.totalPt.Uint());

    if (index.syToAsset(netSyFee - netSyToReserve) == 0) {
        revert Errors.MarketZeroNetLPFee();
    }

    emit Swap(msg.sender, receiver, exactPtIn.neg(), netSyOut.Int(), netSyFee, netSyToReserve);
}

From this code and the surrounding comments, we derive the following invariant:

  • For each market, LP tokens represent a share of SY/PT reserves. LP balances decrease only when LP held by the market contract is burned via burn, and the function ensures that SY/PT flows are consistent with AMM math and that post-operation balances satisfy totalSy/totalPt constraints.

On the lending side, Morpho’s flash-loan logic (from src/Morpho.sol in etherscan_getsourcecode.json) implements:

  • A transfer of loan tokens (USDC) to a callback that implements IMorphoFlashLoanCallback.onMorphoFlashLoan.
  • A requirement that the callback repay amount + fee; otherwise, the transaction reverts and no state change persists.

Together, these invariants imply:

  • Morpho cannot be under-repaid; the flash-loan amount plus fee must be returned.
  • Pendle cannot lose SY/PT reserves without accounting for them in market state; burn and swap functions enforce reserve consistency.

The incident does not violate these invariants. Instead, it uses them: by pulling LP from the victim vaults into the markets and burning it, the adversary causes Pendle to release the SY/PT underlying that LP, and by carefully routing those flows, the adversary ensures that Morpho’s loan is repaid and the excess value is captured.

4.2 ACT Opportunity Definition

The ACT opportunity is defined at Ethereum mainnet block 24,383,880 (just before the first adversary-crafted transaction is mined).

  • Pre-state σ_B: Ethereum mainnet at block 24,383,880, with the following relevant conditions:
    • Morpho USDC market at 0xbbbbbbbbbb9cc5e90e3b3af64bdaf62c37eeffcb is active and exposes flashLoan for USDC.
    • Pendle markets at 0xf5929a1c332ceab7918a4593a43db2b9ac20095f (REUSDSY) and 0x6d520a943a4da0784917a2e71defe95248a1daa1 (NUSD SY) are live and hold reserves.
    • Vault-like addresses 0xE5B2... and 0xcbfdba... hold large LP balances in those markets.
    • Public routers and adapters (PendleRouterV4, the SY proxies, and DEX adapters) are deployed and callable.

The seed index (artifacts/root_cause/seed/index.json) and per-tx metadata files confirm that:

  • The two relevant transactions are:
    • 0xee2b216b7d649513dc8ba102e130d3d86d189b393a0d5f387e479be3dbda799d (block 24,383,881, from 0x53695b...).
    • 0x047fcfa2cfb51879f19769dd25e2768be42985f9c2d8f483f2a0c18703834061 (block 24,383,893, from 0x1f3606...).
  • For both, we have tx metadata, balance diffs, and full opcode-level traces.

4.3 Adversary Transaction Sequence and Breakpoints

The adversary transaction sequence b consists of the two adversary-crafted transactions:

  1. Tx 1: 0xee2b216b... (REUSDSY market unwinding)
    • From EOA 0x53695bc30649f2f4ba1219cb1ede6629e277a696.
    • Deploys orchestrator contract 0x1198e6c15bd2df3d44076b7d1bfc9719504c2c80.
    • Orchestrator constructor calls Morpho::flashLoan(USDC, 182145484269260).
    • Morpho’s trace shows a call to 0xAF650b6dEa7Ffa0a54434D7527cba78C73889e22::onMorphoFlashLoan(...):
... 0xAF650b6dEa7Ffa0a54434D7527cba78C73889e22::onMorphoFlashLoan(182145484269260, ...)
  • Within the callback, PendleRouterV4 is invoked, and the trace shows:
emit Transfer(
  from: 0xE5B2FAbF3b2000eB6b03Bb4EbeA80fABC6159cF0,
  to:   PendleMarketV6: [0xf5929a1C332ceaB7918A4593a43Db2B9aC20095f],
  value: 12838251626546795
)
...
PendleMarketV6::burn(
  receiverSy = TransparentUpgradeableProxy: [0x9487Bd5A3b16Ecb5F3184453E3ee75B800141648],
  receiverPt = PendleMarketV6: [0xf5929a1C332ceaB7918A4593a43Db2B9aC20095f],
  netLpToBurn = 12838251626546795
)
...
emit Burn(receiverSy: ..., receiverPt: ..., netLpBurned: 12838251626546795, netSyOut: 19212761470848932441341, netPtOut: 5730727274)
  • These lines (from artifacts/root_cause/data_collector/iter_3/tx/1/0xee2b216b.../trace.cast.log) show the precise breakpoint:
    • A transfer of exactly 12,838,251,626,546,795 LP tokens from victim 0xE5B2... to the REUSDSY market.
    • A burn of the same LP inside PendleMarketV6, releasing SY and PT.
    • Subsequent swapExactPtForSy calls and SY transfers route the proceeds through PendleRouterV4 and back into USDC.
  • The USDC balance diff artifact confirms that EOA 0x53695b... ends this tx with 25,774,896,133 USDC:
{
  "token": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
  "holder": "0x53695bc30649f2f4ba1219cb1ede6629e277a696",
  "before": "0",
  "after": "25774896133",
  "delta": "25774896133"
}
  • Native balance deltas show that 0x53695b... pays 1,638,749,230,296,610 wei in gas.
  • The LP balance diff for the REUSDSY market confirms that the victim’s LP is fully consumed:
{
  "token": "0xf5929a1c332ceab7918a4593a43db2b9ac20095f",
  "holder": "0xe5b2fabf3b2000eb6b03bb4ebea80fabc6159cf0",
  "before": "12833286961727518",
  "after": "0",
  "delta": "-12833286961727518",
  "contract_name": "PendleMarketV6"
}
  1. Tx 2: 0x047fcfa2... (NUSD SY market unwinding)
    • From EOA 0x1f36068728b86ae4d65249f6f1c8c62cfaeb0675.
    • Deploys orchestrator contract 0x87ebccce2c704405298d4832c5f3751a7d56e2f3.
    • Orchestrator constructor calls Morpho::flashLoan(USDC, 182145484269260) and Morpho calls 0x45c101Be18670BAa1Fda8264fD3ae46525437871::onMorphoFlashLoan(...).
    • Within the callback, PendleRouterV4 routes into the NUSD SY market, and the trace shows:
PendleMarketV6::burn(
  receiverSy = TransparentUpgradeableProxy: [0x29ac34026C369D21fe3B2c7735eC986e2880B347],
  receiverPt = PendleMarketV6: [0x6D520a943a4Da0784917a2e71defe95248A1DaA1],
  netLpToBurn = 21419603957338675349188
)
...
PendleMarketV6::swapExactPtForSy(
  receiver = TransparentUpgradeableProxy: [0x29ac34026C369D21fe3B2c7735eC986e2880B347],
  exactPtIn = 7580065872303864207974,
  data = 0x
)
  • Earlier in the trace, a Transfer event moves LP from victim 0xcbfdba... into the market:
emit Transfer(
  from: 0xcbfdbae49883e378752ff3f64bf8d89562912da6,
  to:   PendleMarketV6: [0x6D520a943a4Da0784917a2e71defe95248A1DaA1],
  value: 21419603957338675349188
)
  • The LP balance diff for this market shows that the victim’s LP position is again fully consumed:
{
  "token": \"0x6d520a943a4da0784917a2e71defe95248a1daa1\",
  "holder": \"0xcbfdbae49883e378752ff3f64bf8d89562912da6\",
  "before": \"21414943336388843011877\",
  "after": \"0\",
  "delta": \"-21414943336388843011877\",
  "contract_name": \"PendleMarketV6\"
}
  • The USDC balance diff shows the adversary’s profit:
{
  "token": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
  "holder": "0x1f36068728b86ae4d65249f6f1c8c62cfaeb0675",
  "before": "0",
  "after": "45907952190",
  "delta": "45907952190"
}
  • Native balance deltas show gas paid of 1,568,620,953,241,572 wei.

Across both transactions, the concrete breakpoints where victim value is reallocated are:

  • Transfer of REUSDSY LP from 0xE5B2... to 0xf5929... and PendleMarketV6::burn with netLpToBurn = 12,838,251,626,546,795, followed by swaps to USDC.
  • Transfer of NUSD SY LP from 0xcbfdba... to 0x6d520a..., PendleMarketV6::burn with netLpToBurn = 21,419,603,957,338,675,349,188, and swapExactPtForSy with exactPtIn = 7,580,065,872,303,864,207,974, again followed by swaps to USDC.

In both cases, the protocols behave as designed: LP transferred into the market can be burned, and the resulting SY/PT can be swapped according to AMM math. The adversary’s innovation is purely in composing these primitives around the victim positions and a flash loan.

5. Adversary Flow Analysis

The adversary-related cluster consists of:

  • EOAs:
    • 0x53695bc30649f2f4ba1219cb1ede6629e277a696 (tx 0xee2b216b... sender and USDC profit recipient).
    • 0x1f36068728b86ae4d65249f6f1c8c62cfaeb0675 (tx 0x047fcfa2... sender and USDC profit recipient).
  • Orchestrator contracts:
    • 0x1198e6c15bd2df3d44076b7d1bfc9719504c2c80 (created in 0xee2b216b...).
    • 0x87ebccce2c704405298d4832c5f3751a7d56e2f3 (created in 0x047fcfa2...).
  • Flash-loan callbacks:
    • 0xAF650b6dEa7Ffa0a54434D7527cba78C73889e22.
    • 0x45c101Be18670BAa1Fda8264fD3ae46525437871.

Txlists for the EOAs (in artifacts/root_cause/data_collector/iter_1/address/1/*/txlist.json) show that around the incident blocks these addresses are short-lived and primarily used to deploy the orchestrators and run the flash-loan transactions, which supports treating them as part of a single adversary-related cluster for this incident.

The end-to-end flow for each transaction is:

  1. Deployment & Flash Loan

    • EOA sends a contract-creation tx that deploys the orchestrator and immediately (in the constructor) calls Morpho::flashLoan(USDC, 182145484269260) on the USDC market.
  2. Callback & Asset Routing

    • Morpho transfers USDC to the callback contract and emits a flash-loan event.
    • The callback routes USDC (and NUSD where necessary) through DEX adapters to align asset types with the required SY.
    • PendleRouterV4 is invoked with route data that deposits into SY contracts and interacts with PendleMarketV6.
  3. LP Transfer, Burn, and Swaps

    • PendleRouterV4 arranges for the victim LP to be transferred into the relevant market contract via ERC‑20 transfer (seen in the traces).
    • PendleMarketV6 burns the LP (burn) and, in the second tx, additionally swaps PT to SY (swapExactPtForSy).
    • The resulting SY/PT flows are routed via PendleRouterV4 and adapters back into USDC.
  4. Flash-Loan Repayment and Profit Realization

    • USDC flows back to Morpho to repay the flash-loan principal and fee, satisfying Morpho’s invariants.
    • Any residual USDC remains at the originating EOA (0x53695b... or 0x1f3606...), as confirmed by the USDC balance diffs.

The adversary’s net portfolio change in the USDC reference asset is:

  • +25,774,896,133 USDC to 0x53695b....
  • +45,907,952,190 USDC to 0x1f3606....
  • Minus gas costs equivalent to at most a small fraction of this amount (even under an extreme 10,000 USDC/ETH pricing assumption).

Because all components are public and unprivileged, this constitutes an ACT opportunity:

  • Any searcher with access to Morpho flash loans and standard routing infrastructure could construct equivalent orchestrators/callbacks.
  • The strategy relies only on canonical on-chain data (traces, logs, balances) and publicly available ABI/source artifacts.

6. Impact & Losses

The direct economic impact is a transfer of value from victim strategies using Pendle LP to the adversary cluster. Based on ERC‑20 balance diffs for USDC:

  • EOA 0x53695b... gains exactly 25,774,896,133 USDC in tx 0xee2b216b....
  • EOA 0x1f3606... gains exactly 45,907,952,190 USDC in tx 0x047fcfa2....
  • The combined gross USDC gain is 71,682,848,323 units.

Native balance diffs show:

  • 0x53695b... pays 1,638,749,230,296,610 wei in gas.
  • 0x1f3606... pays 1,568,620,953,241,572 wei in gas.

Even under an intentionally conservative assumption that ETH is worth more than 10,000 USDC per ETH at the incident time, the total gas cost in USDC terms is strictly less than 33,000,000,000,000 units, which is orders of magnitude smaller than the 71,682,848,323 USDC gross profit. Therefore, the adversary’s net portfolio change in USDC is strictly positive.

On the victim side:

  • LP balances for 0xE5B2... in the REUSDSY market and 0xcbfdba... in the NUSD SY market drop to zero in the corresponding balance_diff.json files, indicating complete unwinding of their LP positions.
  • SY and PT balances for associated addresses adjust accordingly, with flows matching the PendleMarketV6 burn and swapExactPtForSy outputs.

The protocols themselves remain solvent and within their expected invariants:

  • Morpho flash-loan events and USDC transfer logs show full repayment of amount + fee in both txs.
  • Pendle’s totalSy and totalPt accounting and reserve checks are satisfied; no reverts due to insufficient balances occur.

The incident is thus an economic loss to LP/vault users whose positions were unwound, not a solvency failure or security breach of the core protocols.

7. References

  • Seed index and metadata for incident txs

    • artifacts/root_cause/seed/index.json
    • artifacts/root_cause/seed/1/0xee2b216b7d649513dc8ba102e130d3d86d189b393a0d5f387e479be3dbda799d/metadata.json
    • artifacts/root_cause/seed/1/0x047fcfa2cfb51879f19769dd25e2768be42985f9c2d8f483f2a0c18703834061/metadata.json
  • Balance diffs and profit computation

    • artifacts/root_cause/seed/1/0xee2b216b.../balance_diff.json (USDC, LP, SY/PT deltas).
    • artifacts/root_cause/seed/1/0x047fcfa2.../balance_diff.json (USDC, NUSD, SY/PT deltas).
  • High-verbosity transaction traces

    • artifacts/root_cause/data_collector/iter_3/tx/1/0xee2b216b.../trace.cast.log (Morpho flash loan, PendleRouterV4 routes, PendleMarketV6 burn and swapExactPtForSy).
    • artifacts/root_cause/data_collector/iter_3/tx/1/0x047fcfa2.../trace.cast.log (analogous flow for NUSD SY market).
  • Verified contract sources and ABIs

    • Morpho Blue: artifacts/root_cause/data_collector/iter_2/contract/1/0xbbbbbbbbbb9cc5e90e3b3af64bdaf62c37eeffcb/source/etherscan_getsourcecode.json.
    • PendleRouterV4: artifacts/root_cause/data_collector/iter_2/contract/1/0x888888888889758f76e7103c6cbf23abbf58f946/source/etherscan_getsourcecode.json.
    • PendleMarketV6 (REUSDSY and NUSD SY markets) and associated SY contracts: artifacts/root_cause/seed/1/0xf5929a1c332ceab7918a4593a43db2b9ac20095f/src/pendle/contracts/core/Market/PendleMarketV6.sol and related seed source directories for SY tokens.
    • USDC and NUSD token sources: directories under artifacts/root_cause/seed/1/0x43506849d7c04f9138d1a2050bbf3a0c054402dd (FiatTokenV2_2) and artifacts/root_cause/seed/1/0xe556aba6fe6036275ec1f87eda296be72c811bce.
  • Address activity and clustering evidence

    • Txlists for 0x53695b..., 0x1f3606..., and 0x8270400d528c34e1596ef367eedec99080a1b592: artifacts/root_cause/data_collector/iter_1/address/1/*/txlist.json.

These artifacts jointly support the classification of this incident as an ACT-style MEV liquidation/unwind opportunity on Ethereum, with fully deterministic, on-chain-reconstructible behavior.