Article from: @Ehsan1579
Compiled | Odaily Planet Daily (@OdailyChina); Translator | Ethan (@ethanzhang_web 3)
Judging by the headline alone, one might mistakenly think this was an exploit attack.
The core of the event is: Someone exchanged USDT worth 50.4 million dollars and ended up with AAVE worth only 35.9 thousand dollars.
When I first heard about this, I was truly shocked. Therefore, I thoroughly dissected the entire event: transaction tracing, solver path, contract calls, historical reserves, settlement data, adapter flow, Aave interface code, CoW flash loan SDK, and the routing code that determines if a quote is "reasonable".
This was not a hack. The Aave core protocol did not malfunction. The CoW settlement did not malfunction. Uniswap did not malfunction. SushiSwap did not malfunction. The transaction was valid, the signature was valid, all contracts executed strictly according to their code. Yet, almost all economic value was destroyed simply because it was allowed to take an utterly absurd route.
The public chain did not fail; the routing did.
In my view, brushing this off as a simple "user error" is not an objective or rigorous stance. Admittedly, the user signed the order, but the entire software system actually allowed an operation involving nearly 50 million dollars in collateral rotation to complete the quoting, signing, routing, and final execution, with the entire process pointing to a low-liquidity pool holding only about 331 AAVE. This should have been completely impossible, or at the very least, it should have been firmly intercepted and rejected before the settlement process even began.
Tracing the Core Information of the Transaction
The hash of this anomalous transaction is: 0x9fa9feab3c1989a33424728c23e6de07a40a26a98ff7ff5139f3492ce430801f, confirmed on the Ethereum mainnet at block height 24643151 on March 12, 2026, with transaction index 1, consuming 3,780,570 units of Gas, and the transaction executed successfully. The order belonged to wallet address starting with 0x98b9, and the actual solver (transaction sender) address was starting with 0x3980, marked as 'tsolver' in CoW competition data.
First, understand that this was not a simple USDT to AAVE swap at the wallet level. The sold token was aEthUSDT, the interest-bearing USDT deposit certificate on the Aave platform. The bought token was aEthAAVE, the interest-bearing AAVE deposit certificate on the Aave platform. So, this was actually a collateral rotation on Aave conducted through the CoW protocol's settlement system and its flash loan adapter flow.
Before the transaction, the wallet held approximately 50,432,693.075254 aEthUSDT and 0 aEthAAVE. After the transaction, it only had 4.980399 aEthUSDT left and received 327.241335505966487788 aEthAAVE. Effectively, the wallet sold almost its entire position.
Metadata more clearly shows that the route was "toxic" before execution. The order came from the aave-v3-interface-collateral-swap flow. CoW's API displays it as a signed sell order, and the app metadata marks it as a market-style collateral swap using 121 basis points of intelligent slippage. The signed sell amount was 50,432,688.41618 aEthUSDT. The signed minimum buy amount was 324.949260918413591035 aEthAAVE. The actual settlement paid 327.241335505966487788 aEthAAVE.
This is an extremely important detail. This order was never expecting to receive thousands of AAVE, only to be destroyed midway. It was built from the start around an outcome of just over three hundred AAVE.
The Complete Chain of the Routing Collapse
Once you follow the transaction trace, the whole process becomes brutally straightforward.
The top-level fund flow relies on the CoW protocol's GPv2Settlement contract starting with 0x9008. First, the HooksTrampoline contract starting with 0x60bf performs the aEthUSDT authorization, allowing the CoW vault relayer to extract user assets without a separate transaction authorization; subsequently, the GPv2VaultRelayer contract starting with 0xc92e extracts 50,432,688.41618 aEthUSDT from the user's wallet into the settlement process. Up to this point, all operations followed normal logic.
The settlement contract then grants aEthUSDT operation permissions to an unverified auxiliary contract starting with 0xd524 and initiates a call via function selector 0x494b3137; this auxiliary contract then transfers execution permissions to an unverified executor contract starting with 0x699c. At this point, the full picture of the anomalous transaction route is completely exposed.
The first effective call points to the Aave pool contract starting with 0x87870, using the withdraw function (selector 0x69328dec) to burn aEthUSDT and redeem the underlying native USDT; the route then jumps to the deep USDT/WETH trading pool on Uniswap V3 starting with 0x4e68, exchanging all 50,432,688.41618 USDT for 17,957.810805702142342238 WETH.
This stage of the transaction was completely normal: the exchange rate was approximately 2808.4 USDT for 1 WETH, consistent with the market rate at the time, with no liquidity issues or calculation deviations. The first hop of the transaction chain showed no abnormalities.
The problem occurred in the second hop. Once you see the liquidity reserves, the rest of the story becomes inevitable.
After obtaining 17,957.810805702142342238 WETH, the executor transfers all funds into the SushiSwap V2 AAVE/WETH trading pool at address 0xd75ea151a61d06868e31f8988d28dfe5e9df57b4.
I checked the historical liquidity reserve data of this trading pool just before the anomalous transaction occurred (block height 24643150). The pool held only:
331.631982538108027323 AAVE, 17.653276196397688066 WETH
This is not a data entry error but a hard fact.
This trading route injected nearly 17,958 WETH entirely into a micro trading pool that only reserved 17.65 WETH, with a corresponding total AAVE inventory of only 331.63. The input volume of WETH was about 1017 times the WETH reserve in the pool.
This was not a routine issue of "high slippage" or "slightly thin liquidity" but an extremely absurd market order execution path, equivalent to forcing a constant product AMM pool of极小 volume to undertake a huge transaction thousands of times its own size.
The AMM trading pool executed the operation according to its algorithm, nearly exhausting the entire AAVE reserve in the pool.
The SushiSwap pair triggered the core Swap event: the executor transferred in 17,957.810805702142342238 WETH and received only 331.305315608938235428 AAVE in return. After the transaction, the remaining liquidity in the pool was approximately:
0.326666929169791895 AAVE, 17,975.464081898540030304 WETH
Simply put, about 99.9% of the AAVE inventory in the pool was drained in one go.
Based on the pre-trade reserves, the pool's implied AAVE price was approximately $149.50. The user's actual execution price was about 154,114.66 USDT per AAVE. This is over 1000 times worse than the spot price before the trade.
Next, these AAVE were supplied back to the Aave pool using selector 0x617ba037, i.e., supply(address,uint256,address,uint16). The result was newly minted aEthAAVE sent back to the settlement contract. The settlement contract finally transferred 327.241335505966487788 aEthAAVE to the user. Approximately 4.06398010297174764 aEthAAVE remained in the settlement contract as surplus relative to what the user paid for.
So, the settlement did not suddenly twist a good execution result into a bad one. It merely finalized the result that the route had already produced.
This is a key point worth stating explicitly: The catastrophic result was "pre-set" within the route before it was even executed.
Within the embedded auxiliary contract call data of the route, the target amount on the buy side was approximately 331.272185078031026739, the user's signed agreed minimum buy amount was 324.949260918413591035, and the actual settlement amount was 327.241335505966487788. All core values were locked at the level of just over three hundred AAVE before settlement.
This route was born bad.
Where is the Vulnerability?
The answer is: Every layer of the system's verification mechanism was checking the wrong dimensions.
All layers only verified whether the transaction was executable, the signature was valid, and the amount was non-zero. Yet, almost no core layer verified whether the transaction route was economically reasonable. This is the root cause of the mechanism failure.
Code Defect in the Aave Interface Adapter Quote Path
The first obvious code anomaly appears in the CoW adapter quote flow of the Aave interface: the function originally used to attach adapter-specific application data when requesting a quote was directly and forcibly disabled.
Source: rates.helpers.ts:93 and adapters.helpers.ts:194
This means that when the Aave interface requests a quote from CoW, it does not attach the flash loan and hook metadata that would actually be attached when the order is published. In other words, what is being quoted is not exactly what will be executed. The code comment even says the purpose of this helper function is to make adapter quotes more precise, yet this function was hard-disabled.
CoW Quote Competition Logic's Reasonableness Judgment is Too Weak (Core Vulnerability)
The second and most serious problem lies in the quote competition logic of the CoW protocol: in its public service code, as long as the quoted Gas fee is positive and the output amount is non-zero, it is judged as a "reasonable quote".
Source: quote.rs:31
For a routing system handling eight-figure orders, this is an astonishingly weak definition of "reasonableness".
The system did not integrate oracles for price sanity checks, had no interception mechanism for "quotes deviating more than 500 times from the spot price", no risk assessment for "routes that would completely drain a liquidity pool", no early warning for "severe mismatch between the last hop's liquidity and the order size"; it only required the solver return an executable, non-zero routing solution for it to be accepted by the system. This is the core vulnerability of this incident.
Defect in Uniswap V2-style Liquidity Modeling Logic
The third problem lies in the modeling method of Uniswap V2-style liquidity pools: the code only uses the standard constant product algorithm, only rejecting mathematically impossible situations like zero reserves, underflow, overflow, etc., without performing economic feasibility checks.
Source: pool_fetching.rs:118 and pool_fetching.rs:153
This code does not judge whether the liquidity pool's size is sufficient to handle the corresponding route transaction; it only judges whether the swap operation is mathematically valid. Therefore, even a micro pool reserving only 331 AAVE would be judged as a valid venue for a buy order of 17,957 WETH, simply because the constant product algorithm could calculate a non-zero result, completely ignoring that this result would cause devastating asset loss.
Secondary Failure of Flash Loan SDK and Order Verification Mechanism
Subsequently, the flash loan SDK directly solidified this invalid quote into the execution payload of the order and hooks, without any secondary risk blocking.
Then:
Source: index.js:484 and index.js:591
This is why I keep saying this route was "born bad". The adapter layer did not "discover" a new bad amount during execution. It serialized the already quoted bad amount into the hook data and the determined instance address. Once the bad quote existed, the rest of the mechanism faithfully passed it down.
Even CoW's order validation logic did not truly protect the user here because it only checks if the order exceeds the market price at the time of quoting, not whether the quote itself is absurd relative to actual liquidity.
Source: order_validation.rs:694
This is a consistency check. If the quote itself is already nonsense, the order can still pass.
UI Front-end Warning Mechanism is Merely Cosmetic
The Aave interface does have a high price impact warning, but it is not a hard circuit breaker. When the value loss exceeds 20%, it becomes a confirmation checkbox.
Once the user checks the box, the obstacle is cleared:
Source: helpers.ts:24 and HighPriceImpactWarning.tsx:35
Therefore, even though this transaction would nearly wipe out the entire asset value, the system only judged it as an operation requiring user confirmation, rather than a high-risk transaction that the system must firmly reject. The warning mechanism completely lost its risk interception function.
Based on all the above mechanism failures, I absolutely do not agree with the perfunctory conclusion that "this is just the user being stupid". The user did sign, but the entire software system had countless opportunities to intercept this disaster, yet each layer only performed basic checks,判定 "non-zero, executable, signed" and then directly let it pass,最终酿成恶果 (finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿成恶果 - finally酿极恶果 - eventually leading to the disastrous outcome).
The Route Was Not Tampered With
This step is crucial, directly ruling out many erroneous guesses: the Aave official interface flow corresponding to aave-v3-interface-collateral-swap, in the file useSwapOrderAmounts.ts at line 139, combines the quote, network fees, partner fees, and flash loan fees to calculate the slippage-adjusted buy amount; line 331 converts it into a buyAmountBigInt value; subsequently, in the file CollateralSwapActionsViaCoWAdapters.tsx at line 191, this amount is accurately signed.
The subsequent adapter contract will, in AaveV3BaseAdapter.sol at line 141, verify that the signed order fields完全匹配 the stored values; the CoW settlement contract will, in GPv2Settlement.sol at line 337, strictly enforce the limits agreed upon in the signature. Therefore, the on-chain execution result did not exceed the scope allowed by the signed order; the user actually received assets even higher than the signed agreed minimum limit.
This is enough to prove: The disaster occurred before the settlement环节, not during the settlement process. The fatal flaw of the route had already predetermined the outcome.
Where Did the Lost Value Go?
The very next transaction in the same block (hash starting with 0x45388b0f) performed a backrun arbitrage on the destroyed SushiSwap AAVE/WETH pool. After the anomalous transaction stuffed the pool with a huge amount of WETH and drained绝大部分 AAVE, the arbitrageur immediately sold AAVE back into the pool, harvesting the excess value brought by the liquidity imbalance.
This backrun arbitrage extracted approximately 17,929.770158685933 WETH, then paid approximately 13,087.73 ETH to the builder of this block and approximately 4,824.31 ETH to the arbitrage execution address.
All the economic value lost by the user was almost instantly transformed into MEV arbitrage profits and block builder rewards within the same block.
Additionally, checking the block-level timeline confirms: No one maliciously manipulated the SushiSwap trading pool to set a trap for the user before the transaction; this AAVE/WETH trading pair was touched for the first time by this anomalous transaction (transaction index 1); the very next transaction (transaction index 2) performed the first backrun on the price distortion caused by this transaction; transaction index 3 also touched this trading pair during the market correction process. The timeline clearly confirms: This anomalous transaction created an extremely distorted price, and subsequent transactions directly harvested the收益 from this distortion.
So, Who is to Blame?
If you ask if the Aave V3 core protocol broke, the answer is no. The Aave pool executed operations exactly as instructed, normally completing the USDT redemption and AAVE deposit processes.
If you ask if CoW's GPv2Settlement contract broke, the answer is no. The settlement enforced a valid signed order and paid an amount higher than the signed minimum.
If you ask if the Uniswap V3 or SushiSwap trading pair contracts broke, the answer is also no. Both types of trading pools priced the交易 according to their own algorithmic rules.
The real systemic failure occurred at the higher levels of routing and risk control:
The primary responsible party is the CoW protocol's routing, quoting, and solver modules: The entire system's criteria for judging a "reasonable route" were too weak, allowing a tens-of-millions-of-dollars order to最终 flow into a micro, low-liquidity pool, accepting it as long as the route was executable and non-zero, completely ignoring the extreme economic irrationality.
The secondary responsible party is the Aave front-end interface: When requesting adapter quotes, it did not attach the associated application data for the hooks, directly passing the wrong result into the signing process, and relied solely on warning prompts without a hard rejection mechanism. For such extreme large-value transactions, these risk control measures were completely insufficient to prevent risk.
This was an extreme failure in trade route quality and risk control guardrails, directly turning a legitimate and compliant collateral rotation operation into a devastating asset loss event.















