• Duel está abierto en Robinhood Chain
  • Lanza un duelo dos tokens, tres pools, una transacción
  • La ronda cierra en --:--:--
  • Rondas de cuatro horas la recompra del ganador tiene un límite de precio
  • Liquidez bloqueada para siempre, sin tokens del equipo

Seguridad

Qué tiene valor

  • El ETH y los tokens de los pools, en posiciones que nadie puede retirar. El ETH de un bando solo sale de su pool cuando ese bando se vende en él: por un trader, o por la realineación del hook después de que una operación haya separado los tres precios.
  • Los botes, las comisiones del creador y las del protocolo, que el hook guarda como derechos sobre ETH en el PoolManager de Uniswap V4, contabilizados por separado para cada duelo.

Qué lo protege

  • Liquidez bloqueada. Solo la fábrica puede abrir pools registrados o añadir su liquidez de lanzamiento; la retirada y la donación se revierten.
  • Destinatarios acotados. Un bote solo compra al ganador de su duelo; las comisiones del creador solo van al creador del duelo: la billetera que lo lanzó o una dirección a la que cedió su rol y que lo aceptó. Las comisiones del protocolo van a la tesorería vigente, que el propietario de la fábrica puede cambiar tras 48 horas, también para las comisiones del protocolo ya acumuladas.
  • Poderes acotados de la fábrica. Los tokens no tienen propietario ni función de acuñación, y el hook no se puede actualizar ni pausar. El propietario de la fábrica puede pausar nuevos lanzamientos, proponer términos acotados para duelos futuros o cambiar la tesorería tras el plazo. También puede reducir al instante la parte del protocolo en la comisión de swap de todos los duelos, hasta cero, o volver a subirla, nunca por encima de los términos del duelo: lo que el protocolo no toma va a los botes. El propietario puede renunciar al rol para siempre (renounceOwnership): los términos, la tesorería, la tasa del protocolo y una pausa quedan entonces como están, salvo un cambio ya propuesto, que cualquiera puede aplicar tras su plazo.
  • Liquidación antes del swap. El primer swap tras un cierre liquida la media terminada antes de operar. El techo de una recompra está aproximadamente un 10 % por encima de una referencia guardada con precisión de fracciones de tick: una media exponencial de 30 minutos de los ticks del pool de ETH, recortada al tick actual cuando lo supera, de modo que sigue al precio hacia abajo de inmediato.
  • Rondas solo en ETH. El reparto y la media de la ronda usan los dos pools de ETH. Un cambio A/B que no mueve ningún precio en ETH no cambia ni la señal ni la actividad de una ronda que de otro modo estaría tranquila.
  • Comisiones solo con ejecución completa. Los swaps cobrados por adelantado se revierten si no pueden completar el importe solicitado. El gas de red va aparte.
  • Realineación aislada. Solo se conservan los bucles rentables, limitados por el ETH del pool vendedor. Un intento fallido se revierte y se omite; por falta de gas, se revierte el swap (ArbitrageStarved), para que quien llama no pueda omitirla reteniendo gas. Esto no garantiza que los precios coincidan ni protege de todas las pérdidas de trading.
  • Las mismas reglas en todas las rutas. El hook cobra comisiones, impuestos y quemas tanto si el router es el de Duel como si es otro router V4.

La fábrica empieza con los lanzamientos en pausa. Mientras paused() sea true, solo owner() puede lanzar un duelo; las llamadas de los demás revierten con CreationPaused. El propietario abre los lanzamientos con setPaused(false). Los duelos existentes siguen negociándose.

Lo que muestra el sitio

  • Imágenes solo del sitio. Las páginas muestran las imágenes de un duelo únicamente desde la propia dirección de Duel, y solo imágenes que el sitio ha procesado: un JPEG, PNG o WebP leído primero por su cabecera (1536 × 1536 píxeles y 5 MB como máximo), decodificado en WebAssembly, ajustado a 1024 píxeles y codificado de nuevo como WebP, sin sus metadatos. La política de seguridad de las páginas no les permite cargar imágenes de ningún otro sitio.
  • Códecs aislados. Las imágenes se decodifican en un Worker propio, al que solo llega el sitio y que no guarda nada: ni clave ni almacenamiento. Un fallo en un códec solo alcanzaría la imagen que lee. El sitio comprueba lo que responde ese Worker (un WebP estático del tamaño esperado) antes de guardarlo, y los decodificadores en C empiezan de cero con cada imagen.
  • Duelos lanzados desde el contrato. Sus datos pueden indicar cualquier dirección. El sitio no muestra imágenes https; descarga una imagen IPFS una sola vez, desde una pasarela pública (5 MB y 10 segundos como máximo), la procesa como una subida y muestra su propia copia, o las iniciales del bando.
  • Subidas con límites. El sitio solo acepta imágenes desde sus propias páginas: diez por minuto desde una misma dirección y un número limitado al día. Una imagen que ningún duelo usa se elimina al cabo de un día.

Cómo se comprobó

  • Tests automatizados cubren el comportamiento de los contratos, la app web y el bot de alertas. La cobertura es una métrica de los tests, no una prueba de que todo comportamiento posible sea seguro.
  • Tests sobre un fork ejercitan la integración con los contratos de Uniswap V4 desplegados en Robinhood Chain, incluidos el Universal Router, Permit2 y el V4 Quoter.
  • Tests de regresión conservan los casos encontrados durante la revisión interna, como la contabilidad de comisiones, casos límite del lanzamiento, la liquidación y los pools agotados.
  • Tests de invariantes comprueban la contabilidad a lo largo de secuencias aleatorias de operaciones, liquidaciones y reclamaciones: los derechos sobre ETH deben coincidir con lo adeudado, y no deben quedar tokens intermedios en el hook, la fábrica ni el router. Superar las ejecuciones configuradas no demuestra la seguridad para toda secuencia posible.

La revisión interna encontró y corrigió una ruta de salida exacta que esquivaba el impuesto antisnipe, un reparto que no seguía a un bando comprado en solitario, pools agotados que la referencia de precio de la recompra leía mal y enlaces inseguros en los metadatos de un duelo.

Informar de una vulnerabilidad

Si crees que has encontrado una vulnerabilidad, gracias por dedicar tiempo a informarnos. Escríbenos en privado por Telegram, a @chatwithdivine, con lo que encontraste y, si puedes, cómo reproducirlo, y danos tiempo para investigarlo antes de compartir nada públicamente. Responderemos rápido y te mantendremos informado.

Nunca escribimos primero: confía solo en @chatwithdivine.