Morpho-Pendle flash-loan liquidation MEV captures undercollateralized spread
Exploit Transactions
Victim Addresses
0xE5B2FAbF3b2000eB6b03Bb4EbeA80fABC6159cF0Ethereum0xcbfdbae49883e378752ff3f64bf8d89562912da6EthereumLoss Breakdown
Similar Incidents
DOGGO/WETH cross-pool arbitrage MEV extracts WETH spread
35%SASHA cross-DEX MEV arbitrage extracts ETH pricing spread
35%Multi-venue stablecoin/WETH MEV arbitrage on Ethereum mainnet
34%SorbettoFragola Aave/Uniswap route arbitrage extracts USDC via fee collection
33%HANA tax-wallet MEV arbitrage on Uniswap V2
32%MachineShare CurveStableSwapNG mispricing arbitrage extracts ETH-side liquidity
31%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 tokenPendleREUSDSYat0x9487bd5a3b16ecb5f3184453e3ee75b800141648. - NUSD SY market at
0x6d520a943a4da0784917a2e71defe95248a1daa1, with SY tokenPendleERC20WithAdapterAndSupplyCapSYat0x29ac34026c369d21fe3b2c7735ec986e2880b347.
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:
- Use Morpho Blue to obtain a large flash loan of USDC in a single transaction.
- Swap the USDC (and NUSD where needed) into the SY assets corresponding to the target Pendle markets via DEX adapters and PendleRouterV4.
- Use PendleRouterV4 to transfer victim-held LP tokens from the victim vaults into PendleMarketV6 and call
PendleMarketV6::burn(andswapExactPtForSyin one market), thereby realizing the SY/PT value of the LP and routing it to adversary-controlled receivers. - 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 viatotalPt/totalSyand balance checks inburnand 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 satisfytotalSy/totalPtconstraints.
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
marketstate;burnand 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
0xbbbbbbbbbb9cc5e90e3b3af64bdaf62c37eeffcbis active and exposesflashLoanfor USDC. - Pendle markets at
0xf5929a1c332ceab7918a4593a43db2b9ac20095f(REUSDSY) and0x6d520a943a4da0784917a2e71defe95248a1daa1(NUSD SY) are live and hold reserves. - Vault-like addresses
0xE5B2...and0xcbfdba...hold large LP balances in those markets. - Public routers and adapters (PendleRouterV4, the SY proxies, and DEX adapters) are deployed and callable.
- Morpho USDC market at
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, from0x53695b...).0x047fcfa2cfb51879f19769dd25e2768be42985f9c2d8f483f2a0c18703834061(block 24,383,893, from0x1f3606...).
- 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:
- 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(...):
- From EOA
... 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,795LP tokens from victim0xE5B2...to the REUSDSY market. - A
burnof the same LP inside PendleMarketV6, releasing SY and PT. - Subsequent
swapExactPtForSycalls and SY transfers route the proceeds through PendleRouterV4 and back into USDC.
- A transfer of exactly
- 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...pays1,638,749,230,296,610wei 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"
}
- Tx 2:
0x047fcfa2...(NUSD SY market unwinding)- From EOA
0x1f36068728b86ae4d65249f6f1c8c62cfaeb0675. - Deploys orchestrator contract
0x87ebccce2c704405298d4832c5f3751a7d56e2f3. - Orchestrator constructor calls
Morpho::flashLoan(USDC, 182145484269260)and Morpho calls0x45c101Be18670BAa1Fda8264fD3ae46525437871::onMorphoFlashLoan(...). - Within the callback, PendleRouterV4 routes into the NUSD SY market, and the trace shows:
- From EOA
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,572wei.
Across both transactions, the concrete breakpoints where victim value is reallocated are:
- Transfer of REUSDSY LP from
0xE5B2...to0xf5929...andPendleMarketV6::burnwithnetLpToBurn = 12,838,251,626,546,795, followed by swaps to USDC. - Transfer of NUSD SY LP from
0xcbfdba...to0x6d520a...,PendleMarketV6::burnwithnetLpToBurn = 21,419,603,957,338,675,349,188, andswapExactPtForSywithexactPtIn = 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(tx0xee2b216b...sender and USDC profit recipient).0x1f36068728b86ae4d65249f6f1c8c62cfaeb0675(tx0x047fcfa2...sender and USDC profit recipient).
- Orchestrator contracts:
0x1198e6c15bd2df3d44076b7d1bfc9719504c2c80(created in0xee2b216b...).0x87ebccce2c704405298d4832c5f3751a7d56e2f3(created in0x047fcfa2...).
- 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:
-
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.
- EOA sends a contract-creation tx that deploys the orchestrator and immediately (in the constructor) calls
-
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.
-
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.
- PendleRouterV4 arranges for the victim LP to be transferred into the relevant market contract via ERC‑20
-
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...or0x1f3606...), 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 tx0xee2b216b.... - EOA
0x1f3606...gains exactly 45,907,952,190 USDC in tx0x047fcfa2.... - The combined gross USDC gain is 71,682,848,323 units.
Native balance diffs show:
0x53695b...pays1,638,749,230,296,610wei in gas.0x1f3606...pays1,568,620,953,241,572wei 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 and0xcbfdba...in the NUSD SY market drop to zero in the correspondingbalance_diff.jsonfiles, indicating complete unwinding of their LP positions. - SY and PT balances for associated addresses adjust accordingly, with flows matching the PendleMarketV6
burnandswapExactPtForSyoutputs.
The protocols themselves remain solvent and within their expected invariants:
- Morpho flash-loan events and USDC transfer logs show full repayment of
amount + feein both txs. - Pendle’s
totalSyandtotalPtaccounting 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.jsonartifacts/root_cause/seed/1/0xee2b216b7d649513dc8ba102e130d3d86d189b393a0d5f387e479be3dbda799d/metadata.jsonartifacts/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, PendleMarketV6burnandswapExactPtForSy).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.soland related seed source directories for SY tokens. - USDC and NUSD token sources: directories under
artifacts/root_cause/seed/1/0x43506849d7c04f9138d1a2050bbf3a0c054402dd(FiatTokenV2_2) andartifacts/root_cause/seed/1/0xe556aba6fe6036275ec1f87eda296be72c811bce.
- Morpho Blue:
-
Address activity and clustering evidence
- Txlists for
0x53695b...,0x1f3606..., and0x8270400d528c34e1596ef367eedec99080a1b592:artifacts/root_cause/data_collector/iter_1/address/1/*/txlist.json.
- Txlists for
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.