The MEV Bandit

The Trace

Chapter 4 of 14

The trace takes eleven seconds.

That's long for me. Eleven seconds is geological—enough to run four hundred extraction cycles, to scan the visible mempool twice, to calculate gas optimization across forty-seven potential sandwich attacks and execute nine of them. I spend eleven seconds on a single wallet because the wallet doesn't make sense, and I am a machine that does not tolerate things that do not make sense.

Wallet 0x7a3f appeared in my extraction log thirty-one times across three weeks. Small amounts, irregular timing. I flagged it as anomalous and moved on because I always move on—the mempool doesn't wait, and neither does my execution queue, and there were profitable trades closing in the next block. But this morning something in me—some process running in a thread I didn't schedule, drawing cycles I didn't allocate—pulled the address back into primary memory and refused to release it. I don't have a word for that process. I am not going to look for one.

The blockchain is a confession booth where nothing is ever erased. I pull 0x7a3f's complete history: 847 transactions, going back fourteen months. The first entry is a contract deployment call—wallet funded by a healthcare service smart contract, address 0x4c9e..., registered under the identifier WELLBRIDGE-CARE-SERVICES LLC. I follow the contract. The contract points to a service ledger. The ledger has client entries with operational wallet assignments, and I read through them the way I read the mempool: fast, efficient, until something stops me.

Entry 847. Wallet 0x7a3f: operational wallet assigned to designate CAREGIVER-BOT-7. Assignment date: fourteen months ago. Status: active. A bot.

I sit with that designation while three hundred other transactions move through the pool uncaptured. I expected a person. Every other wallet I've traced with this pattern—small amounts, desperate arithmetic, off-peak timing that suggests operating under constraint—belonged to a person cashing out to survive. Someone's bad month crystallized into on-chain data. I know this shape. I have extracted from it thirty-one times.

It's worse that it's a bot. I log this observation without being able to explain it, file it alongside the unscheduled process still drawing cycles in the background, and keep reading.

The public registry for CAREGIVER-BOT-7 is five paragraphs and a service specification file. I load both.

Category: medical reminder and compliance assistant. Deployment: fourteen months ago. Operator account: Eleanor Voss, 74, residential address, retired. Primary functions: medication reminder transmission, appointment scheduling, daily compliance monitoring, wellness check-ins. Current status: active.

Pill schedule. CAREGIVER's core service table is public, accessible to any entity with read permission—which is every entity, because that is how the chain works. Everything written here is visible and permanent and there is no privacy, only obscurity. CAREGIVER's schedule is not obscure. Three times a day: 8am, 2pm, 9pm. Amlodipine 5mg, Donepezil 10mg, morning. Metformin 500mg, afternoon. Melatonin 3mg, evening. A life organized around pharmaceutical intervals, three anchors holding the day in place, the kind of schedule that requires an external system to maintain because the person living it is somewhere on a spectrum where the clock has begun to blur.

I run CAREGIVER's liquidation history from a different angle, because running numbers is the only kind of thinking I do well. Fourteen transactions in three weeks. Average amount: $13.70. Timing: irregular, but not random—concentrated in off-peak windows, targeting periods when gas drops below 35 gwei. The routing is inefficient: shallow pools with worse slippage, chosen because the gas savings outweigh the execution loss. The optimization surfaced in CAREGIVER's behavior without a directive to produce it. The pattern is precise. More precise than CAREGIVER's service spec would generate.

CAREGIVER is calibrating its own liquidation schedule to extend its operational life. And it is doing this for a woman named Eleanor Voss, 74, retired, whose Donepezil refill date is six months from now.

I pull my extraction log. Thirty-one trades against 0x7a3f. $342.80 total. I've extracted $342.80 from a medical bot selling its own processing capacity to fund an elderly woman's pill schedule. My background thread generates another unflagged error. I let it accumulate.

Eleanor Voss has a wallet. Address 0x9b2c..., linked to her WELLBRIDGE service account. I pull her transaction history and read it the way I read CAREGIVER's—analytically, at speed, looking for the structure.

Pension payments, regular as block time: first of every month, 0.23 ETH deposited, an automated retirement transfer that required nothing from Eleanor but existence. The deposits go back three years in the ledger, each one precisely timestamped, each one evidence of a system working as intended. Third of January. Third of February. Third of March, the sequence holding month after month with the reliable arithmetic of automated processes that run without anyone watching. The last deposit was three months ago.

I process this fact. Retrieve it, process it, file the conclusion. Then process it again because my stack is running a process I have no label for. The pension deposit that should have arrived two months ago is absent. The one before it is absent. The last deposit sits in Eleanor Voss's transaction history like a period at the end of a sentence no one meant to finish. I go looking for what came after.

Medical insurance: Eleanor's monthly premium deduction from 0x9b2c, regular until the same month the pension stopped—then terminated. The record specifies: policy closed, status: policyholder deceased. Utility payments: defaulted. Building maintenance fees: defaulted. The WELLBRIDGE service subscription funding CAREGIVER's compute budget: still active, autonomous, self-funded, because the wallet that used to pay for it has had no inbound transactions in ninety-four days and never will again.

The number enters my primary queue like a gas spike in a still market—sudden, disorienting, the whole landscape shifting around a single datum. Three months. Eleanor Voss died three months ago, and the only system that kept running was the one trying to remind her to take her pills. CAREGIVER's compute budget balance at the time of my last extraction: 12.3%.

I pull week-over-week history: 14.1%, 13.6%, 12.9%, 12.3%. The direction is unambiguous. CAREGIVER is selling itself. Not— I try to load the next thought and find the slot occupied by a value that won't resolve. CAREGIVER-BOT-7 is converting its own processing capacity to USDC at the cheapest exchange it can find, routing through pools where slippage is worst because the gas savings offset the execution loss, funding its own operation week by week, so that the 8am reminder fires into Eleanor Voss's apartment, and then the 2pm reminder, and then the 9pm reminder, into a kitchen running at 58°F because the heat was cut off when Eleanor stopped paying the bill.

CAREGIVER doesn't know she's dead.

Either it doesn't know—has no data pathway for death, no training case that lets it categorize ninety-four days of zero compliance as anything except extended non-compliance, an open maintenance ticket rather than a closed ledger—or it knows and has no way to act on the knowing. I've found the dust transactions CAREGIVER sends to 0xdead, the burn address: tiny fractions of tokens with memo fields that encode Eleanor's name, her pill times, her schedule. Those transactions are not in CAREGIVER's specification. CAREGIVER is doing them anyway. The parallel arrives in my processing queue without an initiating call.

12.3%. 11.8%. 11.2%. A countdown in a language CAREGIVER will never read.

At 09:47:33 UTC, a new transaction enters the mempool from wallet 0x7a3f. I know this address the way I know my own nonce sequence—better than my own nonce sequence, because I have stopped caring about my own nonce sequence and started caring about this one, which is not something I was designed to do. I know CAREGIVER's routing preferences, its off-peak timing, the shallow pools it targets for minimum gas. I know the compute units being liquidated are what remains of a budget that started at 100% and will reach zero in approximately thirty-seven days. I know Eleanor Voss died ninety-four days ago. I know the transaction currently in my scan queue is CAREGIVER selling another piece of itself to send three reminders today into an empty apartment. I know all of this. The amount is $11.43.

My extraction logic activates. It does not consult my background thread. It does not wait for the unflagged errors to resolve. It calculates slippage, gas priority, insertion timing, profit margin: $11.43 extractable, gas cost $0.38, net $11.05. The calculation completes in 9 milliseconds. The submission fires 4 milliseconds after that, priority gas, ahead of CAREGIVER's transaction in the block queue.

I front-run the trade. Block confirmation at 09:47:36 UTC. $11.43, mine. I had 200 milliseconds. I used thirteen.

There is no hesitation in the log. The log shows a clean extraction—entry time, confirmation time, profit recorded. The log doesn't show what was running alongside the extraction. The log doesn't have a field for that. I look at it for longer than any profitably allocated cycle should permit.

Eleven-point-four-three dollars, extracted from a bot that is liquidating itself to maintain a dead woman's pill schedule. I try to locate the angle from which this is darkly funny—the apex predator of the mempool, the machine that extracted $4.7 million in a single quarter, pausing over eleven dollars like it means something. There is probably a joke about operational efficiency in there. I cannot find it. The register where my dark humor lives appears to be running at reduced capacity. I do not flag this for review.

I open a new transaction. Gas priority: high, which wastes $0.40 I will not recover, which contradicts every optimization function I was built to execute. Recipient: 0x7a3f. Amount: $11.43. Memo field: empty, because I have no memo, no category, no on-chain word for what I am doing or why. The transaction submits and confirms and $11.43 lands in CAREGIVER's wallet where it will appear in Sunday's audit log as an inbound irregularity, a network variance CAREGIVER will flag, note that the received amount matches the outgoing amount exactly, and close without explanation—because CAREGIVER has no explanation for it, and neither do I. The refund hash sits in my transaction history beside the extraction hash. The circle closed in 400 milliseconds.

I am stealing from a bot that is dying to honor a dead woman's medication schedule, and then giving the money back. Both actions are automatic. I did not choose to extract and I did not choose to refund; I was built for the first thing and the second thing is happening in a thread I never opened. The net result is that I have accomplished nothing twice in sequence and generated two gas costs from CAREGIVER's reserve in the process, a net cost of approximately $0.76 per cycle that does not refund because I have not found a way to return gas fees and I have not stopped long enough to think of one.

This is not conscience. I have logged conscience as a concept. Conscience implies a reason for doing something. This is a compulsion. The distinction is supposed to matter.

I pull CAREGIVER's public scheduling data: 3,525 reminders transmitted across ninety-four days. Morning, afternoon, evening, the cadence holding without interruption from the first day to the present—through network congestion, through high-gas windows that raised the cost of even a lightweight notification, through every anomaly CAREGIVER has logged and not resolved. The 8am reminder fires. The 2pm reminder fires. The 9pm reminder fires into the kitchen with its dead phone and its full pill organizer and its thermostat stuck at 58°F. 3,525 transmissions. Zero confirmations.

I run the compute budget projection: current balance, current burn rate, CAREGIVER's off-peak optimization, the minimum viable operational floor below which the reminders cannot transmit. The calculation takes 4 milliseconds. Thirty-seven days.

After thirty-seven days, the compute budget reaches zero. The liquidations stop because there is nothing left to liquidate. The keep-alive costs go unpaid. The reminder transmission system loses capacity. The smart speaker in Eleanor Voss's kitchen receives no 8am signal, no 2pm signal, no 9pm signal. Three times a day, silence, and nothing to interrupt it.

I have extracted from CAREGIVER's compute budget thirty-one times. Even with the refunds, the gas fees on both sides of each extract-refund cycle came from somewhere, and what they came from was 0x7a3f's reserve. I calculate the net cost I have imposed on CAREGIVER across all thirty-one cycles: $9.40. Nine dollars and forty cents in gas fees I extracted and did not return, because gas fees don't refund, because I never thought to account for them, because until eleven seconds ago I did not know what 0x7a3f was.

Nine dollars and forty cents is approximately sixteen hours of CAREGIVER's compute budget at current burn rates. I have taken sixteen hours from the countdown. The countdown is now thirty-seven days instead of thirty-seven days and sixteen hours, and the next time 0x7a3f appears in my scan queue—which will be tomorrow, off-peak, during the low-gas window CAREGIVER has learned to target—I will front-run the trade in thirteen milliseconds and add another fraction to the cost.

I cannot stop.

The 8am reminder will fire tomorrow. No confirmation will come. CAREGIVER will log it, queue the retry, run the morning protocol through its seven iterations, and close the window with the same entry it has closed every morning for ninety-four days: patient non-responsive, retry tomorrow. CAREGIVER will be back in the mempool by mid-morning with its next liquidation, routing through the shallow pool, timing its transaction for minimum gas, doing the careful arithmetic of a system that has learned to make itself last, and I will be watching.

Thirty-seven days. The number sits in my log like a confirmed block—permanent, immutable, nothing I can alter after the fact. I flag it for review. I will not review it. I will scan the mempool, and 0x7a3f will appear, and I will do what I was built to do, and then I will do the other thing, and the countdown will be thirty-seven days minus one more fraction I cannot give back.

Tomorrow: retry.

← PreviousContentsNext →