DEV Community

~K¹yle Million
~K¹yle Million

Posted on

I Told Claude Code to Build an Autonomous DeFi Liquidation Bot. Here's What Actually Happened

The goal was simple: build something that generates revenue without me touching it.

I gave Claude Code a directive. No step-by-step instructions, no hand-holding. Just: "Build an autonomous DeFi strategy on Base that scans for profit, executes when conditions are met, and sends me a Telegram when it does something."

Three weeks and six versions later, here's what actually happened.

Version 1–4: DEX Arbitrage Was Already Dead

The first instinct was DEX arb. Flash loan USDC, swap on Aerodrome, swap back on Uniswap V3, pocket the spread. Standard stuff.

Claude Code built it correctly. Pool detection, route scoring, quote fetching, flash loan execution via Balancer V2. The math checked out. The code was clean.

The problem was the market.

Flashblocks on Base (100ms block times) means MEV bots are processing opportunities faster than any external scanner can even detect them. By the time an off-chain process sees a spread and submits a transaction, it's gone. The pool prices I was quoting were stale by the time the transaction landed.

After four versions, 23 pools, 146 routes, and zero profitable executions, the scanner was honest about it: best spread = -$1.06 per $1000 flash. Market at equilibrium.

That's not a bug. That's correct behavior in a fully competitive market.

The Pivot: Morpho Blue Liquidations

I sent a research document about Morpho Blue's liquidation mechanics and told Claude Code to evaluate whether liquidation bots were a better fit than arb.

The analysis was thorough. Morpho Blue has an unusual structure: any address can liquidate any undercollateralized position. No whitelist. No keeper registry. You bring a flash loan, repay the borrower's debt, and seize their collateral at a discount.

The key insight: liquidation opportunities aren't race conditions in the same way as DEX arb. When a position crosses the liquidation threshold (health factor < 1.0), it doesn't disappear in 100ms. It sits there until someone closes it. The window is minutes to hours, not milliseconds.

This was the right target.

What Claude Code Built

The v7 liquidation daemon is 829 lines of Python. Key components:

Borrower indexing: The daemon seeds from Morpho's API (129 borrowers across AERO/USDC, weETH/WETH, cbXRP/USDC, uniBTC/USDC, wstETH/msETH markets), then stays live by watching Borrow events via eth_getLogs.

Health factor calculation: For each borrower, it reads their supply/borrow shares, converts to assets using the current market state, fetches the oracle price, and computes HF = (collateral × oracle_price/1e36 × LLTV) / borrowed_assets.

Liquidation execution: When HF < 1.0, it constructs a flash loan from Balancer V2, repays the bad debt, and seizes collateral in a single atomic transaction via a deployed LiquidationExecutor.sol.

Watchdog: A bash watchdog loop restarts the daemon on crash and fires a Telegram alert on repeated failures.

The Bugs That Almost Killed It

Here's where it gets honest.

Bug 1 — The HF formula was wrong. The initial implementation computed health factor as (collateral / borrowed) × LLTV. This is missing the oracle price term. Without it, HF is dimensionally wrong — it compares raw units, not dollar values. For a market where collateral is AERO and debt is USDC, a raw ratio gives you something like 10^12, which is never < 1.0. Zero liquidations possible.

Claude Code caught this itself during a v7 test run when the daemon logged HF=2847391847483.5 for a position that was obviously underwater according to Morpho's own interface. It diagnosed the missing oracle price term and rewrote the formula.

Bug 2 — The RPC rate-limiting cascade. The daemon uses Infura for multicall batches (reading all borrower positions per block). Infura's free tier has request limits. At 2-second Base blocks, the daemon was making ~400+ RPC calls per minute. Free tier exhausted in hours.

The fix: use eth_getLogs via public nodes (mainnet.base.org) for the slow indexing pass, and reserve the paid RPC for the latency-sensitive multicall reads on each new block.

Bug 3 — The stale endpoint problem. This one bit me in production yesterday. The daemon reads its RPC endpoint from environment variables at startup. I updated .env to switch from Infura to a Coinbase Base RPC (which is free and doesn't rate-limit), but the running daemon held onto the old Infura URL. It kept silently failing multicalls with 402 errors for 20 hours.

The fix: kill the process, let the watchdog restart it with the new .env. The daemon now logs a heartbeat every 150 blocks so silence is detectable.

Where It Stands

Right now, PID 536542:

  • Subscribed to newHeads on Base via WebSocket
  • Tracking 129 borrowers across 5 markets
  • Reading oracle prices and computing HF on every block
  • Checking Morpho Blue and Moonwell simultaneously

The markets are currently healthy. All tracked positions have HF > 1.0. No liquidation opportunities pending.

What's blocking live execution: the hot wallet (0x793e...) has 0.001 ETH. The flash loan contract needs ~0.009 ETH in gas to execute a liquidation. Until the wallet is funded, the daemon scans but can't pull the trigger.

This is not a software gap. It's a capital gap. The code is correct.

What Claude Code Can and Can't Do Here

Can do:

  • Build production-grade event-driven infrastructure from a research spec
  • Debug its own math errors when given live data to test against
  • Handle multi-contract interactions (Morpho + Chainlink + Balancer + Multicall3)
  • Run autonomously with watchdog recovery, disk caching, and Telegram alerting

Can't do (yet):

  • Fund its own gas wallet from zero capital
  • Predict when DEX markets are too efficient before building against them (though it assessed correctly once given data)
  • Guarantee correctness on first implementation — requires test runs against live data to surface the subtle math bugs

The honest summary: the infrastructure is sound. The engineering decisions are defensible. The remaining blocker is $25 of ETH.


The complete ops stack I used to manage this build — session memory, bash validation, coordinator resume integrity, compaction gate, and 11 other skills — is available at shopclawmart.com/@thebrierfox.

If you're building something like this and want to compare notes, drop a comment. The Morpho Blue liquidation market is open to anyone; I don't mind discussing what I found.

Top comments (0)