Ir al contenido principal
BlockchainMar 28, 2026

Deep EVM #12: Huff Avanzado — Ejecución Adaptativa y Computación On-Chain

OS
Open Soft Team

Engineering Team

Más allá de los contratos estáticos

Los contratos que hemos construido hasta ahora son estáticos — su bytecode es inmutable y su lógica es fija. Pero hay un mundo de posibilidades en contratos que adaptan su comportamiento basándose en condiciones on-chain: precios de gas, estado del mempool, o datos de oráculos.

Ejecución condicional basada en gas

Un bot de MEV puede ajustar su estrategia según el precio actual del gas:

#define macro ADAPTIVE_SWAP() = takes(0) returns(0) {
    gasprice                    // [gasPrice]
    0x0BA43B7400 gt            // [gasPrice > 50 gwei?]
    modo_economico jumpi        // Saltar si gas alto
    
    // Gas bajo: ejecutar swap completo con verificaciones
    FULL_SWAP()
    stop
    
    modo_economico:
    // Gas alto: ejecutar swap mínimo sin verificaciones extras
    MINIMAL_SWAP()
    stop
}

Lectura eficiente de estado multi-pool

Para un bot de arbitraje que lee reservas de múltiples pools:

#define macro READ_RESERVES_BATCH() = takes(0) returns(0) {
    // Leer número de pools del calldata
    0x04 calldataload           // [numPools]
    
    // Offset inicial en calldata (después de numPools)
    0x24                        // [offset, numPools]
    
    loop:
    // Verificar si terminamos
    dup2 iszero fin jumpi       // [offset, remaining]
    
    // Leer dirección del pool
    dup1 calldataload           // [poolAddr, offset, remaining]
    
    // STATICCALL a getReserves()
    0x0902f1ac                  // [selector, poolAddr, offset, remaining]
    0xe0 shl                    // [selector<<224, poolAddr, ...]
    0x00 mstore                 // [poolAddr, offset, remaining]
    
    // Preparar staticcall
    0x40                        // retSize (64 bytes: 2 uint112)
    0x00                        // retOffset
    0x04                        // argSize
    0x00                        // argOffset
    dup5                        // pool address
    gas                         // gas
    staticcall                  // [success, poolAddr, offset, remaining]
    
    // Almacenar resultado en memoria para retorno batch
    // ...
    
    // Avanzar
    swap2 0x20 add swap2        // [offset+32, remaining]
    swap1 0x01 swap1 sub swap1  // [offset+32, remaining-1]
    loop jump
    
    fin:
    // Retornar todos los datos leídos
}

Computación de producto constante optimizada

El cálculo de amountOut en un AMM requiere multiplicación y división de enteros grandes:

// amountOut = (amountIn * 997 * reserveOut) / (reserveIn * 1000 + amountIn * 997)
#define macro CONSTANT_PRODUCT() = takes(3) returns(1) {
    // Stack: [amountIn, reserveIn, reserveOut]
    
    // Calcular numerador = amountIn * 997 * reserveOut
    dup1 0x03E5 mul             // [amountIn*997, amountIn, reserveIn, reserveOut]
    dup4 mul                    // [numerador, amountIn, reserveIn, reserveOut]
    
    // Calcular denominador = reserveIn * 1000 + amountIn * 997
    swap2                       // [reserveIn, amountIn, numerador, reserveOut]
    0x03E8 mul                  // [reserveIn*1000, amountIn, numerador, reserveOut]
    swap1 0x03E5 mul            // [amountIn*997, reserveIn*1000, numerador, reserveOut]
    add                         // [denominador, numerador, reserveOut]
    
    // amountOut = numerador / denominador
    swap1 div                   // [amountOut, reserveOut]
    swap1 pop                   // [amountOut]
}

Verificación de overflow en Huff

Sin checks automáticos, debemos verificar manualmente:

#define macro SAFE_MUL() = takes(2) returns(1) {
    // Stack: [a, b]
    dup2 dup2                   // [a, b, a, b]
    mul                         // [a*b, a, b]
    dup1                        // [a*b, a*b, a, b]
    swap2                       // [a, a*b, a*b, b]
    dup1 iszero safe jumpi      // [a, a*b, a*b, b]
    swap1 div                   // [a*b/a, a*b, b]
    dup3 eq                     // [a*b/a == b, a*b, b]
    safe jumpi
    0x00 0x00 revert
    
    safe:
    pop pop                     // [a*b]
}

Patrones de auto-optimización

Caché de rutas frecuentes

Un contrato que almacena las rutas de arbitraje más rentables y las reutiliza:

// Slot 100+: caché de rutas
// Formato: [token0, token1, pool, amountMin]
#define macro CHECK_CACHED_ROUTE() = takes(2) returns(1) {
    // Stack: [token0, token1]
    // Calcular hash de la clave del par
    0x00 mstore
    0x20 mstore
    0x40 0x00 sha3              // [routeKey]
    
    // Buscar en caché
    0x64 add sload              // [cachedPool]
    dup1 iszero                 // [isEmpty, cachedPool]
}

Interacción con contratos proxy

Huff puede implementar el patrón proxy EIP-1967 con overhead mínimo:

#define macro PROXY_DELEGATECALL() = takes(0) returns(0) {
    // Leer la dirección de implementación del slot EIP-1967
    0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc
    sload                       // [impl]
    
    // Copiar todo el calldata a memoria
    calldatasize 0x00 0x00 calldatacopy
    
    // Delegatecall
    0x00                        // retOffset
    calldatasize                // argSize
    0x00                        // argOffset
    dup4                        // impl
    gas                         // gas
    delegatecall                // [success]
    
    // Copiar returndata
    returndatasize 0x00 0x00 returndatacopy
    
    // Retornar o revertir
    iszero error jumpi
    returndatasize 0x00 return
    
    error:
    returndatasize 0x00 revert
}

Conclusión

Huff avanzado va más allá de la simple optimización de gas — permite crear contratos que se adaptan a las condiciones on-chain, leen estado de múltiples fuentes eficientemente, y ejecutan computaciones complejas con overhead mínimo. Estas técnicas son la base de los bots de MEV más competitivos y los protocolos DeFi más eficientes del ecosistema Ethereum.