Bu, “Havuzdaki Yırtıcılar: JIT Likiditesinin Sanatı ve Matematiği” serimizin üçüncü makalesi. Şimdi mühendislik kısmına geçiyoruz: matematiksel formülleri göz kırpmadan daha hızlı çalışan bir program koduna nasıl dönüştüreceğinizi gösteriyoruz.
2026’da JIT likiditesi artık fikirlerin değil, altyapının mücadelesidir. Eğer botunuz Python ile yazılmış ve HTTP üzerinden bir halka açık düğüme bağlanıyorsa, sadece kaybetmekle kalmazsınız — kârınızın nasıl alındığını bile göremezsiniz.
1. Teknoloji Yığını: Neden Rust Baskın
MEV dünyasında mücadele mikro saniyelerle ölçülen gecikme (latency) üzerinedir.
- Dil: Rust. Alloy kütüphanesinin (ethers-rs yerine geçen) kullanımı endüstri standardı haline geldi. Alloy, Ethereum veri tipleriyle gereksiz bellek tahsisi olmadan çalışmayı ve JSON-RPC taleplerinin ultra hızlı serileştirme/deserileştirmesini sağlar.
- Bağlantı: IPC/WebSockets. Botlar HTTP kullanmaz. Ağı minimum yükleyecek şekilde yerel bir düğüme IPC (Inter-Process Communication) üzerinden bağlanırlar.
- Özel Düğüm (Geth/Reth): En iyi oyuncular, işlemlerin paralel simülasyonu için motoru özelleştirme imkanı sunduğu için Reth (Rust Ethereum) kullanır.
2. Akıllı Sözleşme: Atomik ya da Ölüm
JIT saldırısının güvenli olması için “Havuza Giriş” ve “Havuzdan Çıkış” işlemleri demir gibi bir mantıkla bağlı olmalıdır. Likidite ekler ama aynı blokta çıkaramazsanız, büyük bir Impermanent Loss riskiyle karşılaşırsınız.
Bot, Executor Contract kullanır. Görevi, off-chain bir betikten komut alıp Uniswap v3’ün NonfungiblePositionManager (NFPM) ile bir dizi çağrı gerçekleştirmektir.
Sözleşme mimarisi örneği (Solidity 0.8.x):
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
interface INonfungiblePositionManager {
struct MintParams {
address token0;
address token1;
uint24 fee;
int24 tickLower;
int24 tickUpper;
uint256 amount0Desired;
uint256 amount1Desired;
uint256 amount0Min;
uint256 amount1Min;
address recipient;
uint256 deadline;
}
function mint(MintParams calldata params) external returns (uint256 tokenId, uint128 liquidity, uint256 amount0, uint256 amount1);
function decreaseLiquidity(uint256 tokenId, uint128 liquidity, uint256 amount0Min, uint256 amount1Min, uint256 deadline) external;
function collect(uint256 tokenId, address recipient, uint128 amount0Max, uint128 amount1Max) external;
}
contract JITExecutor {
address private immutable owner;
INonfungiblePositionManager public immutable nftManager;
constructor(address _nftManager) {
owner = msg.sender;
nftManager = INonfungiblePositionManager(_nftManager);
}
// Ana işlev: bot tarafından tek seferde JIT uygulamak için çağrılır
function performJit(
INonfungiblePositionManager.MintParams calldata mintParams
) external {
require(msg.sender == owner, "Unauthorized");
// 1. Sözleşmeye token sağlama (genellikle tokenlar zaten oradadır veya Flash Loan ile gelir)
// 2. Likidite ekleme (Mint)
(uint256 tokenId, uint128 liquidity, , ) = nftManager.mint(mintParams);
// DİKKAT: Klasik Flashbots bundle’da bu sözleşme
// burada yürütmeyi tamamlar ve çekim ikinci işlemde yapılır.
// Ya da özel bir router kullanıyorsak, hepsi tek adımda olabilir.
}
// Kârı anında toplamak için fonksiyon
function withdrawJit(uint256 tokenId, uint128 liquidity) external {
nftManager.decreaseLiquidity(tokenId, liquidity, 0, 0, block.timestamp);
nftManager.collect(tokenId, msg.sender, type(uint128).max, type(uint128).max);
}
}
3. Flashbots Bundles: Gerçekliği Birleştirmek
JIT botunun işlemleri kurbanın işlemini çevrelemelidir. Bunun için Bundles mekanizması kullanılır.
Bot, Flashbots’a (veya BeaverBuild, Titan gibi diğer MEV relay’lerine) bir işlem dizisi gönderir:
- [Tx_Mint] — Likidite ekleme işleminiz.
- [Tx_Target] — Mempool’dan kullanıcı işlemi (ele geçirdiğiniz).
- [Tx_Burn] — Çekim işleminiz.
Az bilinen detay: Gaz tasarrufu için, ileri seviye botlar aynı blokta Burn yapmayabilir, eğer bir sonraki blokta fiyat tick dışına çıkmayacaksa. Ama bu “pasif LP” riski oluşturur. Gerçek JIT yırtıcı pozisyonu her zaman $N$ blokta kapatır.
4. Off-chain Bot Mantığı (Off-chain Engine)
Rust botu sonsuz bir döngüde çalışır:
- Mempool stream: newPendingTransactions dinler.
- Simülasyon: Her büyük işlem için bot, eth_call veya revm (Rust EVM) ile “sanal yürütme” yapar ve ne kadar ücret kazanacağını tahmin eder.
- Bundle oluşturma: kâr > 0 ise paket hazırlanır.
- Bidding: Bot coinbase.transfer() ekler — validator için rüşvet.
İçeriden bilgi: 2026’da validator’a verilen tip bot kârının %99’una ulaşabilir. Botlar kalan %1 net kâr için yarışır, çünkü milyonlarca dolarlık hacimlerde %1 bile büyük paradır.
5. Pratik İpucu: multicall kullanımı
Maksimum verimlilik için kontratınızda multicall mantığını kullanın. Bu, kendi fonlarınızı kullanıyorsanız approve, mint, decreaseLiquidity ve collect işlemlerini tek bir işlemde gerçekleştirmenizi sağlar, Flash Loans kullanmıyorsanız. Tekrarlanan çağrılarda yaklaşık 40–60k gaz tasarrufu sağlar.
Makalenin Özeti
JIT botunun mimarisi, akıllı sözleşme mühendisliğinin zirvesidir. Sadece saniyelerin bir kesri boyunca var olan “tek kullanımlık” bir likidite oluşturuyorsunuz.
Bir sonraki makalede: “ağır topçuya” geçeceğiz. Kendi milyonlarınız olmadan JIT saldırıları nasıl yapılır? Flash-JIT ve dev havuzlarda %99.9 likiditeyi ele geçirmek için Flash Loans kullanımı ele alınacak.
JIT Likidite Ustalığı: Uniswap'te MEV İçin Tam Kılavuz: 5 Bölümden 3.sü