← Back to articles
July 19, 2026
5 min read

Liquidations on-chain: Aave and Compound mechanics, and the bot business around them

Liquidations on-chain: Aave and Compound mechanics, and the bot business around them
#defi
#liquidations
#aave
#compound
#mev
#chainlink
#flash loans
#crypto

A liquidation on Aave is a standing public offer: repay someone else's debt and receive their collateral at a 5–15% discount. The offer is written into an immutable contract, requires no permission, no KYC, no relationship with the protocol — just being the first address to call liquidationCall() in the block where a position crosses the line. It is the purest race in crypto: the prize is known to the cent, the trigger is (mostly) predictable, and the only question is whether your infrastructure gets there before everyone else's.

This article dissects the machine end to end: the exact math that defines when a position becomes liquidatable, why Chainlink oracle mechanics make liquidations predictable rather than reactive, what a competitive liquidation bot actually consists of, and why the economics of the race have compressed to the point where most of the bonus now leaks to block builders — and, increasingly, back to the protocols themselves. At the end we contrast this with perp-DEX liquidations (GMX, Hyperliquid), which look superficially similar but are a completely different game.

The mechanics: health factor, thresholds, bonuses

LTV vs liquidation threshold

Every collateral asset on Aave v3 carries two distinct risk parameters, and confusing them is the most common mistake borrowers make:

  • LTV (loan-to-value) — the maximum you can borrow against the asset at origination. For WETH on Aave v3 mainnet this is around 80%.
  • Liquidation threshold — the collateralization level at which the position becomes liquidatable. For WETH, around 83%.

The gap between them is a deliberate buffer: you cannot open a position that is instantly liquidatable. But the buffer is thin — a few percent of adverse price movement separates "maximally borrowed" from "up for grabs."

The health factor aggregates everything into one number:

HF=iCiPiLTijDjPjHF = \frac{\sum_i C_i \cdot P_i \cdot LT_i}{\sum_j D_j \cdot P_j}

where CiC_i is the amount of collateral asset ii, PiP_i its oracle price, LTiLT_i its liquidation threshold, and DjPjD_j \cdot P_j the value of each debt position. When HF<1HF < 1, anyone may liquidate. There is no grace period, no margin call, no notification. The condition is evaluated lazily — nothing happens until someone calls the function.

Health factor bands: safe zone above HF 1, partial liquidation between 0.95 and 1, full liquidation below 0.95

Close factor and liquidation bonus

Two more parameters define what the liquidator gets:

  • Close factor — the fraction of the debt a single liquidation may repay. Aave v3's default is 50%. Since Aave v3.3, the close factor jumps to 100% when HF<0.95HF < 0.95 (the CLOSE_FACTOR_HF_THRESHOLD), or when the position's collateral or debt is below a dust threshold (~$2,000) — small positions aren't worth two transactions, and leftover dust creates bad-debt accounting problems.
  • Liquidation bonus (also called liquidation penalty, depending on whose side you're on) — the discount at which the liquidator buys collateral. On Aave it is a fixed spread set per-asset by governance: roughly 5% for WETH and major stablecoins, up to 10–15% for volatile long-tail collateral.

Compound v2 works the same way with different constants: liquidateBorrow() with a 50% close factor and an 8% liquidation incentive (the seized cToken collateral is worth 1.08× the repaid debt). Compound v3 (Comet) redesigned the flow into two steps: absorb() pulls the underwater position onto the protocol's own balance sheet (debt is socialized into reserves, collateral becomes protocol property), and buyCollateral() lets anyone purchase that collateral from the protocol at a governance-configured discount, paid in the base asset. In practice a liquidator calls both in one transaction — absorb itself pays nothing, the profit is entirely in the discounted buyCollateral.

A concrete position, liquidated step by step

Take representative Aave v3 WETH parameters: LTV 80%, liquidation threshold 83%, liquidation bonus 5%.

Setup. You deposit 10 WETH at $3,000 ($30,000 collateral) and borrow 20,000 USDC.

HF=30,000×0.8320,000=1.245HF = \frac{30{,}000 \times 0.83}{20{,}000} = 1.245

Liquidation price. HF=1HF = 1 when collateral value falls to 20{,}000 / 0.83 = \24{,}096, i.e. ETH at **\2,410** — a 19.7% drawdown. Feels safe. It is not, because ETH does 20% drawdowns for breakfast.

The drop. ETH prints $2,350 on the oracle. Collateral is now $23,500:

HF=23,500×0.8320,000=0.975HF = \frac{23{,}500 \times 0.83}{20{,}000} = 0.975

0.95<HF<10.95 < HF < 1, so the 50% close factor applies. A liquidator repays 10,000 USDC of your debt and seizes collateral worth 10{,}000 \times 1.05 = \10{,}500$ at oracle price:

10,5002,350=4.468 WETH\frac{10{,}500}{2{,}350} = 4.468 \text{ WETH}

The liquidator's P&L. They spent $10,000 and received $10,500 of ETH: $500 gross profit for one function call, before gas, swap costs to exit the ETH, and — critically — before whatever they had to bid to win the race (more on that below).

Your P&L. Debt down to $10,000, collateral down to 5.532 WETH ($13,000). New health factor:

HF=13,000×0.8310,000=1.079HF = \frac{13{,}000 \times 0.83}{10{,}000} = 1.079

Note two uncomfortable facts. First, you paid $500 for the privilege of forced deleveraging — the bonus comes entirely out of your equity. Second, the new HF of 1.079 is barely above water: another 7% drop in ETH re-triggers liquidation on the remaining half. Fixed-spread liquidation restores solvency, not safety. This "half-liquidation, still fragile, liquidated again" pattern is the microstructure behind cascade dynamics, which we cover in the sibling article on liquidation cascades as a trading signal.

The trigger: liquidations are predictable, not reactive

Here is the part that separates people who understand this business from people who don't: on Aave and Compound, positions do not become liquidatable when the market price moves. They become liquidatable when the oracle updates.

Both protocols read prices from Chainlink data feeds. A Chainlink feed on Ethereum mainnet pushes a new on-chain price when either of two conditions fires:

  • Deviation threshold — the off-chain aggregated price moves more than a set percentage from the last on-chain value: 0.5% for ETH/USD on mainnet, 1–2% for most smaller feeds.
  • Heartbeat — a maximum interval (3,600 seconds for ETH/USD) after which an update is pushed regardless of deviation.

This has a profound consequence. Between updates, the on-chain price is stale by construction. If Binance ETH drops 0.6% while the on-chain feed still shows the old price, every sophisticated actor knows an oracle update transaction is coming, knows what the new price will (approximately) be, and can compute — before the update lands — exactly which positions will cross HF<1HF < 1 the moment it does.

Timeline showing off-chain price crossing the deviation threshold, the pending oracle update, and the liquidation executed in the same block as the update

The dominant strategy is therefore not "watch health factors and react" but backrun the oracle update: construct a bundle in which your liquidationCall() executes immediately after the Chainlink transmit transaction, in the same block. The oracle update is the starting gun, and everyone can see the starter raising the pistol. The bundle mechanics — private submission to block builders, atomic ordering guarantees — are the same machinery we covered in the article on sandwich attacks and mempool frontrunning; liquidations are simply the most legitimate use of it.

Two refinements matter in practice:

  1. You don't even need to see the transmit in the mempool. Since the off-chain aggregation is observable (you can run the same price computation from CEX feeds), you can predict that an update must fire once deviation exceeds the threshold, and pre-build bundles for both the price path up and the price path down.
  2. Heartbeat updates are scheduled liquidity events. If a feed hasn't deviated 0.5% in an hour, an update lands anyway — and if the price has drifted 0.4% against a wall of positions clustered near HF=1HF = 1, that "harmless" heartbeat is the trigger. Competitive operators track time-since-last-update per feed as a first-class signal.

This predictability is also why the protocols eventually moved to reclaim the value. In March 2025, Aave integrated Chainlink SVR (Smart Value Recapture): oracle updates for participating feeds are routed through Flashbots MEV-Share, the right to backrun them is auctioned, and the winning bid is split between the Aave DAO (65%) and Chainlink (35%) rather than leaking entirely to searchers and builders. Within months the system had processed over $32M in liquidations and recaptured over $1.1M, capturing 80%+ of eligible liquidation MEV. Read that as a market price: the open race had become so efficient that the protocol could auction the finish line.

Building the bot: the four subsystems

A competitive liquidation bot is not a script; it is a small trading firm's worth of infrastructure. Four subsystems, each individually simple, all latency-critical in aggregate.

Liquidation bot architecture: indexer, health monitor with oracle simulation, flash-loan execution contract, bundle submission to builders

1. Position indexing

You need the full set of borrowers and their balances, maintained in real time. The bootstrap is an event backfill — every Supply, Borrow, Repay, Withdraw, LiquidationCall since protocol deployment — folded into current per-user balances, then kept live via a websocket subscription to new logs. Aave's getUserAccountData(address) returns the health factor directly, but calling it per-user per-block for 100k+ borrowers is hopeless; serious operators replicate the protocol's accounting locally (including the interest-rate index math, since debt grows every second) and reserve RPC calls for verification.

2. Health-factor monitoring with oracle simulation

The core loop is not "compute HF at current oracle prices." It is "compute HF at the price the oracle is about to publish":

def liquidatable_at(positions, feed, candidate_price):
    """Positions that cross HF < 1 if `feed` updates to candidate_price."""
    out = []
    for pos in positions.borrowers_exposed_to(feed):
        hf = pos.health_factor(price_override={feed: candidate_price})
        if hf < 1.0:
            close_factor = 1.0 if hf < 0.95 else 0.5
            repay = pos.debt_value * close_factor
            seized = repay * (1 + pos.liq_bonus)
            gross = seized - repay          # the prize, pre-costs
            out.append((pos, repay, gross))
    return sorted(out, key=lambda x: -x[2])

deviation = abs(offchain_px - onchain_px) / onchain_px
if deviation > FEED_DEVIATION_THRESHOLD * 0.8:   # update imminent
    targets = liquidatable_at(positions, feed, offchain_px)
    for pos, repay, gross in targets:
        prepare_bundle(pos, repay, max_bid=gross - costs(pos))

Sorting positions by proximity to HF=1HF = 1 (a priority queue keyed on the price that would trigger each position) keeps the hot set small. The 0.8 factor is the whole game: you want bundles built and submitted before the update is certain, not after.

3. Flash-loan-funded execution

You do not need capital to liquidate — you need it for roughly 200 milliseconds of block time. The canonical execution contract does, atomically:

  1. Flash-borrow the debt asset (Balancer at 0 bps, or Aave itself at ~5 bps — the same primitive we built up in atomic arbitrage with flash loans).
  2. Call liquidationCall(collateral, debtAsset, user, repayAmount, false) — the false receives underlying collateral rather than aTokens.
  3. Swap the seized collateral back to the debt asset on whichever venue quotes best (Uniswap v3 / v4, 1inch route, or a private fill).
  4. Repay the flash loan; the remainder is profit, verified with a require(profit >= minProfit) so a stale simulation reverts instead of executing at a loss.

The swap leg is where sloppy bots die: seizing $10,500 of a long-tail token means eating its DEX liquidity, and price impact on exit can exceed the liquidation bonus. Competitive operators simulate the full round trip — including the exit swap — and skip liquidations where the net is negative, or hold the collateral and hedge on a perp instead of market-dumping it.

4. Bundle submission

The final transaction goes nowhere near the public mempool. It is submitted as a bundle to block builders (or into the SVR/OEV auction where that applies), stating: "place my liquidation immediately after this oracle transmit; here is my tip." The tip is your bid in an all-pay-nothing-if-you-lose auction against every other bot that ran the same simulation. Which brings us to the uncomfortable economics.

The competition: where the bonus actually goes

The academic baseline is Qin, Zhou, Gamito, Jovanovic and Gervais, "An Empirical Study of DeFi Liquidations: Incentives, Risks, and Instabilities" (2021), which measured the business across Aave, Compound, MakerDAO and dYdX from April 2019 to April 2021: 28,138 liquidations totaling $807M, with $63.6M of aggregate liquidator profit. The paper also documented the structural inefficiency of fixed-spread liquidation — the discount is a blunt instrument that routinely over-penalizes borrowers relative to what an auction would charge — and showed liquidators leaving measurable money on the table with naive strategies.

That era's profits will not be repeated, for three compounding reasons:

The gas auction became a builder auction. In 2019–2020, liquidators competed in priority-gas auctions in the open mempool; the winner overpaid gas, the losers reverted, and a meaningful fraction of the bonus stayed with the liquidator. Post-MEV-Boost, competition happens in sealed builder auctions. When N bots simulate the same deterministic opportunity to the same profit figure, bidding converges toward the full prize: the winning bundle routinely tips 90%+ of gross profit to the builder/validator. The liquidator's edge collapses to whoever has marginally better exit pricing, marginally lower costs, or opportunities others failed to see.

Oracle backruns dominate, and they are being enclosed. Since nearly all money-market liquidations are triggered by oracle updates, the profitable strategy space collapsed onto one point: win the slot right after the transmit. SVR-style mechanisms formalize this — the protocol auctions that slot and keeps most of the proceeds. The searcher's take shrinks from "the bonus minus gas" to "the auction winner's margin," which competitive bidding drives toward zero.

The long tail is what's left. The realistic niches for a new entrant in 2026: chains and L2s where builder markets are immature; long-tail lending forks with mispriced bonus parameters and few competing bots; positions with exotic collateral where the exit-swap simulation is genuinely hard (edge through better execution, not better latency); and stress events, when gas spikes and RPC failures knock out the marginal operators — MakerDAO's Black Thursday (March 2020), when zero-bid auctions let liquidators claim $8.3M of collateral essentially for free because nobody else's infrastructure was functioning, remains the canonical example that the race pays best precisely when it is hardest to run.

Sizing the honest expectation: this is now a business with real fixed costs (nodes, builder relationships, monitoring across a dozen deployments) competing for a heavily rebated prize pool. It is a fine way to learn more about EVM internals, oracles and MEV plumbing than any course will teach you. It is a hard way to make a living.

Perp-DEX liquidations: same word, different game

Perpetual DEXs also "liquidate," and the headline numbers are bigger — but the mechanism, and therefore the opportunity, is structurally different.

GMX (v2): positions trade against a liquidity pool at oracle prices (Chainlink low-latency Data Streams). Liquidation fires when collateral minus losses and fees falls below maintenance requirements, and it is executed by keepers — designated infrastructure operating on oracle-signed prices, not an open race. There is no public function paying a 5% bonus to whoever calls first; remaining collateral flows to the pool per protocol rules. From a searcher's perspective there is nothing to win.

Hyperliquid: liquidations run inside the L1's own matching engine. When account equity falls below maintenance margin (evaluated at a mark price blended from CEX feeds and the book, precisely to resist the oracle games described above), the engine sends liquidation market orders into the order book — large positions in partial chunks to limit impact. If equity keeps falling below two-thirds of maintenance margin, the position is taken over at mark price by a backstop liquidator vault that is a strategy inside HLP, the protocol's community-owned market-making vault, with auto-deleveraging as the final layer. Liquidation P&L accrues to HLP depositors — the "liquidator profit" is socialized into a vault anyone can join, not raced for per-event.

The consequence for a trader: on money markets, the game is being the liquidator — an infrastructure race for a fixed spread. On perp DEXs, the liquidator role is closed, so the game shifts to trading around liquidations: liquidation prices are computable from open positions, forced flow hits a visible order book, and clustered liquidation levels become both a magnet and a fuel source for price moves. That is the same logic that makes CEX liquidation cascades tradable — the dynamic we touched on in funding rates kill your leverage (leverage cost is what pushes positions toward the cliff) and in shitcoin pump-and-dump mechanics (engineered pushes into liquidation clusters). The full treatment of cascades as a signal — detecting them forming, measuring their fuel, trading the overshoot — is the subject of the next article in this series.

What to take away

Money-market liquidation is the rare corner of crypto where everything is legible: the trigger condition is a formula, the prize is a governance-set constant, the starting gun is an oracle transaction you can see coming. That legibility built a genuinely open business in 2019–2021, and then — exactly because everything was legible — competition priced the edge down to infrastructure quality and auctioned the remainder back to the protocols. The mechanics remain essential knowledge: if you borrow on-chain, this math is your risk model; if you trade around forced flow, oracle cadence and close factors tell you when and how much; and if you build the bot anyway, at least build it knowing where the money actually goes.

Disclaimer: The information provided in this article is for educational and informational purposes only and does not constitute financial, investment, or trading advice. Trading cryptocurrencies involves significant risk of loss.

Authors

Eugen Soloviov
Eugen Soloviov

Trading-systems engineer

Trading-systems engineer building bots since 2017: cross-exchange arbitrage (connected up to 30 venues), cointegration-based pairs arbitrage across spot and futures, scalping, news and sentiment-driven strategies, trend algorithms, and portfolio management and balancing algorithms. Also builds sub-millisecond order execution, big-data warehouses, backtesting engines, AI agents, and trading interfaces (incl. open-source profitmaker.cc). Stack: JS/TS, Python, Rust/Zig/Go, DevOps, backend, frontend, architecture.

Newsletter

Stay Ahead of the Market

Subscribe to our newsletter for exclusive AI trading insights, market analysis, and platform updates.

We respect your privacy. Unsubscribe at any time.