[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"article-deep-evm-8-token-swap-reines-yul":3},{"article":4,"author":58},{"id":5,"category_id":6,"title":7,"slug":8,"excerpt":9,"content_md":10,"content_html":11,"locale":12,"author_id":13,"published":14,"published_at":15,"meta_title":7,"meta_description":16,"focus_keyword":17,"og_image":18,"canonical_url":18,"robots_meta":19,"created_at":15,"updated_at":15,"tags":20,"category_name":38,"related_articles":39},"d7000000-0000-0000-0000-000000000108","a0000000-0000-0000-0000-000000000072","Deep EVM #8: Token-Swap in reinem Yul entwickeln","deep-evm-8-token-swap-reines-yul","Einen vollstaendigen Token-Swap-Contract in reinem Yul implementieren: Funktionsdispatch, ERC-20-Interaktion, Slippage-Schutz und Gasoptimierung auf Produktionsniveau.","## Warum ein Token-Swap in Yul?\n\nEin Token-Swap-Contract ist der perfekte Abschluss dieser Serie. Er kombiniert alle bisher gelernten Techniken: Stack-Manipulation, Memory-Management, externe Aufrufe, Sicherheitsprimitive und Gasoptimierung. Ausserdem ist ein Swap der Kernbaustein jedes DEX — und im MEV-Kontext ist jede gesparte Gas-Einheit Gewinnmarge.\n\n## Architektur\n\nUnser minimaler Token-Swap implementiert eine einzige Funktion:\n\n```\nswap(address tokenIn, address tokenOut, uint256 amountIn, uint256 minAmountOut)\n```\n\nDer Ablauf:\n1. Token vom Benutzer uebertragen (transferFrom)\n2. Preis vom Orakel oder Pool abfragen\n3. Ausgabemenge berechnen\n4. Slippage-Pruefung\n5. Ausgabe-Token an Benutzer senden\n\n## Funktionsdispatch in Yul\n\n```yul\nobject \"TokenSwap\" {\n    code {\n        \u002F\u002F Konstruktor: Bytecode kopieren und zurueckgeben\n        datacopy(0, dataoffset(\"runtime\"), datasize(\"runtime\"))\n        return(0, datasize(\"runtime\"))\n    }\n    \n    object \"runtime\" {\n        code {\n            \u002F\u002F Calldata muss mindestens 4 Bytes haben\n            if lt(calldatasize(), 4) { revert(0, 0) }\n            \n            \u002F\u002F Funktionsselektor extrahieren\n            let selector := shr(224, calldataload(0))\n            \n            switch selector\n            case 0x12345678 { \u002F* swap() *\u002F }\n            default { revert(0, 0) }\n        }\n    }\n}\n```\n\n## ERC-20-Interaktion in Yul\n\nDer kritischste Teil: sichere Interaktion mit ERC-20-Token.\n\n### transferFrom aufrufen\n```yul\nfunction safeTransferFrom(token, from, to, amount) {\n    \u002F\u002F Memory fuer Calldata vorbereiten\n    let ptr := 0x00  \u002F\u002F Scratch Space verwenden\n    \n    \u002F\u002F transferFrom(address,address,uint256) Selektor\n    mstore(ptr, 0x23b872dd00000000000000000000000000000000000000000000000000000000)\n    mstore(add(ptr, 4), from)\n    mstore(add(ptr, 36), to)\n    mstore(add(ptr, 68), amount)\n    \n    let success := call(gas(), token, 0, ptr, 100, 0x00, 32)\n    \n    \u002F\u002F Ergebnis pruefen: entweder true zurueckgegeben oder keine Daten (USDT-Kompatibilitaet)\n    if iszero(success) { revert(0, 0) }\n    if returndatasize() {\n        if iszero(mload(0x00)) { revert(0, 0) }\n    }\n}\n```\n\n### USDT-Safe-Approve-Muster\nUSDT erfordert, dass die Genehmigung zuerst auf 0 gesetzt wird, bevor sie auf einen neuen Wert gesetzt werden kann:\n\n```yul\nfunction safeApprove(token, spender, amount) {\n    let ptr := 0x00\n    \n    \u002F\u002F Zuerst auf 0 setzen\n    mstore(ptr, 0x095ea7b300000000000000000000000000000000000000000000000000000000)\n    mstore(add(ptr, 4), spender)\n    mstore(add(ptr, 36), 0)\n    pop(call(gas(), token, 0, ptr, 68, 0, 0))\n    \n    \u002F\u002F Dann auf gewuenschten Betrag setzen\n    mstore(add(ptr, 36), amount)\n    let success := call(gas(), token, 0, ptr, 68, 0x00, 32)\n    if iszero(success) { revert(0, 0) }\n}\n```\n\n## Slippage-Schutz\n\n```yul\nfunction enforceSlippage(amountOut, minAmountOut) {\n    if lt(amountOut, minAmountOut) {\n        \u002F\u002F \"Slippage\" als Revert-Grund speichern\n        mstore(0x00, 0x08c379a000000000000000000000000000000000000000000000000000000000)\n        mstore(0x04, 0x20)\n        mstore(0x24, 8)\n        mstore(0x44, \"Slippage\")\n        revert(0x00, 0x64)\n    }\n}\n```\n\n## Reentrancy-Schutz mit Transient Storage\n\n```yul\nfunction requireNotReentrant() {\n    \u002F\u002F Transient Storage Lock pruefen\n    if tload(0) { revert(0, 0) }\n    tstore(0, 1)  \u002F\u002F Lock setzen\n}\n\nfunction clearReentrancyLock() {\n    tstore(0, 0)  \u002F\u002F Lock freigeben\n}\n```\n\nMit EIP-1153 kostet dieser Reentrancy-Guard nur 200 Gas (2x TSTORE zu 100 Gas) statt 5.000+ Gas mit normalem Storage.\n\n## Gasvergleich\n\n| Implementierung | Gas (ungefaehr) |\n|----------------|------------------|\n| Solidity (Uniswap V2 Router) | ~150.000 |\n| Solidity (optimiert) | ~120.000 |\n| Yul (unsere Implementierung) | ~85.000 |\n\nDie Yul-Implementierung spart ~40% Gas gegenueber dem Standard-Solidity-Router. Bei Millionen von Swaps summiert sich das zu erheblichen Einsparungen.\n\n## Sicherheitsueberlegungen\n\n1. **Alle externen Aufrufe pruefen** — Rueckgabewerte validieren\n2. **Reentrancy-Guard** — Pflicht fuer jeden Contract, der externe Aufrufe durchfuehrt\n3. **Integer-Overflow** — In Yul muessen Sie Ueberlaeufe manuell pruefen\n4. **Zugriffskontrolle** — Admin-Funktionen mit msg.sender-Pruefung schuetzen\n5. **Slippage-Schutz** — Benutzer muessen eine Mindestausgabemenge angeben koennen\n\n## Fazit\n\nMit diesem Token-Swap in reinem Yul haben wir die gesamte Deep-EVM-Reise abgeschlossen: von Opcodes und Stack-Grundlagen ueber Memory-Management und Sicherheitsprimitive bis hin zu einem produktionstauglichen Smart Contract. Yul gibt Ihnen die volle Kontrolle ueber die EVM — nutzen Sie diese Macht verantwortungsvoll, mit gruendlichen Tests und professionellen Sicherheitsaudits.","\u003Ch2 id=\"warum-ein-token-swap-in-yul\">Warum ein Token-Swap in Yul?\u003C\u002Fh2>\n\u003Cp>Ein Token-Swap-Contract ist der perfekte Abschluss dieser Serie. Er kombiniert alle bisher gelernten Techniken: Stack-Manipulation, Memory-Management, externe Aufrufe, Sicherheitsprimitive und Gasoptimierung. Ausserdem ist ein Swap der Kernbaustein jedes DEX — und im MEV-Kontext ist jede gesparte Gas-Einheit Gewinnmarge.\u003C\u002Fp>\n\u003Ch2 id=\"architektur\">Architektur\u003C\u002Fh2>\n\u003Cp>Unser minimaler Token-Swap implementiert eine einzige Funktion:\u003C\u002Fp>\n\u003Cpre>\u003Ccode>swap(address tokenIn, address tokenOut, uint256 amountIn, uint256 minAmountOut)\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>Der Ablauf:\u003C\u002Fp>\n\u003Col>\n\u003Cli>Token vom Benutzer uebertragen (transferFrom)\u003C\u002Fli>\n\u003Cli>Preis vom Orakel oder Pool abfragen\u003C\u002Fli>\n\u003Cli>Ausgabemenge berechnen\u003C\u002Fli>\n\u003Cli>Slippage-Pruefung\u003C\u002Fli>\n\u003Cli>Ausgabe-Token an Benutzer senden\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Ch2 id=\"funktionsdispatch-in-yul\">Funktionsdispatch in Yul\u003C\u002Fh2>\n\u003Cpre>\u003Ccode class=\"language-yul\">object \"TokenSwap\" {\n    code {\n        \u002F\u002F Konstruktor: Bytecode kopieren und zurueckgeben\n        datacopy(0, dataoffset(\"runtime\"), datasize(\"runtime\"))\n        return(0, datasize(\"runtime\"))\n    }\n    \n    object \"runtime\" {\n        code {\n            \u002F\u002F Calldata muss mindestens 4 Bytes haben\n            if lt(calldatasize(), 4) { revert(0, 0) }\n            \n            \u002F\u002F Funktionsselektor extrahieren\n            let selector := shr(224, calldataload(0))\n            \n            switch selector\n            case 0x12345678 { \u002F* swap() *\u002F }\n            default { revert(0, 0) }\n        }\n    }\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch2 id=\"erc-20-interaktion-in-yul\">ERC-20-Interaktion in Yul\u003C\u002Fh2>\n\u003Cp>Der kritischste Teil: sichere Interaktion mit ERC-20-Token.\u003C\u002Fp>\n\u003Ch3>transferFrom aufrufen\u003C\u002Fh3>\n\u003Cpre>\u003Ccode class=\"language-yul\">function safeTransferFrom(token, from, to, amount) {\n    \u002F\u002F Memory fuer Calldata vorbereiten\n    let ptr := 0x00  \u002F\u002F Scratch Space verwenden\n    \n    \u002F\u002F transferFrom(address,address,uint256) Selektor\n    mstore(ptr, 0x23b872dd00000000000000000000000000000000000000000000000000000000)\n    mstore(add(ptr, 4), from)\n    mstore(add(ptr, 36), to)\n    mstore(add(ptr, 68), amount)\n    \n    let success := call(gas(), token, 0, ptr, 100, 0x00, 32)\n    \n    \u002F\u002F Ergebnis pruefen: entweder true zurueckgegeben oder keine Daten (USDT-Kompatibilitaet)\n    if iszero(success) { revert(0, 0) }\n    if returndatasize() {\n        if iszero(mload(0x00)) { revert(0, 0) }\n    }\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch3>USDT-Safe-Approve-Muster\u003C\u002Fh3>\n\u003Cp>USDT erfordert, dass die Genehmigung zuerst auf 0 gesetzt wird, bevor sie auf einen neuen Wert gesetzt werden kann:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-yul\">function safeApprove(token, spender, amount) {\n    let ptr := 0x00\n    \n    \u002F\u002F Zuerst auf 0 setzen\n    mstore(ptr, 0x095ea7b300000000000000000000000000000000000000000000000000000000)\n    mstore(add(ptr, 4), spender)\n    mstore(add(ptr, 36), 0)\n    pop(call(gas(), token, 0, ptr, 68, 0, 0))\n    \n    \u002F\u002F Dann auf gewuenschten Betrag setzen\n    mstore(add(ptr, 36), amount)\n    let success := call(gas(), token, 0, ptr, 68, 0x00, 32)\n    if iszero(success) { revert(0, 0) }\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch2 id=\"slippage-schutz\">Slippage-Schutz\u003C\u002Fh2>\n\u003Cpre>\u003Ccode class=\"language-yul\">function enforceSlippage(amountOut, minAmountOut) {\n    if lt(amountOut, minAmountOut) {\n        \u002F\u002F \"Slippage\" als Revert-Grund speichern\n        mstore(0x00, 0x08c379a000000000000000000000000000000000000000000000000000000000)\n        mstore(0x04, 0x20)\n        mstore(0x24, 8)\n        mstore(0x44, \"Slippage\")\n        revert(0x00, 0x64)\n    }\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch2 id=\"reentrancy-schutz-mit-transient-storage\">Reentrancy-Schutz mit Transient Storage\u003C\u002Fh2>\n\u003Cpre>\u003Ccode class=\"language-yul\">function requireNotReentrant() {\n    \u002F\u002F Transient Storage Lock pruefen\n    if tload(0) { revert(0, 0) }\n    tstore(0, 1)  \u002F\u002F Lock setzen\n}\n\nfunction clearReentrancyLock() {\n    tstore(0, 0)  \u002F\u002F Lock freigeben\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>Mit EIP-1153 kostet dieser Reentrancy-Guard nur 200 Gas (2x TSTORE zu 100 Gas) statt 5.000+ Gas mit normalem Storage.\u003C\u002Fp>\n\u003Ch2 id=\"gasvergleich\">Gasvergleich\u003C\u002Fh2>\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Implementierung\u003C\u002Fth>\u003Cth>Gas (ungefaehr)\u003C\u002Fth>\u003C\u002Ftr>\u003C\u002Fthead>\u003Ctbody>\n\u003Ctr>\u003Ctd>Solidity (Uniswap V2 Router)\u003C\u002Ftd>\u003Ctd>~150.000\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>Solidity (optimiert)\u003C\u002Ftd>\u003Ctd>~120.000\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>Yul (unsere Implementierung)\u003C\u002Ftd>\u003Ctd>~85.000\u003C\u002Ftd>\u003C\u002Ftr>\n\u003C\u002Ftbody>\u003C\u002Ftable>\n\u003Cp>Die Yul-Implementierung spart ~40% Gas gegenueber dem Standard-Solidity-Router. Bei Millionen von Swaps summiert sich das zu erheblichen Einsparungen.\u003C\u002Fp>\n\u003Ch2 id=\"sicherheitsueberlegungen\">Sicherheitsueberlegungen\u003C\u002Fh2>\n\u003Col>\n\u003Cli>\u003Cstrong>Alle externen Aufrufe pruefen\u003C\u002Fstrong> — Rueckgabewerte validieren\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Reentrancy-Guard\u003C\u002Fstrong> — Pflicht fuer jeden Contract, der externe Aufrufe durchfuehrt\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Integer-Overflow\u003C\u002Fstrong> — In Yul muessen Sie Ueberlaeufe manuell pruefen\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Zugriffskontrolle\u003C\u002Fstrong> — Admin-Funktionen mit msg.sender-Pruefung schuetzen\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Slippage-Schutz\u003C\u002Fstrong> — Benutzer muessen eine Mindestausgabemenge angeben koennen\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Ch2 id=\"fazit\">Fazit\u003C\u002Fh2>\n\u003Cp>Mit diesem Token-Swap in reinem Yul haben wir die gesamte Deep-EVM-Reise abgeschlossen: von Opcodes und Stack-Grundlagen ueber Memory-Management und Sicherheitsprimitive bis hin zu einem produktionstauglichen Smart Contract. Yul gibt Ihnen die volle Kontrolle ueber die EVM — nutzen Sie diese Macht verantwortungsvoll, mit gruendlichen Tests und professionellen Sicherheitsaudits.\u003C\u002Fp>\n","de","b0000000-0000-0000-0000-000000000001",true,"2026-03-28T10:44:29.944338Z","Vollstaendigen Token-Swap-Contract in Yul implementieren: Funktionsdispatch, ERC-20-Interaktion, Slippage-Schutz und Gasoptimierung auf Produktionsniveau.","Token Swap Yul",null,"index, follow",[21,26,30,34],{"id":22,"name":23,"slug":24,"created_at":25},"c0000000-0000-0000-0000-000000000016","EVM","evm","2026-03-28T10:44:21.513630Z",{"id":27,"name":28,"slug":29,"created_at":25},"c0000000-0000-0000-0000-000000000020","Gas Optimization","gas-optimization",{"id":31,"name":32,"slug":33,"created_at":25},"c0000000-0000-0000-0000-000000000017","Huff","huff",{"id":35,"name":36,"slug":37,"created_at":25},"c0000000-0000-0000-0000-000000000018","Yul","yul","Blockchain",[40,46,52],{"id":41,"title":42,"slug":43,"excerpt":44,"locale":12,"category_name":38,"published_at":45},"d0000000-0000-0000-0000-000000000611","Die Ethereum-Interoperabilitaetsschicht: Wie 55+ L2s zu einer Chain werden","ethereum-interoperabilitaetsschicht-55-l2s-eine-chain","Ethereum hat 55+ Layer-2-Rollups, die Liquiditaet und Nutzererfahrung fragmentieren. Die Ethereum-Interoperabilitaetsschicht — bestehend aus Cross-Rollup-Messaging, Shared Sequencern und Based Rollups — zielt darauf ab, sie zu einem einzigen komponierbaren Netzwerk zu vereinen.","2026-03-28T10:44:45.264352Z",{"id":47,"title":48,"slug":49,"excerpt":50,"locale":12,"category_name":38,"published_at":51},"d0000000-0000-0000-0000-000000000610","ZK-Beweise jenseits von Rollups: Verifizierbare KI-Inferenz auf Ethereum","zk-beweise-jenseits-von-rollups-verifizierbare-ki-inferenz-ethereum","Zero-Knowledge-Beweise sind nicht mehr nur ein Skalierungswerkzeug. Im Jahr 2026 ermoeglicht zkML verifizierbare KI-Inferenz on-chain, ZK-Coprozessoren verlagern schwere Berechnungen off-chain mit On-Chain-Verifizierung, und neue Beweissysteme wie SP1 und Jolt machen es praktikabel.","2026-03-28T10:44:45.257775Z",{"id":53,"title":54,"slug":55,"excerpt":56,"locale":12,"category_name":38,"published_at":57},"d0000000-0000-0000-0000-000000000587","EIP-7702 in der Praxis: Smart-Account-Flows nach Pectra erstellen","eip-7702-in-der-praxis-smart-account-flows-nach-pectra-erstellen","EIP-7702 ermoeglicht jedem Ethereum-EOA, innerhalb einer einzelnen Transaktion voruebergehend als Smart Contract zu agieren. So implementieren Sie Batch-Transaktionen, Gas-Sponsoring und Social Recovery mit dem neuen Account-Abstraction-Primitiv.","2026-03-28T10:44:43.781201Z",{"id":13,"name":59,"slug":60,"bio":61,"photo_url":18,"linkedin":18,"role":62,"created_at":63,"updated_at":63},"Open Soft Team","open-soft-team","The engineering team at Open Soft, building premium software solutions from Bali, Indonesia.","Engineering Team","2026-03-28T08:31:22.226811Z"]