Deep EVM #12: Fortgeschrittenes Huff — Adaptive Ausfuehrung und On-Chain-Berechnung
Engineering Team
Von Grundlagen zu Produktionsmustern
Die vorherigen Artikel behandelten Huff-Grundlagen — Makros, Stack-Management, Sprungtabellen. Jetzt wechseln wir zu Produktionsmustern, die aus echten MEV-Bot-Contracts extrahiert wurden. Diese Muster loesen Probleme, die Solidity nicht effizient ausdruecken kann: adaptive Ausfuehrung basierend auf Calldata, Multi-Operator-Autorisierung ohne Storage-Lesevorgaenge und Memory-Layouts, die die Bytecode-Groesse minimieren.
Adaptive Ausfuehrung
Ein MEV-Bot muss unterschiedliche Strategien basierend auf der aktuellen On-Chain-Situation ausfuehren:
#define macro ADAPTIVE_SWAP() = takes(0) returns(0) {
// Token-Balance on-chain pruefen
caller // [this]
0x70a08231 // [balanceOf_sig, this]
0xe0 shl // [balanceOf_sig_shifted, this]
0x00 mstore // Memory[0x00] = Selektor
0x20 mstore // Memory[0x20] = this
// staticcall zu Token
0x20 0x00 0x24 0x1c // [retSize, retOffset, argSize, argOffset]
dup5 // [token, retSize, retOffset, argSize, argOffset]
gas staticcall // [success]
// Wenn Balance > 0: anderen Pfad nehmen
0x00 mload // [balance]
iszero no_balance jumpi
// Balance vorhanden -> direkter Swap
DIRECT_SWAP()
stop
no_balance:
// Keine Balance -> transferFrom zuerst
TRANSFER_THEN_SWAP()
}
Multi-Operator-Autorisierung ohne Storage
Ein MEV-Bot kann mehrere Operator-Adressen haben. Storage-basierte Pruefung kostet 2.100+ Gas. Eine clevere Alternative nutzt den Priority Fee der Transaktion:
#define macro CHECK_AUTH() = takes(0) returns(0) {
// Operator-Index aus Priority Fee extrahieren
// Jeder Operator hat einen einzigartigen Priority Fee zugewiesen
// msg.sender muss ein bekannter Operator sein
caller
0x00 mstore
0x20 0x00 sha3 // Hash des Senders
// Gegen im Bytecode eingebettete Hashes pruefen
dup1 [OPERATOR_1_HASH] eq is_authorized jumpi
dup1 [OPERATOR_2_HASH] eq is_authorized jumpi
0x00 0x00 revert
is_authorized:
pop
}
Dieses Muster spart den gesamten SLOAD-Overhead fuer die Autorisierung.
USDT-Safe-Approve-Muster
USDT (Tether) hat ein bekanntes Problem: approve() revertiert, wenn die aktuelle Genehmigung ungleich Null ist. Die Loesung:
#define macro SAFE_APPROVE() = takes(3) returns(0) {
// Stack: [token, spender, amount]
// Schritt 1: Auf 0 setzen
dup2 // [spender, token, spender, amount]
0x095ea7b3 0xe0 shl // [approve_sig, spender, token, spender, amount]
0x00 mstore // Memory = Selektor
0x04 mstore // Memory = Selektor + spender
0x00 0x24 mstore // Memory = Selektor + spender + 0
0x00 0x00 0x44 0x00 // [retSize, retOff, argSize, argOff]
dup5 // [token]
gas call pop // Ergebnis ignorieren
// Schritt 2: Auf gewuenschten Betrag setzen
dup1 // [amount, token, spender, amount]
0x24 mstore // Memory = Selektor + spender + amount
0x00 0x00 0x44 0x00
dup5
gas call
// Erfolg pruefen
iszero revert_on_fail jumpi
// Stack aufraeumen
pop pop pop
stop
revert_on_fail:
0x00 0x00 revert
}
Memory-Layout-Optimierung
In Produktions-Huff-Code verwenden Sie feste Memory-Adressen statt dynamischer Allokation:
// Festes Memory-Layout fuer einen MEV-Bot:
// 0x00 - 0x3f: Scratch Space (Hashing, temporaere Berechnungen)
// 0x40 - 0x7f: Calldata-Puffer fuer Aufruf 1
// 0x80 - 0xbf: Calldata-Puffer fuer Aufruf 2
// 0xc0 - 0xff: Rueckgabedaten-Puffer
// 0x100 - ...: Frei
// Vorteil: Kein Free Memory Pointer-Overhead
// Vorteil: Vorhersagbare Memory-Erweiterungskosten
WETH-Handling
MEV-Bots interagieren haeufig mit WETH (Wrapped Ether). Effizientes Wrapping und Unwrapping:
#define constant WETH = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2
#define macro WRAP_ETH() = takes(1) returns(0) {
// Stack: [amount]
// WETH.deposit{value: amount}()
0x00 0x00 0x00 0x00 // [retSize, retOff, argSize, argOff]
dup5 // [amount]
[WETH] // [weth, amount, retSize, retOff, argSize, argOff]
gas call // [success]
iszero revert_label jumpi
}
#define macro UNWRAP_ETH() = takes(1) returns(0) {
// Stack: [amount]
// WETH.withdraw(amount)
0x2e1a7d4d 0xe0 shl 0x00 mstore // Selektor
0x04 mstore // Amount
0x00 0x00 0x24 0x00 0x00 [WETH] gas call
iszero revert_label jumpi
}
Fazit
Fortgeschrittenes Huff in der Praxis bedeutet: adaptive Ausfuehrungspfade basierend auf On-Chain-Zustaenden, gasfreie Autorisierung durch Bytecode-eingebettete Hashes, sichere Token-Interaktionen (insbesondere USDT) und durchdachte Memory-Layouts. Diese Muster bilden das Rueckgrat von Produktions-MEV-Bots, wo jede Gas-Einheit zaehlt.