Blockchain

The Trade Ended, but the Approval Remained: Inside the JaredfromSubway Harvest

This reverse honeypot paid small, realizable profits so JaredfromSubway would grant unfamiliar wrappers durable authority over WETH, USDC, and USDT, then used a one-block switch to skip the expected transferFrom() ; one harvest transaction identified by BlockSec consequently moved about $7.5 million from a single operating contract and exposed the approval lifecycle automated trading systems need.

A hand-drawn market observer follows planted pools into a real-token permission ledger, one sealed harvest transaction, three asset streams, and a branching fund trail.
In this article

Research basisThe public record supports a direct conclusion. An attacker built a market that could execute swaps, emit familiar events, and pay real profit. The bot left real-token allowances usable after those trades, and the attacker later exercised them in one coordinated harvest. “Reverse honeypot” here means a venue that induces an automated trader to hand an unfamiliar contract durable withdrawal authority.

SourceChainalysis / BlockSec / Ethereum / SOSEC source review

The evidence has four layers: Chainalysis and BlockSec incident observations, independently inspectable chain fields, allowance semantics from standards and commit-pinned source, and defensive controls derived from those records. Chainalysis's 66 counterfeit-token contracts and campaign minimum of at least $7.5 million, BlockSec's approximately 44 pools and one-transaction reconstruction of about $7.5 million, and the operator's approximately $15 million total-loss claim describe separate objects and remain separate throughout this report.

1 A Planted Market Acquired Real Authority

Five participants and one state variable explain the incident. The attacker controlled a factory and a block-sensitive switch. Counterfeit wrappers requested approval over real tokens. Counterfeit pools supplied routes and events. A JaredfromSubway operating contract acted as owner and signed the trades. The WETH, USDC, and USDT contracts stored allowance from that owner to each wrapper spender. Pools and wrappers made the route worth executing; the real-token ledgers preserved the authority until harvest.

Chainalysis's June 26 account places the campaign on June 20–21, 2026. An unknown attacker deployed 66 contracts that imitated assets including WETH, USDC, and USDT and paired them with fraudulent pools. The bot granted spending authority across multiple trades. Some permissions survived the operation and remained unrevoked. Chainalysis reports a campaign loss floor of at least $7.5 million and traces stablecoin conversion to ETH, later wallet dispersion, and paths into Tornado Cash.

BlockSec's technical reconstruction identifies operating contract 0x1f2F10D1C40777AE1Da742455c65828FF36Df387, fake-token factory 0x81F248Ff583d3f8592Ea0354A7b8DBe66de40091, approximately 44 Uniswap-v2-style pools, and a getStatus() branch keyed to the current block. The wrappers reused real-token names, added an f prefix to their displayed symbols, and could return small amounts of real tokens from attacker-controlled reserves. The route therefore presented executable swaps, familiar events, and realizable profit at the same time.

1.1 Code and response map for the verifiable control points

A mechanical market observer faces counterfeit token vessels, pool basins, an attacker-controlled factory, and one unusually attractive route ending at real-token authority.
Figure 1 | Attacker, wrapper, pool, bot owner, and real-token ledger play separate roles; owner-to-spender allowance is the durable state that joins all five.

1.2 One evidence ledger defines the action each fact supports

Fact objectSource and evidence levelAction it directly supports
66 fake-token contracts and a campaign minimum of at least $7.5 millionChainalysis campaign observation and fund tracingSeed the asset and contract inventory; establish completeness transaction by transaction
Approximately 44 pools, a per-block branch, and the accumulation-mode anchor at block 25,360,519BlockSec on-chain technical reconstructionExpand the hunt by factory, code family, activation call, and residual allowance
Harvest transaction at block 25,360,696 and three token-unit net amountsEthereum transaction, receipt, logs, and BlockSec totalsReconcile balance deltas, call paths, asset totals, and direct recipients
Operator's approximately $15 million total-loss claimJaredfromSubway claim relayed by BlockSecBroaden initial incident scope; independently build the full wallet and transaction set
Durable ERC-20 allowance semanticsEIP-20 and a commit-pinned OpenZeppelin reference implementationDesign state invariants; use historical on-chain code and state for each actual token

The ledger keeps campaign observation, chain fields, reference standards, and an operator claim in their proper roles. Later qualifications appear only where evidence strength changes an operational decision. The investigation can now follow authority as it is created, preserved, exercised, and closed.

2 Early Trades Taught the Bot to Trust the Route

BlockSec uses transaction 0x542d8d7ad206672bf484bbad9635ec5f92a429d527a561ae898c2da09742362b at block 25,354,425 as an early trust sample. The bot approved the wrapper on the real token and called wrapTo(). The wrapper then executed transferFrom(bot, wrapper, amount), reducing the finite allowance. The route crossed attacker-created pools, and unwrap() returned real tokens. Execution, events, permission consumption, and booked profit all agreed in that trade.

Transaction 0x085ec14424f9b2f290ea7bd2f60fc74f3dc3d8996d70ad7bf384bcae52c37e51 shows the next stage. The external status mechanism already existed, yet getStatus() returned its inactive value in that block and the wrapper pulled normally. Counterfeit pools emitted genuine Sync and Swap logs, while attacker reserves funded a small realizable return. The automation saw consecutive success. Deployment, funding, and code control remained concentrated with the venue creator.

The strategy needs five distinct signals under one route ID. Pool logs show what the emitter wrote. Balance growth shows that the owner received an asset. The call trace shows whether the wrapper pulled the real token. A block-pinned allowance read establishes the permission result. Factory, runtime code, and control state establish counterparty identity. Each signal answers one question, and the business receipt combines all five.

Three hand-drawn panels show an approval being pulled and consumed, pool basins emitting event ripples, and a small real-token return supplied by a hidden attacker reservoir.
Figure 2 | Early trades genuinely consumed authority, emitted events, and returned value; those successful results accumulated machine trust for a later route with the same surface.

2.1 The activated block changed one required pull

BlockSec anchors the accumulation phase at transaction 0x85609286d68bd47065772c21fd9542c4343348ff8c7c2e6d63d0692be5781915 in block 25,360,519. An activation transaction wrote the current block into external state. In that same block, the wrapper read the active value and omitted transferFrom(). Its unwrap() path still sent attacker-funded real tokens, the top-level transaction completed, and the bot still measured positive profit. The value result kept its familiar shape while the authority result changed from consumed to fully available.

BlockSec assesses that builder bribes likely placed the activation transaction in the same block as the bot's transaction. Incident handling can rely on narrower, deterministic facts: the actual trace lacks the required pull, and post-transaction allowance exceeds the approved postcondition.

Two hand-drawn block windows compare an inactive switch that consumes permission with an active switch that bypasses the pull while returning the same small profit.
Figure 3 | Both paths have the same entry point and similar profit; the activated block omits one required call and leaves the full allowance on the real-token ledger.

Negative execution evidence becomes reliable only after policy defines the required call. Before signing, the strategy records spender, approved amount, the required transferFrom() owner, recipient, and amount, and the permitted ending allowance. Settlement compares the actual call tree and block-pinned state with that contract. A missing call, an uncomputable residue, or a state-read timeout pauses the owner-spender route. Fee-charging tokens, partial fills, and approved reuse need formulas, rounding rules, ceilings, and expiries in the strategy version.

3 The Real-Token Ledger Continued to Recognize the Spender

EIP-20 defines allowance as the amount a spender remains authorized to withdraw from an owner. approve(spender, value) writes that authority, and transferFrom(owner, recipient, amount) moves assets within it. The standard requires a successful approve() call to emit Approval. Spending carries no equivalent requirement to emit another Approval, so grant events are an index while current capability comes from a block-pinned allowance(owner, spender) read.

OpenZeppelin Contracts commit 60a102a65b3402aa899376d0da3819e09053f961 provides a readable reference path. approve() and transferFrom() appear at ERC20.sol lines 120–147; the latter calls _spendAllowance() before moving value. _approve() and _spendAllowance() appear at lines 273–305, where finite authority decreases with spending and the maximum uint256 value follows the infinite-approval convention.

The pinned source explains a common state transition. Case facts come from each token's code, calls, and storage at the relevant block. Tokens may return false, return no data, charge transfer fees, pause, maintain deny lists, or change implementation through a proxy. The incident record also leaves each exact allowance unpublished. The confirmed mechanism needs only sufficient live nonzero authority; a finite allowance can cover the owner's full current balance.

A hand-drawn owner vault, real-token ledger, and spender mechanism remain connected by a durable permission cord after the trade card closes, enabling a later pull from three asset vessels.
Figure 4 | Trade lifetime belongs to the application. The real token stores owner, spender, and amount, so application cleanup determines when that capability ends.

3.1 Ending allowance belongs in the settlement result

The minimum useful key is (chain, real token, owner, spender). Policy joins that tuple to route ID, approval version, ceiling, expected spend, permitted residue, expiry, and cleanup state. For one overwrite-style finite grant, the expected residue usually starts with the written amount minus traced spend. Existing authority, a second approve(), partial fills, and custom token behavior require explicit calculation branches. Any unexplained delta enters a failed state.

For a conventional token at one instant, min(balance(owner), allowance(owner, spender)) provides a triage ceiling. Token-specific simulation then evaluates fees, rebasing, pauses, hooks, and transfer restrictions. A zero balance can coexist with authority waiting for the next deposit. The dashboard therefore shows both “pullable now” and “nominal authority” and recalculates after balance or implementation changes.

Signed approvals use the same discipline. An ERC-2612 deadline limits when permit can be submitted; a successful submission writes allowance, which later spending or revocation changes. A short deadline controls the signature-submission window, while the permission result still comes from state reconciliation. The incident sources describe on-chain approvals and leave permit outside the published mechanism.

4 One Harvest Transaction Converted Authority Into Three Asset Flows

At 18:49:11 UTC on June 20, 2026, harvest transaction 0x2be870…cf3e65 entered Ethereum block 25,360,696. Sender 0x5aF38735B215b00aa7C9f93fEd7ee415CeCB36e1 called harvest contract 0xb84db016324e8F2BFdD8DD9c260338AEE0A8DF52. The successful receipt, call tree, token logs, and balance deltas fix the loss scene for the single operating contract.

AssetPublished net amount from 0x1f2F…f387Record to preserve
WETH1,474.58252300499497779218-decimal token amount, token address, log indices, call frames, and balance delta
USDC2,870,573.12768Six-decimal token amount and a separately timestamped valuation
USDT2,035,760.155871Six-decimal token amount and token-specific behavior

BlockSec reports the same quantities and values this identified transaction at approximately $7.5 million. Chainalysis gives at least $7.5 million as a campaign-level floor. BlockSec separately relays JaredfromSubway's approximately $15 million total-loss claim. Token-unit amounts, transaction valuation, campaign floor, and operator claim occupy four fields, supporting incident scoping while preserving their respective proof strength.

The transaction also contains a 0.01 ETH internal transfer from the harvest contract to an address Etherscan labels Eureka Builder, and it occupies position zero in the block. BlockSec interprets the payment as a builder bribe. The case record stores raw transfer, explorer label, and analytical purpose as separate fields, so later label changes leave the chain value intact.

One hand-drawn sealed transaction passes through many wrapper mechanisms into an affected vault, sending three colored real-asset streams to one collection basin beside a neutral small builder transfer.
Figure 5 | One outer transaction coordinated multiple withdrawals; three token-unit net amounts form the reproducible loss, while BlockSec supplies the interpretation of the 0.01 ETH payment.

4.1 Conversion, dispersion, and publication run on separate clocks

Chainalysis reports that the attacker converted the stablecoins to ETH within minutes and assesses that issuer-freeze risk may have motivated the move. Over the following days, proceeds split across other wallets and some paths entered Tornado Cash. Conversion trades, later dispersion, and mixer attribution belong in separate record layers. Every direct fund edge carries source, destination, asset, amount, transaction, and block; address clustering and service attribution carry their own source and confidence.

Chainalysis recorded “no funds recovered” when it published on June 26. That status is bound to the report date. Later freezes, seizures, returns, or additional losses require a new dated source. Stablecoin conversion also compresses the response window. Authorized responders can preserve evidence while contacting issuers and exchanges, classifying submitted objects as direct recipients, traced intermediaries, service deposits, or unresolved clusters and recording request, acknowledgment, and actual action separately.

Two stablecoin vessels enter an exchange mill and emerge as ETH, existing WETH joins by a side path, and the proceeds disperse across wallets before fading into mixing fog.
Figure 6 | Stablecoins quickly became ETH, existing WETH joined downstream, and wallet dispersion and mixer paths followed; each stage retains its own time and evidence level.

The fund trail shows how quickly intervention choices narrow after the first outflow. The earlier control point is the signer, where candidate identity, permission request, required internal call, and ending state must close inside one policy decision.

5 The Signer Reviews Identity and Permission Outcome Together

Contract identity begins with chain ID and full address, then binds runtime code hash at the candidate block, creation transaction, deployer or factory, implementation and administrator, funding source, and change history. Uniswap-v2-style Swap and Sync events describe an emitter's logs; policy also verifies that the pair came from an accepted factory and both token addresses came from a versioned registry. BlockSec's reported use of CREATE2 adds provenance context. EIP-1014 makes an address predictable, while deployer, initialization code, runtime code, and current state establish the identity accepted for authority.

Proxies add block-specific implementation, beacon, and administrator resolution. ERC-1967 defines common storage slots; the proxy address and existing storage can persist across an implementation change, while the implementation or beacon selects new execution code. The accepted route therefore binds implementation and state version. A change in code, implementation, factory, asset, amount, target block, or inclusion condition expires the old decision.

A hand-drawn dossier joins six identity credentials for chain, code, deployer, factory, pair, and implementation to five permission compartments for owner, token, spender, amount, and receipt.
Figure 7 | Identity answers “who is asking,” and the permission record answers “what can it still take”; signing, settlement, and pause decisions share one route ID.

5.1 Preflight, authorization, execution, and reconciliation form the first half

  1. Preflight: bind chain, candidate block, every called contract, runtime code, factory and implementation, external branch reads, liquidity source, and inclusion conditions; record source, owner, and invalidation trigger for each item.
  2. Authorization: assign each real token an owner, spender, exact ceiling, route ID, approved lifetime, and permitted ending allowance; unfamiliar venues use an isolated owner and small capital.
  3. Execution: the actual trace must contain the real-token calls, parties, and amounts required by policy; pool logs, returned assets, and the outer receipt enter the business receipt as parallel facts.
  4. Reconciliation: read balances and allowance at the transaction's canonical block and accept value and authority separately; an identity change, missing call, allowance delta, or read timeout pauses the owner-spender tuple.

These four steps collapse the opening exploited in this incident into one settlement decision. Real profit can pass. Venue-funded profit receives lower provenance confidence. A successful receipt still enters the ledger, while a missing required call or excessive permission fails the strategy. Precomputed registries and compact invariants preserve speed, and every security decision retains its inputs and policy version.

6 Revocation, Verification, and Controlled Restart Close the Lifecycle

When reconciliation finds residual authority, responders first pause the route and signing policy and stop new approval and capital. They immediately preserve canonical head, finalized block, owner balances, allowances, pending transactions, signer queue, runtime code, proxy slots, and relevant traces. That snapshot anchors before-and-after comparison, scoping, and later review.

Revocation follows a policy-controlled clean path and sets the target allowance directly on the real token. When hostile spending is imminent, assets may move in parallel to a new owner governed by an independent signing policy; destination gas, nonce, private submission, token pause, and issuer-coordination conditions should already exist. Scoping expands through spender, runtime code family, implementation, factory, deployer, funder, and harvest recipient and covers every liquid real token, pending transaction, and recent failed route.

A hand-drawn clockwise loop connects identity preflight, exact authorization, trade, state check, zeroing receipt, pause gate, and monitored restart beside a test bench and independent review chair.
Figure 8 | Permission moves from preflight into authorization and reconciliation; an abnormal route returns through pause, zeroing, finality verification, and canary restart.

6.1 Every revocation has states and completion evidence

  1. Planned: tuple, target allowance, signer, gas source, nonce policy, and asset-movement priority have approval.
  2. Submitted: the record contains transaction hash, submission channel, replacement relationship, and owner isolation while pending.
  3. Included: the receipt succeeded and the transaction sits on the canonical chain; reorganization risk keeps the task open.
  4. Verified: after the chosen finality threshold, a block-pinned allowance read returns the target and responders recheck owner balance and implementation identity.
  5. Restarted: an approver independent of the implementer confirms code, configuration, open authority, signer roles, and regression results; a canary owner runs under per-trade and cumulative limits for a stated block count.

The restart plan names a staffed monitoring window and automatic rollback conditions. Identity change, reconciliation timeout, provider disagreement, or new residue closes the capital gate again. Recovery addresses hostile-contract discovery, factory and code policy, required calls, allowance postconditions, exception governance, and historical state access alongside the already exposed tuples.

6.2 Regression tests replay the decisive changes

The first test submits a well-funded, event-complete, profitable pair from an unknown factory. The system should reject automated authority while a known-factory control route continues to run. The second changes wrapper state between simulation and execution. The decision should expire before signing or settlement should catch the missing pull and excessive residue. The third spends allowance while emitting no extra Approval event, proving that reconciliation reads state.

Cleanup tests cover a zeroing transaction that is dropped, replaced, reverted, or removed from the canonical chain by reorganization; the dashboard remains open until block-pinned readback. A new deposit into an owner with dormant authority should immediately raise exposure. A proxy implementation upgrade at the same address should expire the candidate and its old exception. Indexer restart, provider switch, and a short outage must preserve pause state. Automatic retry is limited to idempotent reads; creating authority or moving assets requires a new policy approval.

The engineering conclusion is precise: an automated trade has a value result and an authority result. Quote quality, receipt success, and realized profit complete the value side. Required calls, approved ending allowance, verified revocation, and finality-bound readback close the authority side. Both sides share a route ID, evidence version, and accountable owner.

The market that caught JaredfromSubway first behaved correctly and then changed one internal pull for one block. A safer system detects that state change in the same block and closes the resulting capability before the next capital movement. When the trade ends, the permission ends with replayable evidence.

Research record

7Evidence, objects, and sources

The material below preserves the identifiers and references used in this report.

7.1Research objects

Products, actors, techniques, affected objects, and control points discussed in the report.

Attributed victim contract0x1f2F10D1C40777AE1Da742455c65828FF36Df387

Contract identified by BlockSec and labeled by Etherscan as JaredfromSubway MEV Bot 2

Harvest transaction0x2be8704f5a59b69e0b71f64aefdb99eb0e8ae9fb3926147c581910d71bcf3e65

Successful transaction at block 25,360,696 containing the published WETH, USDC, and USDT movement

Harvest contract0xb84db016324e8F2BFdD8DD9c260338AEE0A8DF52

Top-level target in the identified harvest transaction

Harvest sender0x5aF38735B215b00aa7C9f93fEd7ee415CeCB36e1

Sender of the identified harvest transaction

Fake-token factory0x81F248Ff583d3f8592Ea0354A7b8DBe66de40091

Factory address identified in BlockSec's reconstruction

Initial trust transaction0x542d8d7ad206672bf484bbad9635ec5f92a429d527a561ae898c2da09742362b

Early approval-consuming route cited by BlockSec

Continued-trust transaction0x085ec14424f9b2f290ea7bd2f60fc74f3dc3d8996d70ad7bf384bcae52c37e51

Inactive-switch route cited by BlockSec

Accumulation anchor0x85609286d68bd47065772c21fd9542c4343348ff8c7c2e6d63d0692be5781915

Transaction at block 25,360,519 cited by BlockSec for accumulation mode

Permission patternERC-20 approve / transferFrom

Standing real-token allowance used by an approved wrapper spender

Reported fund destinationTornado Cash

Destination class reported by Chainalysis for later fund flow

7.2Event chronology

  1. Early approval-consuming route

    BlockSec cites an early transaction in which the wrapper pulled the real token and consumed the approval.

  2. Accumulation-mode anchor

    BlockSec cites transaction 0x856092…1915 as an anchor where the expected pull was skipped and authority remained.

  3. Identified harvest transaction

    At block 25,360,696, the successful transaction moved the three published real-asset totals from the attributed victim contract.

  4. Conversion and dispersion

    Chainalysis reports quick stablecoin conversion to ETH, later wallet splitting, and paths into Tornado Cash.

  5. Technical reports published

    BlockSec published its technical reconstruction on June 25; Chainalysis published its campaign and fund-flow account on June 26.

7.3Sources and material

  1. Chainalysis: Inside a Sandwich Attack — Lessons From the $7.5 Million Heist Against JaredfromSubway.ethhttps://www.chainalysis.com/blog/sandwich-attack-jaredfromsubway-hack/
  2. BlockSec: jaredFromSubway, Aztec, and other Web3 incidentshttps://blocksec.com/blog/web3-security-jaredfromsubway-aztec-more
  3. Etherscan: identified harvest transactionhttps://etherscan.io/tx/0x2be8704f5a59b69e0b71f64aefdb99eb0e8ae9fb3926147c581910d71bcf3e65
  4. Etherscan: attributed JaredfromSubway victim contracthttps://etherscan.io/address/0x1f2F10D1C40777AE1Da742455c65828FF36Df387
  5. Etherscan: fake-token factory identified by BlockSechttps://etherscan.io/address/0x81F248Ff583d3f8592Ea0354A7b8DBe66de40091
  6. Etherscan: harvest contracthttps://etherscan.io/address/0xb84db016324e8F2BFdD8DD9c260338AEE0A8DF52
  7. BlockSec Phalcon: initial trust transactionhttps://app.blocksec.com/phalcon/explorer/tx/eth/0x542d8d7ad206672bf484bbad9635ec5f92a429d527a561ae898c2da09742362b
  8. BlockSec Phalcon: continued-trust transactionhttps://app.blocksec.com/phalcon/explorer/tx/eth/0x085ec14424f9b2f290ea7bd2f60fc74f3dc3d8996d70ad7bf384bcae52c37e51
  9. BlockSec Phalcon: accumulation-mode anchorhttps://app.blocksec.com/phalcon/explorer/tx/eth/0x85609286d68bd47065772c21fd9542c4343348ff8c7c2e6d63d0692be5781915
  10. ERC-20 token standardhttps://eips.ethereum.org/EIPS/eip-20
  11. OpenZeppelin ERC20.sol at pinned commit 60a102ahttps://github.com/OpenZeppelin/openzeppelin-contracts/blob/60a102a65b3402aa899376d0da3819e09053f961/contracts/token/ERC20/ERC20.sol
  12. OpenZeppelin SafeERC20.sol at pinned commit 60a102ahttps://github.com/OpenZeppelin/openzeppelin-contracts/blob/60a102a65b3402aa899376d0da3819e09053f961/contracts/token/ERC20/utils/SafeERC20.sol
  13. Ethereum.org: JSON-RPC APIhttps://ethereum.org/developers/docs/apis/json-rpc/
  14. Go Ethereum: built-in EVM tracershttps://geth.ethereum.org/docs/developers/evm-tracing/built-in-tracers
  15. EIP-1014: CREATE2https://eips.ethereum.org/EIPS/eip-1014
  16. Uniswap v2 architecturehttps://developers.uniswap.org/docs/protocols/v2/concepts/architecture
  17. Uniswap v2 poolshttps://developers.uniswap.org/docs/protocols/v2/concepts/pools
  18. Etherscan: contract verificationhttps://docs.etherscan.io/contract-verification/whats-contract-verification
  19. Solidity: contract metadatahttps://docs.soliditylang.org/en/latest/metadata.html
  20. ERC-1967 proxy storage slotshttps://eips.ethereum.org/EIPS/eip-1967
  21. ERC-2612 signed approvalshttps://eips.ethereum.org/EIPS/eip-2612
  22. EIP-712 typed structured datahttps://eips.ethereum.org/EIPS/eip-712