← Alle Insights

Flash Loans & Arbitrage: Atomic Trades als Strategie.

Ein unbesicherter Kredit über 50 Millionen USD, der innerhalb einer einzigen Transaktion aufgenommen, eingesetzt und zurückgezahlt wird — auf jedem Bankenmarkt der Welt undenkbar. In Ethereum ist es die Standardarchitektur seit Aave V2. Flash Loans haben DeFi-Arbitrage demokratisiert und gleichzeitig die Angriffsfläche für Exploits vergrößert. Wer die Mechanik versteht, sieht beide Seiten klarer.

Das Atomic-Loan-Prinzip.

Ein Flash Loan ist ein Kredit innerhalb einer Transaktion. Die Bedingung: Am Ende der Transaktion muss der geliehene Betrag plus Fee zurückgezahlt sein. Andernfalls wird die gesamte Transaktion zurückgerollt — als hätte sie nie stattgefunden. Diese Atomizität ist nur möglich, weil die Ethereum Virtual Machine deterministisch und transaktional ist. Der Kreditgeber trägt kein Default-Risiko, weil ein Default mathematisch nicht möglich ist.

Die wichtigsten Anbieter sind Aave (0,05 % Fee), Balancer (0 % Fee, aber begrenzte Liquidität pro Asset), dYdX (historisch wichtig) und Uniswap V3 selbst über Flash Swaps. Die Auswahl hängt von der benötigten Liquidität und dem Asset ab.

Klassische Arbitrage-Setups.

Die naheliegendste Anwendung: Preisdifferenz-Arbitrage zwischen DEXes. Wenn ETH auf SushiSwap 3.000 USDC kostet und auf Uniswap V3 3.005 USDC, leihen Sie etwa 1.000 ETH bei Aave, kaufen sie auf SushiSwap, verkaufen sie auf Uniswap, zahlen den Kredit zurück und behalten die Differenz minus Gas und Fees.

In der Praxis ist diese einfache Form längst von hochoptimierten Bots besetzt. Was heute noch lohnt:

Eine Aave-Flash-Loan-Implementierung.

Hier eine vereinfachte Solidity-Variante eines Arbitrage-Contracts, der einen Flash Loan bei Aave aufnimmt und zwei DEXes routet:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

import "@aave/core-v3/contracts/flashloan/base/FlashLoanSimpleReceiverBase.sol";
import "@aave/core-v3/contracts/interfaces/IPoolAddressesProvider.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";

interface IRouter {
    function swapExactTokensForTokens(
        uint256 amountIn,
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external returns (uint256[] memory amounts);
}

contract FlashArb is FlashLoanSimpleReceiverBase {
    address public owner;
    IRouter public routerA;
    IRouter public routerB;

    constructor(address provider, address _routerA, address _routerB)
        FlashLoanSimpleReceiverBase(IPoolAddressesProvider(provider))
    {
        owner = msg.sender;
        routerA = IRouter(_routerA);
        routerB = IRouter(_routerB);
    }

    function executeOperation(
        address asset,
        uint256 amount,
        uint256 premium,
        address,
        bytes calldata params
    ) external override returns (bool) {
        (address tokenOut, uint256 minProfit) = abi.decode(params, (address, uint256));

        // Hop 1: asset -> tokenOut auf Router A
        IERC20(asset).approve(address(routerA), amount);
        address[] memory path1 = new address[](2);
        path1[0] = asset;
        path1[1] = tokenOut;
        uint256[] memory out1 = routerA.swapExactTokensForTokens(
            amount, 0, path1, address(this), block.timestamp
        );

        // Hop 2: tokenOut -> asset auf Router B
        uint256 received = out1[1];
        IERC20(tokenOut).approve(address(routerB), received);
        address[] memory path2 = new address[](2);
        path2[0] = tokenOut;
        path2[1] = asset;
        uint256[] memory out2 = routerB.swapExactTokensForTokens(
            received, amount + premium + minProfit, path2, address(this), block.timestamp
        );

        // Rückzahlung
        uint256 totalDebt = amount + premium;
        IERC20(asset).approve(address(POOL), totalDebt);
        return true;
    }

    function initiate(address asset, uint256 amount, address tokenOut, uint256 minProfit) external {
        require(msg.sender == owner, "not owner");
        bytes memory data = abi.encode(tokenOut, minProfit);
        POOL.flashLoanSimple(address(this), asset, amount, data, 0);
    }
}

Der Knackpunkt liegt in der minProfit-Klausel auf dem zweiten Swap. Wenn der Markt zwischen Mempool-Sichtung und Inclusion gegen Sie läuft, reverted die Transaktion und Sie zahlen nur Gas — keinen tatsächlichen Verlust auf der Arbitrage. Das ist das Schöne an Atomic Loans: Der Worst Case sind die Transaktionskosten.

Off-Chain-Pipeline für Opportunity Detection.

Der Smart Contract ist nur die Hälfte der Geschichte. Profitabel wird das Setup erst durch ein Off-Chain-System, das in Echtzeit Pool-Reserves überwacht und potenzielle Arbitrage-Opportunities identifiziert. Mein Stack:

import asyncio
from web3 import AsyncWeb3
from web3.providers.async_rpc import AsyncHTTPProvider

WS_URL = "wss://eth-mainnet.example/ws"
POOLS = {
    "uniswap_eth_usdc": "0x88e6...",
    "sushi_eth_usdc": "0x397f...",
}

async def fetch_reserves(w3, pool_addr):
    # vereinfacht: Slot 0 für V3, getReserves für V2
    code = await w3.eth.get_code(pool_addr)
    # ... ABI-Auswahl je nach Pool-Typ
    pass

async def detect_arb(w3, threshold_bps=15):
    while True:
        prices = {}
        for name, addr in POOLS.items():
            r = await fetch_reserves(w3, addr)
            prices[name] = r
        # Spread berechnen
        a = prices["uniswap_eth_usdc"]
        b = prices["sushi_eth_usdc"]
        spread_bps = abs(a - b) / min(a, b) * 10_000
        if spread_bps > threshold_bps:
            print(f"Opportunity: {spread_bps:.1f} bps")
            # Profit-Simulation, dann Transaction senden
        await asyncio.sleep(0.2)

async def main():
    w3 = AsyncWeb3(AsyncHTTPProvider(WS_URL))
    await detect_arb(w3)

asyncio.run(main())

In der Praxis ist das Polling viel zu langsam. Echte Bots abonnieren den Mempool über spezialisierte Anbieter (Bloxroute, Eden, Flashbots Protect), simulieren Transaktionen lokal mit Anvil oder Foundry-Forks und senden Bundles direkt an Block-Builder, um Frontrunning zu vermeiden.

MEV und der Wettlauf um Block-Inklusion.

Klassische Arbitrage auf Ethereum L1 ist heute fast vollständig MEV-Searcher-Territorium. Wer in den Mempool sendet, kompetiert gegen Bots, die Latenzen unter zehn Millisekunden haben, eigene Builder-Beziehungen unterhalten und ihre Bots in Rust oder spezialisiertem Yul schreiben. Für Privatanwender ist L1-Arbitrage nicht mehr realistisch.

Wo es noch Raum gibt: L2-Ketten wie Arbitrum, Base, Optimism haben niedrigere Konkurrenzdichte und niedrigere Gas-Kosten. Cross-Chain-Arbitrage zwischen L1 und L2 ist über Bridges möglich, aber nicht atomic — das Risiko steigt deutlich. Liquidations-Bots auf weniger frequentierten Lending-Protokollen bieten ebenfalls noch Edge.

Risikoseite und ethische Fragen.

Flash Loans waren das technische Vehikel für viele der größten DeFi-Hacks: bZx, Harvest, Cream, Beanstalk. Das Muster ist meist gleich: Ein Angreifer leiht sich Hunderte Millionen Dollar, manipuliert kurzzeitig den Preis eines schlecht abgesicherten Oracles, extrahiert Wert aus einem abhängigen Protokoll, zahlt den Loan zurück.

Aus Risiko-Perspektive bedeutet das: Wenn Sie ein Protokoll bauen oder benutzen, das On-Chain-Preise als Oracle einsetzt, sind Flash-Loan-Angriffe ein konkretes Bedrohungsmodell. Time-Weighted Average Prices (TWAP), Chainlink-Feeds und Multi-Oracle-Setups sind die Standard-Mitigations. Wer als Trader Flash Loans nutzt, ist auf der anderen Seite — aber sollte die Implikationen für die Pools, in denen er liquidiert, kennen.

Wann sich Flash Loans für Privatanleger lohnen.

Ehrlich gesagt: selten. Die Standard-Arbitrage ist abgegrast. Was bleibt:

Als reiner Ertrags-Hebel sind Flash Loans heute eher Werkzeug für Spezialisten als für Endanwender. Die Kenntnis der Mechanik ist trotzdem wertvoll — vor allem für jeden, der DeFi-Protokolle integriert oder absichert.

Sie evaluieren ein DeFi-Protokoll oder bauen einen eigenen Trading-Bot? Erstgespräch buchen — wir prüfen Architektur, Risiken und Profitabilität.