Calculated from recorded token losses using historical USD prices at the incident time.
0xE5B2FAbF3b2000eB6b03Bb4EbeA80fABC6159cF0Ethereum0xcbfdbae49883e378752ff3f64bf8d89562912da6EthereumOn 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.
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:
0xf5929a1c332ceab7918a4593a43db2b9ac20095f, with SY token PendleREUSDSY at 0x9487bd5a3b16ecb5f3184453e3ee75b800141648.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:
0xbbbbbbbbbb9cc5e90e3b3af64bdaf62c37eeffcb.0x169a5eff..., 0x1b6bb412...) to align assets with the target SY contracts.0x888888888889758f76e7103c6cbf23abbf58f946, which routes to Pendle facets that handle SY deposits, LP interactions, and swaps.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.
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:
PendleMarketV6::burn (and swapExactPtForSy in one market), thereby realizing the SY/PT value of the LP and routing it to adversary-controlled receivers.The root cause can be summarized as:
amount + fee) and health factors; Pendle enforces reserve accounting via totalPt/totalSy and balance checks in burn and swap functions.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:
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:
IMorphoFlashLoanCallback.onMorphoFlashLoan.amount + fee; otherwise, the transaction reverts and no state change persists.Together, these invariants imply:
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.
The ACT opportunity is defined at Ethereum mainnet block 24,383,880 (just before the first adversary-crafted transaction is mined).
0xbbbbbbbbbb9cc5e90e3b3af64bdaf62c37eeffcb is active and exposes flashLoan for USDC.0xf5929a1c332ceab7918a4593a43db2b9ac20095f (REUSDSY) and 0x6d520a943a4da0784917a2e71defe95248a1daa1 (NUSD SY) are live and hold reserves.0xE5B2... and 0xcbfdba... hold large LP balances in those markets.The seed index (artifacts/root_cause/seed/index.json) and per-tx metadata files confirm that:
0xee2b216b7d649513dc8ba102e130d3d86d189b393a0d5f387e479be3dbda799d (block 24,383,881, from 0x53695b...).0x047fcfa2cfb51879f19769dd25e2768be42985f9c2d8f483f2a0c18703834061 (block 24,383,893, from 0x1f3606...).The adversary transaction sequence b consists of the two adversary-crafted transactions:
0xee2b216b... (REUSDSY market unwinding)
0x53695bc30649f2f4ba1219cb1ede6629e277a696.0x1198e6c15bd2df3d44076b7d1bfc9719504c2c80.Morpho::flashLoan(USDC, 182145484269260).0xAF650b6dEa7Ffa0a54434D7527cba78C73889e22::onMorphoFlashLoan(...):... 0xAF650b6dEa7Ffa0a54434D7527cba78C73889e22::onMorphoFlashLoan(182145484269260, ...)
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)
artifacts/root_cause/data_collector/iter_3/tx/1/0xee2b216b.../trace.cast.log) show the precise breakpoint:
12,838,251,626,546,795 LP tokens from victim 0xE5B2... to the REUSDSY market.burn of the same LP inside PendleMarketV6, releasing SY and PT.swapExactPtForSy calls and SY transfers route the proceeds through PendleRouterV4 and back into USDC.0x53695b... ends this tx with 25,774,896,133 USDC:{
"token": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
"holder": "0x53695bc30649f2f4ba1219cb1ede6629e277a696",
"before": "0",
"after": "25774896133",
"delta": "25774896133"
}
0x53695b... pays 1,638,749,230,296,610 wei in gas.{
"token": "0xf5929a1c332ceab7918a4593a43db2b9ac20095f",
"holder": "0xe5b2fabf3b2000eb6b03bb4ebea80fabc6159cf0",
"before": "12833286961727518",
"after": "0",
"delta": "-12833286961727518",
"contract_name": "PendleMarketV6"
}
0x047fcfa2... (NUSD SY market unwinding)
0x1f36068728b86ae4d65249f6f1c8c62cfaeb0675.0x87ebccce2c704405298d4832c5f3751a7d56e2f3.Morpho::flashLoan(USDC, 182145484269260) and Morpho calls 0x45c101Be18670BAa1Fda8264fD3ae46525437871::onMorphoFlashLoan(...).PendleMarketV6::burn(
receiverSy = TransparentUpgradeableProxy: [0x29ac34026C369D21fe3B2c7735eC986e2880B347],
receiverPt = PendleMarketV6: [0x6D520a943a4Da0784917a2e71defe95248A1DaA1],
netLpToBurn = 21419603957338675349188
)
...
PendleMarketV6::swapExactPtForSy(
receiver = TransparentUpgradeableProxy: [0x29ac34026C369D21fe3B2c7735eC986e2880B347],
exactPtIn = 7580065872303864207974,
data = 0x
)
0xcbfdba... into the market:emit Transfer(
from: 0xcbfdbae49883e378752ff3f64bf8d89562912da6,
to: PendleMarketV6: [0x6D520a943a4Da0784917a2e71defe95248A1DaA1],
value: 21419603957338675349188
)
{
"token": \"0x6d520a943a4da0784917a2e71defe95248a1daa1\",
"holder": \"0xcbfdbae49883e378752ff3f64bf8d89562912da6\",
"before": \"21414943336388843011877\",
"after": \"0\",
"delta": \"-21414943336388843011877\",
"contract_name": \"PendleMarketV6\"
}
{
"token": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
"holder": "0x1f36068728b86ae4d65249f6f1c8c62cfaeb0675",
"before": "0",
"after": "45907952190",
"delta": "45907952190"
}
1,568,620,953,241,572 wei.Across both transactions, the concrete breakpoints where victim value is reallocated are:
0xE5B2... to 0xf5929... and PendleMarketV6::burn with netLpToBurn = 12,838,251,626,546,795, followed by swaps to USDC.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.
The adversary-related cluster consists of:
0x53695bc30649f2f4ba1219cb1ede6629e277a696 (tx 0xee2b216b... sender and USDC profit recipient).0x1f36068728b86ae4d65249f6f1c8c62cfaeb0675 (tx 0x047fcfa2... sender and USDC profit recipient).0x1198e6c15bd2df3d44076b7d1bfc9719504c2c80 (created in 0xee2b216b...).0x87ebccce2c704405298d4832c5f3751a7d56e2f3 (created in 0x047fcfa2...).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
Morpho::flashLoan(USDC, 182145484269260) on the USDC market.Callback & Asset Routing
LP Transfer, Burn, and Swaps
transfer (seen in the traces).burn) and, in the second tx, additionally swaps PT to SY (swapExactPtForSy).Flash-Loan Repayment and Profit Realization
0x53695b... or 0x1f3606...), as confirmed by the USDC balance diffs.The adversary’s net portfolio change in the USDC reference asset is:
0x53695b....0x1f3606....Because all components are public and unprivileged, this constitutes an ACT opportunity:
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:
0x53695b... gains exactly 25,774,896,133 USDC in tx 0xee2b216b....0x1f3606... gains exactly 45,907,952,190 USDC in tx 0x047fcfa2....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:
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.burn and swapExactPtForSy outputs.The protocols themselves remain solvent and within their expected invariants:
amount + fee in both txs.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.
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.jsonBalance 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
artifacts/root_cause/data_collector/iter_2/contract/1/0xbbbbbbbbbb9cc5e90e3b3af64bdaf62c37eeffcb/source/etherscan_getsourcecode.json.artifacts/root_cause/data_collector/iter_2/contract/1/0x888888888889758f76e7103c6cbf23abbf58f946/source/etherscan_getsourcecode.json.artifacts/root_cause/seed/1/0xf5929a1c332ceab7918a4593a43db2b9ac20095f/src/pendle/contracts/core/Market/PendleMarketV6.sol and related seed source directories for SY tokens.artifacts/root_cause/seed/1/0x43506849d7c04f9138d1a2050bbf3a0c054402dd (FiatTokenV2_2) and artifacts/root_cause/seed/1/0xe556aba6fe6036275ec1f87eda296be72c811bce.Address activity and clustering evidence
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.