if you've been providing liquidity on uniswap v3 for a while and your returns feel... underwhelming — this is probably the answer you've been looking for.

there's a bot that shows up in your pool, takes most of the fees from a massive swap, then disappears. total time in pool: one block. about 12 seconds.

it's called JIT liquidity. sounds like some fancy DeFi feature. it's not. it's an attack.

but before i can show you how the attack works, you need to understand one design decision that makes it all possible.

first, you need to understand one thing about how fees work

in uniswap v3, you don't just dump tokens into a pool and earn fees on everything. you pick a price range — called a tick range — and your liquidity only earns fees when the market price is inside that range.

tighter range = more capital efficient = more fees per dollar deposited. when you're in range.

here's the part that matters: fees are distributed proportionally to how much liquidity you have in range at the exact moment of the swap. not over time. not based on how long you've been there. just a snapshot — right now, at this tick, what percentage of the in-range liquidity do you own?

Tick range diagram showing JIT bot's narrow tall spike dominating the passive LP's wide flat position at current price
the JIT bot's narrow concentrated position completely dominates the passive LP's wider range at the exact price point of the swap.

you could be in the pool for 90 days. a bot could show up 2 seconds before a swap. if that bot owns 80% of the in-range liquidity at that exact moment — it gets 80% of the fees. that one design decision is what the entire attack is built on.

okay so what is JIT, actually?

JIT is just-in-time liquidity. sounds like some crazy feature — it's an attack.

here's the setup. ethereum has a public mempool — basically a waiting room where transactions sit before they get picked up and added to a block. and crucially: anyone can read it.

before your swap even executes on-chain, the entire world can already see who's swapping, how much, and in which pool. a JIT bot reads this. it calculates the exact tick range the swap will touch. then — in the same block as the swap, ordered right before it — the bot deposits a massive concentrated position in that exact range.

the swap happens. the bot owns most of the in-range liquidity. fees get distributed proportionally. the bot takes most of them. same block — the bot withdraws everything. completely out before the next block even starts.

JIT attack step-by-step flow: mempool detection, bot deposit, swap execution, fee capture, withdrawal — all in one block
the full sequence: mempool detection → calculation → deposit → swap → fee capture → withdrawal. all in one block.

a $500,000 swap. 12 seconds. here's what happens.

a whale drops a $500k swap into the mempool. rotating out of ETH into USDC. transaction is pending — not on-chain yet — but sitting there publicly visible for anyone watching.

the bot reads it and does the math. based on current pool state, it calculates exactly which tick range this swap will touch, and how much liquidity it needs to own 80% of the in-range liquidity at that moment.

it submits a deposit transaction. same block. ordered before the swap. the swap executes. the bot is now the dominant LP at this exact tick. fees distribute proportionally. bot captures most of the fees from a $500k trade.

then it withdraws. same block. done.

and the passive LP who's been sitting in this pool for three months? they get almost nothing from that trade. not because their range was wrong. not because they made any mistake. just because, at the precise moment the swap executed, a bot temporarily owned most of the pool.

Bar chart showing fee capture shifting from passive LPs to JIT bots as trade size increases from small to whale
fee capture shifts from passive LPs to JIT bots as trade size increases. small trades are rarely targeted. whale trades are almost entirely captured.

why this is actually unfair

uniswap's fee model has no concept of time in pool. no seniority. no loyalty. the protocol only sees a snapshot: right now, at this tick, who has liquidity in range? a bot in the pool for 12 seconds has the exact same claim as someone who's been there for 90 days.

research has shown JIT attacks can eat up to 44% of passive LP fee income on large trades. not on one trade. systematically. every large swap. every major pool. around the clock.

and the bot takes zero impermanent loss risk while doing this. it's never in the pool long enough for price to move against it. it's pure extraction.

the obvious fix — and why it fails

the first thing people suggest: minimum deposit time. force LPs to wait N blocks before they can earn fees. that way, the bot can't just drop in and drop out.

sounds good. doesn't work.

a bot with enough capital just... pre-positions. it watches the mempool for patterns — recurring large trades, known DEX aggregator routes, predictable on-chain activity. it deposits N+1 blocks before the expected swap, waits, collects fees, withdraws. minimum deposit time raises the cost of the attack — more capital locked for longer, more gas, more forecasting — but it doesn't break the strategy.

Block timeline showing JIT attack works with no minimum and bot simply pre-positions with N-block minimum
side-by-side: the attack with no minimum vs. with an N-block minimum. the bot just shifts its entry earlier. same outcome.

why this is actually a hard problem to solve

here's what makes JIT structurally tricky. the attack looks like three completely normal-looking transactions: bot deposits liquidity in tick range [A, B] — totally normal. large swap touches range [A, B] — totally normal. bot removes all liquidity — totally normal.

no single transaction looks malicious. the attack only becomes visible when you look at all three together — specifically, the timing between them.

uniswap v4 introduced hooks — smart contract code that runs at specific points in the swap lifecycle. people have proposed using hooks to detect JIT. but there's a fundamental limitation: a hook only has context for the single transaction it's currently executing. it can see a swap happening. it can see liquidity being added. what it can't do is correlate — 'hey, this address added liquidity 2 blocks ago right before a big swap, and now they're removing it immediately after.'

detecting JIT requires persistent cross-transaction state. tracking who added how much liquidity where, and checking whether they withdrew suspiciously fast after a large swap. standard hooks don't support this kind of stateful reasoning across transactions without significant additional infrastructure.

Diagram showing three transactions each with an isolated hook that sees only its own transaction, unable to correlate the JIT pattern
hooks see each transaction in isolation. the JIT pattern (deposit → swap → withdraw) only becomes visible across all three — which standard hooks can't correlate.

this is why, in 2026, JIT is still an open problem. the attack surface is real, quantifiable, and systematic. the fixes are either insufficient or architecturally complex. no clean, widely-deployed solution exists yet.

what an actual fix would need to do

cross-transaction state tracking. a hook that keeps a persistent record — who added liquidity, at what tick, in which block. when a withdrawal happens, it checks: did this LP add within the last K blocks? was there a large swap in between? if yes, redistribute or withhold the fees. technically possible. gas-expensive. full of edge cases (what if the LP added legitimately before a coincidental large swap?).

delayed fee settlement. instead of distributing fees atomically at swap time, hold them in escrow and only release after a minimum holding period. makes short-lived positions economically pointless. catch: breaks composability for any protocol that depends on immediate fee distribution.

private mempools or commit-reveal. if swap details aren't visible to bots until they're already on-chain — through encrypted mempools or MEV-protection services like flashbots protect — the JIT attack loses its information advantage entirely. this is happening at the infrastructure level. but it requires users to opt in. and most don't.

none of these is a clean, frictionless fix. they all have tradeoffs. and in a space where capital efficiency and composability are prized above almost everything else, any fix that adds friction will face resistance.

the bigger picture

JIT is a case study in how design creates unintended attack surfaces. proportional, instant fee distribution in uniswap v3 and v4 is elegant and gas-efficient. it's also exploitable by anyone with enough capital and a fast enough bot.

the passive LP — the person who read a DeFi blog, picked a range, deposited their savings, and went back to their day job — is systematically outcompeted by bots that never sleep, never miss a large swap, and take none of the impermanent loss risk.

it's not illegal. it's not a bug in the traditional sense. it's a rational actor exploiting a design choice. and until the design changes, or the information advantage disappears, it will keep happening. every block. on every large swap. in every major pool.