Registro de decisiones
El registro canónico es doc/DECISIONS.md. Esta página resume los puntos de inflexión.
2026-08-25 — Revisión de seguridad interna
Un hallazgo de severidad alta: las ejecuciones parciales dejaban ETH y USDC atrapados en los routers, gravados en su totalidad. Se corrigió rechazando las ejecuciones parciales en lugar de gestionarlas.
2026-08-27 — La comisión pasa del 4 % al 5 %
La parte del creador se duplica, del 1 % al 2 %. Esquema de $STOCKFUN: de 2 / 1,5 / 0,5
a 2 / 2,5 / 0,5. La parte de la tesorería se queda en el 2 %, y esa es la cifra que nunca
se mueve.
Consecuencia aceptada: la ida y vuelta pasa del 7,84 % al 9,75 %. Desde el 2026-10-05, la tasa y su reparto son ajustes del owner, con estos valores por defecto.
2026-08-27 — El buyback del creador
Levanta la exclusión «sin salida» en un único camino, que siempre termina en el burn. El Treasury Ratio puede ahora bajar a discreción de un creador. Eliminado el 2026-09-27, sustituido por el airdrop.
2026-08-29 — Modo de emergencia
El owner puede mover los activos de una tesorería tras 48 horas públicas. Sustituye a la promesa «nadie puede tocar la tesorería». El protocolo deja de describirse como trustless. Inmediato desde el 2026-10-05: el plazo ya no existe.
2026-09-11 — El rail pasa a Robinhood Chain
El bloqueo era la elegibilidad del contrato de un vault ante un emisor de mint primario, nunca documentada públicamente. Los pools secundarios de Robinhood Chain no la exigen. Precio pagado: una dependencia cross-chain aceptada.
2026-09-12 — Desaparece la bonding curve
Sustituida por dos posiciones single-sided de Uniswap v4, bloqueadas desde la creación. Sin graduación, sin migración, sin comisión de graduación.
La FDV de lanzamiento no cambia: sigue siendo aquella con la que abría la curva, 3,409 ETH. Un primer ticket de 2 ETH se lleva el 36,06 % del supply frente al 36,99 % de antes: el lanzamiento se comporta como antes, con menos de un punto de diferencia.
Descartado por el camino: un lanzamiento a 5 000 $ con un techo de 50 000 $, que solo daba 3,25 ETH de profundidad y permitía al primer comprador de 2 ETH llevarse el 57 % del supply. Y la idea de que un techo más bajo calmaría el mercado: cede antes el relevo a la banda sin límite, que es poco profunda, y duplica la FDV alcanzada tras gastar 50 ETH.
2026-09-12 — Anti-snipe de tres bloques
Solo el creador en el bloque 1, 99 % al buyback en el bloque 2 salvo el creador y la whitelist del owner, normal a partir de ahí. Sustituido el 2026-09-28 por el anti-snipe decreciente.
Adoptado con pleno conocimiento de la objeción: un impuesto del 99 % solo produce algo si alguien pierde su dinero, y cerrar el bloque 2 habría tenido el mismo efecto disuasorio sin ninguna víctima. La whitelist está a nivel de protocolo y no de creador precisamente para que no pueda convertirse en una ventaja para insiders mercado por mercado.
2026-09-12 — Sin burn en las ventas
Se descartó la idea de enviar al burn el 10 % de los tokens entrantes en cada venta. Pagado por el vendedor, llevaba la ida y vuelta al 18,78 %. Pagado por el LP, hacía falsa la afirmación «liquidez bloqueada para siempre» y daba a cualquiera una palanca de aproximadamente 1:1 para quemar el float e inflar su propia bag.
2026-09-27 — El airdrop sustituye al buyback del creador
La tesorería de un mercado tiene ahora un solo uso: el 100 % de las acciones que compra se
distribuyen por airdrop a los holders de su token, a prorrata, en especie, en
Robinhood Chain. El buyback del creador se elimina, y con él el camino de vuelta del
bridge. El buyback y burn de $STOCKFUN se mantiene.
Descartado por el camino: mantener el buyback del creador, y un reparto que conservaba el 60 % en la tesorería y distribuía el 40 %, el antiguo plan V2. Consecuencias aceptadas: ya ninguna tesorería acumula, el Treasury Ratio pierde su sentido, y el eslogan y el tagline deben revisarse. El mecanismo se codificó el 2026-10-04: consulta El airdrop.
2026-09-27 — Un ciclo cada 24 horas
La cadencia del airdrop se fija el mismo día. Una vez cada 24 horas, para cada mercado cuya tesorería haya acumulado al menos 0,1 ETH, el keeper convierte, envía a través del bridge, compra las acciones y luego las distribuye por airdrop. Por debajo del umbral, ese día no ocurre nada; el ETH espera.
Las acciones solo se pueden comprar mientras la bolsa estadounidense está abierta, así que no hay ciclo los fines de semana ni los festivos de la NYSE. En el código del keeper, hasta el 2026-10-06 la conversión se hacía durante la sesión, en la primera pasada en que el vault contenía el umbral; desde entonces sigue esta decisión, una vez por ventana, en la primera pasada del keeper después de que se cierre la ventana y solo si el vault contiene el umbral en ese momento (consulta 2026-10-06 más abajo); desde el sexto bucle de auditoría, el mismo día, el USDC que contiene un vault sigue también esta cadencia. El envío al airdrop se hace una vez por ventana desde el 2026-10-05, después de la sesión del día: consulta El keeper.
2026-09-27 — Fondos atascados y medición de las tenencias
Los restos de un ciclo interrumpido se terminan de procesar en el siguiente ciclo, se alcance o no el umbral. El owner puede mover sin aviso previo los fondos del airdrop atascados durante 24 horas en un vault espejo: es la única excepción al plazo público de 48 horas, elegida a sabiendas. Las tenencias se miden como el saldo promedio durante las 24 horas anteriores al ciclo, lunes incluidos. La ventana de los fondos atascados pasó a 48 horas el 2026-09-28, y la regla se cerró el 2026-10-05, sin haberse codificado.
2026-09-28 — Anti-snipe decreciente
80 % en el bloque de apertura, menos 8 puntos por bloque, 5 % a partir del bloque 11, en
compras y ventas. El excedente va a la tesorería del mercado, o a las comisiones
reclamables del equipo en $STOCKFUN. Exentas: la compra de lanzamiento del creador y una
whitelist fijada por el creador en la transacción de creación, pública, inmutable y con un
tope de 20 direcciones; en $STOCKFUN, la fija el owner en el lanzamiento. Desde el
2026-10-05, estas cifras son ajustes del owner, con los valores de arriba por defecto.
Descartado por el camino: marcar las wallets que compran en los primeros bloques y gravar sus ventas posteriores, incluso tras una transferencia. Un pool v4 no ve la wallet, un impuesto cobrado por el token hace fallar la venta, y bloquear las wallets marcadas fuera del router de StockFun haría que los escáneres señalaran el token. Consecuencia aceptada: la whitelist pasa del protocolo al creador, algo que la decisión del 2026-09-12 había descartado para evitar una ventaja para insiders.
2026-09-28 — Fondos del airdrop atascados: 48 horas
El owner puede mover sin aviso previo los fondos del airdrop que hayan permanecido 48 horas en un vault espejo, en lugar de 24. Con 24 horas, la ventana igualaba el periodo del ciclo, así que unos restos ordinarios, aplazados un solo ciclo, pasaban a poder moverse sin aviso previo; con 48 horas, ya no. Los fondos de un fallo del viernes siguen pudiendo moverse el domingo, antes del ciclo del lunes. Decidido el mismo día: el reloj nunca se detiene, ni durante una pausa ni los fines de semana. Regla cerrada el 2026-10-05, sin haberse codificado: la transferencia de emergencia es inmediata en todas partes.
2026-09-28 — Tenencias registradas onchain
El token de cada mercado registra las tenencias de cada wallet a lo largo del tiempo, así que un contrato calcula el promedio de las 24 horas anteriores a un ciclo y cada parte; el keeper nunca las proporciona. Descartado: un reparto calculado offchain por el keeper y publicado con un plazo de impugnación. Costo aceptado: cada transferencia del token paga gas adicional.
2026-09-28 — El airdrop en acciones wrapped, en Ethereum
Las acciones compradas en Robinhood Chain se bloquean allí en adaptadores LayerZero desplegados por StockFun, uno por acción, y se envían a Ethereum como acciones wrapped. La distribución tiene lugar en Ethereum, donde viven el token y sus tenencias, y cada holder reclama su parte a su cargo. Consecuencias aceptadas: las acciones wrapped solo valen lo que valgan las acciones bloqueadas y la configuración de LayerZero, no tienen mercado en Ethereum, y una congelación de los Stock Tokens por parte de su emisor inmovilizaría las acciones bloqueadas. Decidido el mismo día: la configuración de LayerZero de los adaptadores queda en manos del owner, sin plazo y sin tope de retiros, como hace Paxos con el USDG. Descartado: una configuración congelada tras el despliegue, y cambios con un aviso previo de 48 horas.
2026-09-28 — El router oficial sigue siendo modificable
El owner puede cambiar el router de swap oficial en cualquier momento, y el hook reconoce la whitelist anti-snipe a través de ese router. Consecuencia aceptada: al designar otro router, el owner puede eximir a cualquiera del anti-snipe.
2026-09-28 — Una comisión de creación de 0,001 ETH
La comisión de creación pasa a 0,001 ETH, fijada en el código, en lugar de unos 3 $: sin feed de precios, sin ajuste por parte del owner. Su valor en dólares sigue ahora el precio del ETH. Ajuste del owner desde el 2026-10-05, 0,001 ETH por defecto.
2026-09-28 — El PoolManager fuera del registro de tenencias
El token no registra el PoolManager de Uniswap, una de las partes de cada swap, que
contiene los tokens de todos los pools y nunca recibe un airdrop: su historial se lee como
cero, mientras que el del trader se sigue registrando. Ahorro medido: unos 24 000 de gas
por swap, tanto en compras como en ventas.
2026-09-29 — Sin comisión de LP en los pools de StockFun
Los pools se crean con una comisión de LP de Uniswap nula en lugar del 0,30 %: el impuesto del hook es todo el costo de un trade, un 5 % por sentido y un 9,75 % por una ida y vuelta antes del impacto en el precio. Costo aceptado: la tesorería, el equipo y el creador pierden su parte de las comisiones de LP, y desaparece el burn de la parte en tokens de esas comisiones. Desde el 2026-10-05, la comisión de LP es un ajuste de lanzamiento, nula por defecto; cada pool conserva la comisión con la que se creó.
2026-10-01 — Correcciones de la auditoría de seguridad del 2026-09-29
Aplicadas el 2026-09-30 y el 2026-10-01, después de revisar cada hallazgo y elegir su corrección. Cada hallazgo corregido tiene tests de regresión que fallan sobre el código auditado.
Solo el lock de liquidez puede añadir liquidez a un pool de StockFun: una posición de terceros operaba contra los swaps gravados sin pagar el impuesto ni el anti-snipe. El nuevo permiso del hook cambió la dirección del hook, que se volvió a minar.
Solo la parte de la tesorería se envía durante un trade. Las partes del equipo y del buyback se acreditan en el hook y se pagan mediante reclamaciones que cualquiera puede llamar, a las wallets actuales de la factory; el escrow ya no existe. El router y el lock ingresan el monto de entrada antes del swap. Hasta entonces, una wallet de comisiones que volvía a llamar a Uniswap podía detener el trading en todos los pools.
Cada etapa de conversión gasta un monto que indica el keeper, así que un vault más grande que su plataforma de negociación convierte por fracciones. El efectivo se reserva por acción del basket a medida que llega, y una acción que el keeper omite conserva su reserva; el vault espejo funciona igual.
Cada token registra a lo largo del tiempo su supply fuera del PoolManager de Uniswap, el
denominador de la parte a prorrata del airdrop. De las tres opciones de la auditoría, esta
cuesta una escritura más por swap; volver a registrar el PoolManager habría costado unos
24 000 de gas por swap. Consecuencia aceptada: las ventanas del airdrop empiezan y terminan
en una hora en punto.
En el rail de Robinhood, un basket rechazado ya no bloquea los demás mercados de un lote, un token remoto admite un solo identificador, una ejecución parcial en v3 hace fallar su ruta, un hub remoto en pausa sigue aplicando los cambios de rol, y los registros canónicos se pagan en el orden en que llegaron.
Medido: una compra a través del router cuesta 113 529 de gas y una venta 137 250, frente a 125 862 y 150 416 antes. Sigue abierto, a la espera de la decisión del owner: la rotación del adaptador del bridge (M-2, y L-8 con él), las atestaciones de Ondo (M-7) y los routers que se aceptan a sí mismos como destinatario (L-4). Desde el 2026-10-05, M-7 y L-4 están corregidos, y M-2 se queda como está por decisión del owner, y L-8 con él.
2026-10-01 — El pipeline de seguridad completa las correcciones
El mismo día, una segunda ronda de auditoría, a cargo de dos auditores independientes, completó varias correcciones. Cada una tiene tests de regresión; ninguna cambia una decisión de diseño ni un parámetro inmutable.
En Robinhood Chain, una ruta v3 se ejecuta pool a pool, y cada pool debe consumir todo su monto de entrada: la comprobación anterior solo veía el primer pool, y una ejecución parcial más adelante dejaba el token intermedio donde cualquiera podía llevárselo. Un ticket canónico de contabilidad paga como máximo tantos registros como añadió a la cola, empezando por los más antiguos, así que una acumulación de registros ya no lo lleva más allá del gas de su ejecución automática; el sweep paga el resto.
Una emergencia ejecutada que deja el efectivo de un vault por debajo de sus reservas las pone todas a cero, en los dos vaults: lo que queda, y todo el efectivo que entra después, se reparte de nuevo según los pesos. Hasta entonces, la puesta a cero solo existía en la lectura, y las antiguas reservas volvían con la siguiente entrada de efectivo.
En cada compra, el keeper retiene n−1 unidades en la última acción de un basket: el
residuo del redondeo va a esa acción, y una transferencia de polvo podía hacer fallar la
compra. También reduce a la mitad una fracción de burn que el pool de $STOCKFUN no puede
ejecutar entera. Cada token registra su primera marca horaria en el despliegue, lo que
solo importaba en un reloj que empieza en la hora 0, como el de una cadena de pruebas. El
router de acciones de Ethereum sincroniza antes de pagar en ETH, y la Lens rechaza una
página vacía.
Medido: el primer swap de un token en cada hora cuesta unos 28 000 a 30 000 de gas más en una transacción propia, no unos 23 000.
A la espera de la decisión del owner, sin decidir: una emergencia sobre el efectivo
registrado del hub remoto, cuyos registros se pagan entonces con el efectivo de otros
mercados (R2H-1); un token de efectivo que rechaza un vault espejo, lo que detiene la cola
canónica y hace fallar los lotes que agrupan ese mercado (R2H-2); el margen de la última
acción del lado de los contratos, que cambia la regla de asignación documentada (R2T-1);
cobrar el impuesto de compra como claims del PoolManager, para que cualquier router
pueda comprar (R2F-1, option b); que la factory despliegue ella misma el vault de
$STOCKFUN (R2F-2); y tres puntos informativos (R2H-4, R2H-6, R2H-7). Una acción que ya
no se puede volver a comprar nunca sigue recibiendo su peso de cada entrada de efectivo:
es intencionado, ya que retirar un tramo cambiaría los pesos fijos del basket. Desde el
2026-10-05, R2H-1 queda cubierto por las herramientas de liquidación de los bucles de
auditoría de ese día más un procedimiento, la puesta en pausa del hub remoto por el owner
antes de la transferencia; R2H-2 queda cerrado por las entregas no bloqueantes del cuarto
bucle; la option b de R2F-1 se descarta, y el impuesto se sigue cobrando como hasta ahora;
y un vault que rechaza ETH ya no detiene su mercado, la detención que describía R2F-2: ver
las entradas del 2026-10-05 más abajo.
2026-10-02 — Todos los módulos upgradeables
Hasta entonces, ningún contrato del protocolo era upgradeable. Todos los módulos salvo los tokens y el lock de liquidez pasan a ser upgradeables por el owner de StockFun, con efecto inmediato: sin timelock. Cada uno es un proxy con upgrades mediante UUPS, y pregunta a su autoridad de upgrade quién puede hacerle un upgrade: la factory en Ethereum, el hub remoto en Robinhood Chain. Los vaults, en las dos cadenas, son un proxy por mercado, con upgrades mercado por mercado. El proxy del hook se mina con los 14 permisos v4, así que una implementación posterior puede usar cualquier callback sin mover la dirección.
Los tokens no llevan ninguna lógica propia: un ERC-20 simple con un supply fijo y un único
setter, setRecorder, para el owner. El registro de tenencias sale de ellos hacia un
nuevo módulo, el registrador de tenencias, al que cada token llama en cada transferencia;
si la llamada falla, la transferencia falla. Desde el 2026-10-05, los tokens también
tienen rescues, para lo que se envía a su propia dirección, y esa llamada bloqueante es
la única excepción deliberada a la regla de aislamiento del fundador (ver más abajo).
El lock de liquidez sigue sin ser upgradeable y gana un modo de cierre: el owner lo anuncia
y, 30 días después, puede recuperar toda la liquidez de cada pool, la de $STOCKFUN
incluida, hacia cualquier dirección. El owner puede cancelarlo; el trading continúa durante
los 30 días, y no se puede lanzar ningún mercado nuevo mientras haya un cierre pendiente.
Existe para el caso de que el proyecto cierre; los 30 días son el aviso previo de los
holders. El deployer de los vaults espejo en Robinhood Chain tampoco es upgradeable: la
dirección de cada vault espejo se deriva de él.
Lo que cambia: un upgrade no espera las 48 horas del modo de emergencia, que se mantiene; las reglas que este libro llama fijas, desde los límites de los vaults hasta el burn y la tasa del 5 %, se cumplen mientras el owner no haga un upgrade del módulo que las lleva; la factory se despliega primero y la conecta el owner, lo que cambia el orden de despliegue. Un swap cuesta unos 27 000 de gas más, medido de forma aislada: una compra 237 190 de gas en lugar de 210 105, una venta 285 031 en lugar de 258 278 —el precio de los proxies en su camino y de la llamada al registrador—. Desde el 2026-10-05, el modo de emergencia tampoco tiene plazo, y los límites de los vaults y la tasa del 5 % son ajustes del owner.
2026-10-04 — El contrato del airdrop
Codificado y probado, no desplegado. AirdropDistributor, un módulo upgradeable en
Ethereum ligado a la factory, distribuye las acciones de cada mercado por ciclo diario. La
ventana de un ciclo se cierra a las 13:00 UTC, antes de la apertura de la bolsa
estadounidense todo el año; sus compras y envíos se hacen en la sesión que sigue. Un ciclo
se abre con su primer envío, o antes, y congela sus cifras: el registrador de tenencias,
la lista de exclusiones vigente al cierre de la ventana y las tenencias elegibles. Dos
caminos lo alimentan, sendToAirdrop en el vault espejo, a través del adaptador LayerZero
de cada acción, y en el vault de Ethereum para el rail local; nada más abona un ciclo.
Resuelto el mismo día: ningún envío por parte del keeper, solo reclama el holder, a su
cargo (TBD 5); ningún tope por wallet, ningún mínimo, ningún vencimiento (TBD 7); una
lista de exclusiones por token, fijada por el owner, 16 direcciones como máximo, con la
dirección de burn siempre y el contrato de vesting en el caso de $STOCKFUN (TBD 8). Un
envío para una ventana sin tenencias elegibles queda apartado para la primera ventana que
las tenga, llame quien llame y cuando sea, mientras, entretanto, la hora del ciclo no
cambie y el registrador de tenencias del token no se sustituya.
Asumido y documentado: el keeper elige cuándo, así que un envío que llega después de las
13:00 UTC siguientes se mide sobre la ventana del día siguiente; mover la hora del ciclo
vuelve a recortar las ventanas aún no abiertas, incluidas las que las acciones apartadas
todavía tienen que revisar; el registrador de tenencias de un token recibe upgrades en el
propio contrato, nunca se sustituye en un token en circulación. Fuera de este cambio: la
regla de las 48 horas para los fondos atascados, los adaptadores de acciones, el paso del
airdrop en el keeper y la pantalla de reclamación de la dapp. Desde el 2026-10-05 ya
no hay contrato de vesting que excluir, la regla de las 48 horas está cerrada, y la hora
del ciclo forma parte de un horario que fija el owner, la duración y la hora de cierre de
las ventanas (setCycleSchedule); un registrador designado en un token en circulación
parte del supply del token fuera del PoolManager (ver la entrada del bucle de auditoría
más abajo).
2026-10-05 — Sin asignación al equipo, un modo de emergencia inmediato, cada cifra un ajuste
Tres decisiones, codificadas y probadas el mismo día, no desplegadas.
Desaparece la asignación al equipo. El contrato de vesting del equipo, TeamVesting, se
elimina, y ningún $STOCKFUN queda reservado para el equipo: todo el supply,
1 000 000 000 de tokens por defecto, va a la posición single-sided bloqueada, igual que
todo el supply de un mercado va a sus dos posiciones. Hasta entonces, el 10 % iba al
contrato de vesting durante 12 meses, y el airdrop excluía ese contrato de los ciclos de
$STOCKFUN; ahora solo se excluye la dirección de burn, junto con, desde el tercer bucle
de auditoría de ese día, el operador del lanzamiento (ver más abajo).
El modo de emergencia pasa a ser inmediato. emergencyTransfer mueve un activo fuera de un
vault, de un hub del bridge o del contrato del airdrop, hacia cualquier dirección, de
inmediato; cada transferencia tiene un identificador secuencial y un evento público. La
programación a 48 horas del 2026-08-29 desaparece, con su ventana de cancelación, y el
plazo no es un parámetro: una emergencia actúa en cuanto el owner la usa, nunca tras una
espera. La sustitución del adaptador del bridge, changeAdapter, también es inmediata,
con las mismas direcciones fijadas. La regla de los fondos del airdrop atascados, decidida
el 2026-09-27 y el 2026-09-28 y nunca codificada, queda cerrada: la transferencia
inmediata la cubre, en cualquier contrato, en cualquier momento.
Cada cifra pasa a ser un ajuste. Las cifras del protocolo son ahora ajustes onchain del owner, en las dos cadenas, con los valores actuales por defecto: el impuesto, su reparto y el anti-snipe; la comisión de creación y los límites de longitud de los textos de un nuevo mercado; la forma de los nuevos mercados, comisión de LP y tick spacing incluidos, y las partes de lo que cobran las posiciones bloqueadas; el umbral de conversión y los límites de precio de los vaults; el horario y los límites del airdrop; los heartbeats de los oráculos; el gas y el slippage del bridge. Cada uno surte efecto de inmediato y rechaza los valores imposibles. Un cambio del impuesto se aplica desde el siguiente swap en todos los pools, incluido uno que siga en sus bloques anti-snipe; un cambio de forma se aplica a los mercados creados después, y cada pool conserva la comisión de LP y el tick spacing con los que se creó.
Se mantiene fijo: el aviso previo de 30 días del modo de cierre, END_DELAY, en el lock,
que no es upgradeable; las unidades y codificaciones, desde el punto básico hasta la hora
del registro de tenencias; y la conexión, desde los feeds de precios hasta los endpoints
del bridge, que solo un upgrade puede apuntar a otro sitio.
Consecuencia aceptada: las cifras que este libro da para el impuesto, el lanzamiento, los vaults y el airdrop son valores por defecto, no garantías; el owner puede cambiar cada una en cualquier momento, sin aviso previo. Medido: leer los ajustes del impuesto le cuesta a un swap unos 1 200 de gas más, en caliente. Consulta Modelo de confianza.
2026-10-05 — Las correcciones del bucle de auditoría
El mismo día, un bucle de revisión de todo el código dio lugar a correcciones en los contratos, cada una con un test de regresión, no desplegadas. Cuatro de ellas cambian el comportamiento.
Tras una transferencia de emergencia, las cuentas se saldan, nunca con cargo a otro mercado. El contrato del airdrop y el hub remoto guardan activos que se deben a varios mercados. Tras una transferencia fuera de cualquiera de los dos, los pagos que dependen de lo que falta esperan —las reclamaciones de esa acción en el airdrop, los pagos del hub remoto en el rail de USDG— hasta que los activos vuelvan o hasta que el owner de StockFun impute la pérdida al ciclo o al mercado que la sufrió; en el rail canónico, el owner da de baja el registro cuyo efectivo se llevó la transferencia antes de que llegue el siguiente depósito. Un ciclo solo admite una baja parcial mientras nadie haya reclamado de él la acción, y cada holder pierde entonces la misma proporción; una vez que algunos holders han cobrado, solo una baja de todo su resto, que pierden los holders que aún no han cobrado. La transferencia en sí sigue siendo inmediata e incondicional. Consulta Modo de emergencia.
Solo el keeper envía a través del bridge. Hasta entonces, cualquiera podía enviar un lote de bridge: un tercero podía colar uno con el mínimo menos estricto del adaptador entre dos trades propios en el pool de Curve, o hacer fallar el lote del keeper pasando antes por el bridge uno de sus vaults.
Solo el keeper y el owner de StockFun despliegan por adelantado un vault espejo en Robinhood Chain. Hasta entonces, cualquiera podía hacerlo, incluso para un mercado que aún no existía, ligado a la conexión de ese día. Un vault desplegado por adelantado toma ahora el router de acciones y el oráculo del hub remoto en su primer lote.
Un registrador de tenencias designado en un token en circulación parte del supply del
token fuera del PoolManager, y un registrador que ya registró el token lo rechaza. Hasta
entonces, un registrador nuevo partía de cero: cada venta fallaba, y las partes del
airdrop de los ciclos abiertos después quedaban rotas para siempre. Ahora el trading
continúa, y los holders a los que el nuevo registrador no ha visto moverse se leen como si
no hubieran tenido nada hasta su siguiente movimiento. La regla sigue siendo hacer el
upgrade del registrador en el propio contrato.
Correcciones menores: los vaults aplican el propio mínimo del keeper a lo que realmente
llega, no solo su propio límite; el ticket de contabilidad del bridge canónico paga según
el tamaño del lote; los ajustes rechazan un tick de lanzamiento en el que ningún pool
puede abrirse, un límite nulo para el nombre, y un hook y un lock sobre PoolManager
distintos; un cambio a ventanas del airdrop más largas ya no bloquea un mercado que tiene
acciones apartadas. Consulta Modelo de confianza.
2026-10-05 — La segunda pasada del bucle de auditoría
El mismo día, un segundo bucle de revisión de las correcciones dio lugar a más correcciones en los contratos, cada una con un test, no desplegadas, y a cambios en el keeper.
Las cuentas contabilizan lo que las respalda, nunca el saldo. El saldo del contrato del
airdrop, y del hub remoto en el rail de USDG, también contiene tokens que han llegado pero
aún no están abonados: una entrega cuyo último paso no se ha ejecutado. Tras una
emergencia, esos tokens podían reabrir las reclamaciones de un ciclo vaciado y pagarlas
con las acciones de otro mercado. Los dos contratos contabilizan ahora ellos mismos lo que
respalda sus cuentas. Una transferencia de emergencia toma primero de ahí; lo que se lleva
más allá de eso procedía de tokens aún no abonados, y las siguientes entregas lo saldan
antes de respaldar nada, con el hub remoto registrando esos lotes en lugar de entregarlos.
Los activos vuelven mediante restore, que cualquiera puede llamar; una simple
transferencia no respalda nada, así que los tokens extraviados solo se recuperan mediante
un rescue, para restaurarlos. Consulta Modo de emergencia.
Tras una baja de todo el resto de un ciclo, que sigue a una reclamación, lo que llegue después a ese ciclo se reparte a prorrata entre todos sus holders, como si el monto dado de baja nunca hubiera estado allí; hasta entonces iba primero a los holders que aún no habían cobrado, en el orden en que reclamaban. Una baja que no deja nada apartado para un mercado pone fin a su búsqueda de una ventana.
Un token rechaza un registrador de tenencias ligado a un PoolManager de Uniswap distinto
del de su pool, que contaría el pool como un holder y pagaría a cada holder una fracción
de su parte. Y un registrador designado en un token en circulación mantiene un supply
registrado al menos igual al total de los holders, no igual a él, hasta que todos los
holders se hayan movido.
En el bridge canónico, la comisión se cotiza a una tarifa base que indica el keeper, el doble de la última, y el exceso se devuelve: una cotización leída sin precio del gas veía una tarifa base nula, y un lote largo fallaba. El hub remoto solo se entera de quién es el keeper por un lote: antes del primero, el owner de StockFun despliega por adelantado el vault espejo del primer mercado, y un mercado cuyo vault el keeper no puede desplegar por adelantado queda fuera de su lote, con una alerta. El keeper cuenta por separado los fallos de un vault en Ethereum y en Robinhood Chain.
De la segunda ronda del 2026-10-01: R2H-1 queda cubierto por las herramientas de liquidación más un procedimiento, la puesta en pausa del hub remoto por el owner antes de la transferencia; R2H-2 queda mitigado, aún abierto: un vault espejo congelado ya no detiene la cola canónica para siempre, y solo el keeper compone un lote, pero una entrega a ese vault sigue fallando en su totalidad, así que el keeper debe dejar fuera ese mercado. Consulta Modelo de confianza. Cerrado el mismo día por la cuarta pasada: ver más abajo.
2026-10-05 — Un fallo nunca bloquea el resto
La regla de diseño del fundador, fijada el mismo día: cuando algo hace fallar una función, las demás funciones no deben pagar por ello; todo debe seguir funcionando, y todo debe tener una palanca para recuperar los fondos perdidos y recibir la corrección. Tiene dos partes. Aislamiento: un fallo en una función, un mercado, una acción, un ciclo, un registro o un destinatario nunca bloquea a los demás; el elemento se omite, se guarda como adeudado o se difiere, con un evento, y el resto sigue. Palancas: cada contrato que puede guardar ETH o tokens, aunque sea de paso o por error, tiene una palanca para sacar lo que se queda atascado, y cada módulo puede recibir una corrección, un upgrade o un setter que lo sustituye. A partir del cuarto bucle de auditoría, los bucles cuentan cualquier infracción como un defecto.
Una excepción deliberada: la notificación de un token a su registrador de tenencias sigue
siendo bloqueante, y una notificación que falla hace fallar la transferencia. Una
notificación a la que se permitiera fallar dejaría que un holder la privara de gas en su
propia transferencia, de modo que el registro omitiera el movimiento y su parte del
airdrop creciera. La palanca es inmediata: setRecorder(0) en el token, o un upgrade del
registrador en el propio contrato, de una transacción cada una.
Consecuencias aceptadas: una parte rechazada espera a su destinatario en lugar de detener el resto; una transferencia de emergencia no imputada a ningún mercado hace esperar los pagos de ese activo hasta que se liquide; y mientras un token no tiene registrador, el airdrop no abre ningún ciclo suyo y deja apartadas sus acciones. Consulta Arquitectura.
2026-10-05 — La tercera pasada del bucle de auditoría
El mismo día, un tercer bucle, centrado en secuencias: operaciones correctas por sí solas que fallan en cierto orden o en cierto momento. Cada corrección tiene un test, no desplegada.
restore devuelve primero lo que una transferencia de emergencia se llevó por encima de
lo que respalda las cuentas, en el contrato del airdrop y en el rail de USDG del hub
remoto, y respalda las cuentas con el resto: devolver los tokens de una entrega que espera
ya no paga con ellos al mercado vaciado. Una acción dada de baja entera de un ciclo antes
de que nadie la reclamara sale de la lista de ese ciclo.
Un registrador de tenencias designado en un token en circulación empieza un registro nuevo en el momento del cambio: el airdrop no mide ninguna ventana que empezara antes de él, cuyas acciones esperan, apartadas, a la primera ventana que cubre por completo, y el token notifica el saldo de la dirección de burn en el momento del cambio. Hasta entonces, una ventana así, medida solo desde el cambio, pagaba de más a quien se movía después. Procedimiento: abrir primero los ciclos de las ventanas ya cerradas y luego hacer el cambio justo después del final de una ventana; hacer un upgrade del registrador en el propio contrato sigue siendo la regla.
El script de lanzamiento de $STOCKFUN excluye del airdrop al operador del lanzamiento,
cuyo primer ciclo pagaba hasta entonces esa tenencia. Los scripts del bridge se detienen
antes de desplegar cuando la factory ya designa otro hub, y mapean las acciones antes de
designar el hub; setBridgeHub rechaza un hub que no puede transportar un basket
registrado. Offchain: una transacción cuyo recibo no se puede leer se sigue por su hash y
nunca se envía dos veces; la vigilancia de emergencias lee sus eventos por fragmentos, y
alerta una vez cuando falla y otra cuando se recupera; un mercado cuya entrada en el lote
no se puede construir queda fuera, con una alerta. En la app, una transacción sin
confirmar conserva su hash (desde el décimo bucle de auditoría se sigue hasta lo que se
mina con su nonce, sin que una cancelación en la wallet se lea nunca como hecha: más
abajo), y un pool que el modo de cierre recuperó no muestra ni precio ni trading.
2026-10-05 — La cuarta pasada del bucle de auditoría: la regla en el código
El mismo día, el cuarto bucle llevó la regla del fundador al código. Cada corrección tiene un test de regresión, no desplegada.
Las entregas del bridge nunca bloquean otro mercado, la decisión del owner sobre R2H-2:
una parte que el token de efectivo rechaza a un vault espejo se queda en el hub remoto,
adeudada a su mercado, y los demás cobran; en el rail canónico sale de la cola, de modo
que los registros que van detrás se pagan. Cualquiera la paga más tarde con sweep. Una
transferencia de emergencia en el hub remoto puede imputarse a un solo mercado, cuyas
cuentas se liquidan en la misma llamada. Las reclamaciones pagan lo que pueden: una acción
para la que las cuentas se quedan cortas, o cuya transferencia se rechaza, se difiere y
sigue adeudada, y claimMany omite un ciclo que excluye a quien llama. Cada tramo de
compra, cada acción de un envío al airdrop y cada mercado de un lote del bridge van por
separado. Un vault que rechaza ETH ya no detiene su mercado: el hook guarda lo que no pudo
pagar como adeudado a ese vault, el lock guarda para su destinatario la parte rechazada de
un cobro de comisiones, y cualquiera las paga; un contrato creador que no puede recibir
ETH reclama hacia otra dirección. La Lens lee un vault a la vez.
Palancas en todas partes: un rescue de lo que un módulo guarda por error en cada módulo que no guarda nada de nadie, en el hook solo para lo extraviado, en el lock nunca para las partes que guarda, en el burner para su ETH solo cuando ningún burn pueda ya gastarlo, y en los dos tokens; los vaults, los hubs y el contrato del airdrop conservan el modo de emergencia.
Además: el router de Ondo solo sirve a los vaults de su factory (M-7), y cada router se
rechaza a sí mismo como destinatario (L-4); el ticket de depósito del rail canónico se
cotiza a la tarifa base; el script de lanzamiento de $STOCKFUN incluye al operador en la
lista antes de la acuñación; la comprobación del almacenamiento compara cada nivel de cada
struct. Decidido el mismo día: M-2 y R2F-1 se quedan como están. Consulta
Modo de emergencia y Modelo de confianza.
2026-10-05 — El paso del airdrop en el keeper y la pantalla de reclamación
Escritos el mismo día, a petición del fundador, sin ninguna decisión nueva; no desplegados. El keeper envía las acciones de cada mercado una vez por ventana, después de la sesión estadounidense por defecto: primero coloca las acciones apartadas, luego abre el ciclo y después hace el envío, cada acción y cada mercado por separado, y sigue cada entrega desde Robinhood Chain hasta que se abona, con una alerta que lleva el comando para volver a ejecutar una entrega retrasada. La pantalla de reclamación de la dapp muestra lo que una wallet puede reclamar, ventana por ventana, y reclama hasta diez ventanas por transacción, entre unos 3,4 y 3,5 millones de gas medidos en frío. Queda fuera: ejecutar automáticamente el último paso de una entrega fallida; la alerta da el comando en su lugar.
La pasada offchain del cuarto bucle dio después al keeper sus nuevas tareas: pagar las deudas que guardan el hook y el lock, alertar sobre los tramos fallidos, los mercados omitidos repetidamente y las entregas rechazadas, planificar cada tramo de acción por separado, un archivo de estado entre reinicios y el cobro diario de las comisiones de LP. La app muestra «Figures unavailable» para un vault que no puede responder. Consulta El keeper y La dapp.
2026-10-05 — La quinta pasada del bucle de auditoría
El mismo día, un quinto bucle encontró siete problemas de gravedad baja, cada uno corregido con un test, no desplegado. La transferencia del hub remoto imputada a un registro canónico es para un registro cuyo depósito ha llegado: rechaza un monto que supere el efectivo no retenido para partes rechazadas, y un registro cuyo depósito se ha perdido se da de baja. Una acción cuyo saldo no se puede leer ya no detiene un envío al airdrop, ni su cotización, y tampoco lo hace un adaptador sin código en la cotización. Los contratos de implementación de la factory y del hub remoto, que guardan su admin en el almacenamiento del proxy, toman a su deployer como palanca para lo que se les envía. El lock y los dos tokens ganan rescues para los claims de v4 y los NFT que se les envían por error; el lock sigue sin tener ninguna llamada genérica. Un lote del bridge deja fuera un mercado cuyo vault aún no tiene código. Se corrigió un comentario que describía mal cómo una compra mueve los fondos. Consulta Modo de emergencia.
2026-10-06 — La pasada offchain del quinto bucle
La revisión del código offchain en el quinto bucle encontró tres problemas de gravedad media y dieciséis de gravedad baja, cada uno corregido el mismo día con un test, no desplegado. El keeper se atiene ahora a la cadencia del 2026-09-27: el ETH de un vault se convierte una vez por ventana del airdrop, si el vault contiene el umbral en la primera pasada del keeper después de que se cierre la ventana; por debajo, el ETH espera a la ventana siguiente. Hasta entonces, el keeper lo convertía en cualquier pasada de la sesión en cuanto el vault contenía el umbral. Cada transacción que envía el keeper se escribe en su archivo de estado, con su nonce, antes de esperar su recibo, de modo que un keeper interrumpido mientras espera no la vuelve a enviar; una que ya ningún nodo conoce se abandona pasado un plazo; una carpeta de estado solo la usa un keeper a la vez. En el rail de Ondo, una compra que Ondo cotiza por debajo del límite del vault ya no se envía para que falle, ni se paga una atestación por ella. Una acción cuyo adaptador no responde queda fuera, ella sola, de un envío al airdrop.
Un basket contiene como máximo cinco acciones, un límite técnico que el owner de StockFun
puede cambiar mediante un upgrade: cada costo que crece con un basket se mide hasta ese
tamaño, y los tres baskets del lanzamiento contienen tres, tres y dos. La Lens lleva el
estado de cada vault y lo que el hook y el lock le deben, y su upgrade se pone en
producción antes que el Worker y la app que la leen. El script de lanzamiento de
$STOCKFUN reanuda una ejecución que se detuvo antes de que se designara el mercado del
protocolo, en lugar de acuñar un segundo token. La app cuenta en su tesorería el ETH que
se le debe a un vault, deja margen en una reclamación para una acción abonada antes de que
se mine, recuerda una acción que su token rechazó, y nunca muestra como nada una cifra que
no pudo leer. Consulta El keeper, Los baskets y
La dapp.
2026-10-06 — El sexto bucle de auditoría
El sexto bucle encontró un problema de gravedad alta y cinco de gravedad baja, cada uno corregido el mismo día con un test, no desplegado. En el bridge canónico, usado en la testnet y como fallback, el keeper dejaba de reejecutar los tickets de un lote en cuanto sus mercados quedaban abonados, y a un mercado se le podía abonar el efectivo de otro lote, de modo que un depósito que no lograba su ejecución automática podía expirar. El keeper vigila ahora cada ticket hasta saber que se ejecutó, sea cual sea el abono de su transferencia, reejecuta uno que siga vivo y alerta cuando de uno no se sabe que se haya ejecutado al cabo de seis horas por defecto, o cuando se ha perdido; abona una transferencia canónica solo por los propios eventos del hub remoto, nunca por un saldo.
Con las correcciones llegó una decisión, tomada por la auditoría como su opción por defecto recomendada: la cadencia del 2026-09-27 alcanza al USDC. El USDC de un vault, gastado en acciones en Ethereum o enviado por el bridge, sale una vez después de cada conversión de su ETH, y como máximo una vez por ventana en los demás casos; hasta entonces, unas pocas unidades de USDC enviadas a un vault hacían que el keeper enviara una transacción, o todo un lote del bridge, en cada pasada. Las compras en Robinhood Chain siguen haciéndose en cada pasada: el saldo de un vault espejo no distingue una entrega de una donación, y los topes de cada compra reparten a propósito una entrega grande en varias pasadas. Las ejecuciones locales y de testnet desactivan ambas cadencias con el mismo interruptor.
También se corrigió: una búsqueda de acciones apartadas que no colocaría nada, para un
vault sin nada que enviar, ya no se envía cada día; un vault por debajo del umbral se
comprueba con un saldo leído después del cierre de la ventana; antes ese mismo día, el
archivo de despliegue local pasó a comprobarse frente a la cadena antes de usarse; la app
marca el precio de $STOCKFUN como «(last read)» mientras la Lens no puede leer su
tesorería, y el worker no registra ningún precio para él entretanto. El bucle siguiente,
iniciado el mismo día, encontró que el keeper cotizaba todos los vaults en un solo router
mientras que cada vault conserva el router con el que se creó: ahora cada vault se cotiza
en el suyo. Consulta El keeper.
Desde el séptimo bucle, más abajo, «nada que enviar» significa nada que valga la pena enviar, y el keeper lee cada ticket empezando por el recibo de su creación.
2026-10-06 — El séptimo bucle de auditoría
El séptimo bucle encontró un problema de gravedad media y catorce de gravedad baja, cada uno corregido el mismo día con un test, no desplegado; los contratos estaban limpios. En el bridge canónico, el keeper leía si un ticket seguía existiendo antes de leer el recibo de su creación: un depósito creado entre las dos lecturas, o visto por dos nodos con un bloque de diferencia, podía pasar por ejecutado mientras seguía vivo, y expirar sin reejecución y sin alerta. Ahora los lee en el orden en que lo hace el SDK de Arbitrum: primero el recibo, luego la ejecución automática y luego el ticket en un bloque no anterior a su creación.
Con las correcciones llegó una decisión, tomada por la auditoría como su opción por
defecto recomendada: el keeper solo envía al airdrop lo que vale lo que cuesta enviarlo.
Una acción por encima del polvo que el bridge de LayerZero no puede transportar, valorada
con el propio oráculo de su vault a la última respuesta de su feed de precios, debe valer
su propia comisión de LayerZero, o su parte del gas del envío en Ethereum, y las acciones
que pasan deben valer juntas todo el envío más la apertura del ciclo de la ventana cuando
aún no está abierto; si no, esperan en el vault a una ventana posterior, con lo que se vaya
acumulando. Un valor que el keeper no puede leer deja salir el envío, como antes. El
múltiplo es un ajuste del keeper, KEEPER_AIRDROP_MIN_VALUE_BPS: una vez el costo por
defecto, y 0 desactiva la regla. Solo decide cuándo sale una acción, nunca cuánto, qué ni
adónde. Hasta entonces, un regalo de acciones apenas por encima del polvo al vault de un
mercado que nadie opera hacía que el keeper abriera el ciclo de esa ventana y pagara un
mensaje de LayerZero cada día; y ese mismo polvo contaba como «algo que enviar», así que el
límite de las búsquedas de acciones apartadas del sexto bucle no se cumplía en el bridge.
También se corrigió: cada búsqueda de logs del keeper se detiene unos pocos bloques por
debajo del último bloque de la cadena, de modo que nunca se pierde un evento detrás de un
nodo con uno o dos bloques de retraso; el keeper comprueba que cada RPC sirve la cadena que
indica su configuración, y si no, se niega a arrancar; su webhook de alertas tiene un
límite de tiempo y su respuesta se lee, y una alerta que no acepta se guarda y se vuelve a
enviar; un ajuste vacío toma su valor por defecto. El Worker de datos de la app lee cada
contrato upgradeable por separado, así que uno que falla tras un upgrade defectuoso ya no
deja en blanco las cifras del token $STOCKFUN; muestra el volumen de 24 horas como
desconocido mientras sus lecturas de los logs de trades siguen fallando, comprueba que cada
uno de sus endpoints sirve su cadena, y el gráfico de precios sitúa cada punto en su
momento. Ni la Lens ni el esquema de datos del Worker cambian. Consulta
El keeper y La dapp.
Desde el octavo bucle, más abajo, una acción cuya propia cotización es cero se consulta en su adaptador, la apertura de la ventana se cuenta una sola vez en el rail local, el ticket se lee unos pocos bloques por debajo del último, y el keeper ya no supone un identificador de cadena cuando no hay ninguno configurado.
2026-10-06 — Protecciones de los feeds de precios en Robinhood Chain
El plan de lanzamiento enumeraba dos protecciones que el oráculo aún no tenía, ambas recomendadas por la documentación de Robinhood. Están construidas, no desplegadas, como ajustes del owner de StockFun que empiezan desactivados; cada una solo puede retener un precio, nunca cambiarlo.
- Una operación corporativa. Mientras una acción pasa por una, su token indica que su oráculo está en pausa, y su feed de precios mantiene su último valor, que aún puede parecer fresco mientras cambia el multiplicador del token. El oráculo retiene ahora el precio de esa acción: su tramo de compra falla solo, con su efectivo guardado para ella, y se compran las demás acciones del basket. La comprobación está activada para todas las acciones del rail de Robinhood, acción por acción, para que un token cuya respuesta no se pueda usar, o cuyo indicador siga activado, pueda desactivarse por separado. Un token que no responde cuenta como no pausado: Robinhood califica el indicador de orientativo, y la propia comprobación de antigüedad del feed sigue siendo la salvaguarda principal.
- El secuenciador. Robinhood Chain es una cadena Arbitrum con un único secuenciador. Con el feed de disponibilidad del secuenciador L2 de Chainlink, el oráculo retiene todos los precios mientras el secuenciador está caído, volvió a funcionar dentro del periodo de gracia (una hora por defecto), o el feed no se puede leer. No existe ningún feed así para Robinhood Chain, y Chainlink ya no los añade a nuevas redes: el rail se despliega con esta comprobación desactivada, por una elección explícita que exige el script de despliegue, y el owner de StockFun configura el feed si alguna vez se publica uno.
En Ethereum, ambas siguen desactivadas. Consulta El rail de Robinhood.
2026-10-06 — El octavo bucle de auditoría
El octavo bucle encontró un problema de gravedad media y ocho de gravedad baja, cada uno corregido el mismo día con un test, no desplegado; los contratos y las protecciones de los feeds de precios estaban limpios. Antes de que la app hubiera leído el registro de baskets de la cadena, su formulario de lanzamiento ofrecía los baskets configurados con sus números configurados: en un despliegue que numerara sus baskets de otra manera, un creador podía lanzar un mercado, de forma irreversible, sobre un basket distinto del mostrado. El formulario ofrece ahora solo los baskets leídos de la cadena, y vuelve a leer el elegido de la factory justo antes de enviar, algo que rechaza si el nombre o las acciones difieren.
También se corrigió: el keeper solo sigue un lote del bridge una vez que el bloque que lo contiene tiene unos pocos bloques de profundidad, de modo que una reorganización de los bloques más recientes de Ethereum ya no puede dejarlo vigilando identificadores que nunca existen; distingue el polvo que el bridge no puede transportar de una acción cuya propia comisión de LayerZero no se puede cotizar, que ahora deja fuera con una alerta en lugar de descartarla en silencio; guarda una sola alerta en espera por alerta distinta, con cuántas veces y cuándo se lanzó, así que las alertas repetidas en cada ciclo ya no desplazan a una alerta puntual; ya no deja de lado un archivo de estado escrito para otra cadena antes de comprobar qué cadena sirve su RPC, y exige los dos identificadores de cadena; lee un ticket unos pocos bloques por debajo del último, que tienen todos los nodos de un endpoint; y en el rail local cuenta una sola vez la apertura de la ventana. El keeper, su preflight y su inspector conocen ahora las protecciones de los feeds de precios: las compras en Robinhood Chain esperan mientras el oráculo retiene los precios por el secuenciador, con una alerta, y una acción en plena operación corporativa espera sola, sin contar nunca como un fallo. El Worker de datos de la app nunca hace retroceder su ventana de trades, así que un nodo unos bloques por detrás ya no hace que el volumen de 24 horas cuente bloques dos veces; su proxy RPC rechaza todo lo que no sea una dirección; publica por qué falta el precio de una acción (esquema de datos 8), lo que la app muestra; y el panel de trading cobra a una wallet de la whitelist el impuesto normal durante la ventana anti-snipe, como hace el hook. La Lens no cambia, y el Worker y la app se siguen pudiendo desplegar en cualquier orden. Consulta El keeper y La dapp.
2026-10-06 — El gas de la entrega del airdrop con Glamsterdam
Sepolia activó la actualización Glamsterdam de Ethereum el 2026-10-06, durante la
ejecución de LayerZero en testnet (más abajo); Hoodi y mainnet aún no tenían fecha.
Reajusta el precio del crecimiento del estado: un nuevo slot de almacenamiento escrito en
frío cuesta 110 020 de gas, frente a 22 100 antes. Cada cifra fija de gas de los contratos
y de los scripts se volvió a medir en Sepolia, y todas se mantienen salvo un par, el gas que
recibe una entrega del airdrop en Ethereum: el envío del vault espejo llevaba una sola
cifra de compose, 600 000, y el lzReceive del OFT de la acción solo recibía lo que impone
ese OFT. Todas las entregas del primer ciclo de la ejecución se quedaron sin gas en el
ejecutor de LayerZero y se ejecutaron a mano. El décimo bucle de auditoría encontró
después dos más: el gas propio de los scripts de despliegue y el del compose del bridge
para un lote (más abajo).
La decisión del fundador, ese mismo día: el keeper simula cada entrega y elige su gas, acotado dentro de los límites que el owner de StockFun fija en el hub remoto; una entrega que siga atascada la vuelve a ejecutar el keeper, que alerta en un segundo fallo. En el código, no desplegado en mainnet:
- El hub remoto tiene dos políticas de gas, cada una con un valor por defecto, un
suelo y un techo: el gas de
lzReceiveademás de lo que impone el OFT de la acción, 650 000 entre 200 000 y 1 500 000 (setAirdropReceiveGas), y el gas del compose, 1 250 000 entre 600 000 y 4 000 000 (setAirdropComposeGas). ElsendToAirdrop(stocks, receiveGas, composeGas)del vault espejo envía lo que el hub concede para lo que pide el keeper, y cero toma el valor por defecto; la llamada solo con las acciones toma los dos valores por defecto. Un hub que recibe un upgrade desde una versión anterior a las políticas rechaza todo envío hasta que se fijen ambas - El keeper simula el
lzReceivey el compose de cada acción en Ethereum, desde la dirección del endpoint, y pide lo que necesita más un 25 %; cuando una simulación no puede ejecutarse, toma lo que usaron las últimas entregas del mercado, y si no, los valores por defecto del hub. Una entrega que sigue almacenada en el endpoint, una vez que el ejecutor de LayerZero la ha hecho fallar o al cabo de diez minutos, se vuelve a ejecutar desde la propia clave del keeper, con lo que necesita según la simulación más un 25 %, como máximo 4 000 000 de gas por defecto; una que no puede salir se alerta con el comando para ejecutarla a mano, y un segundo fallo se alerta y no se vuelve a enviar nunca - La app reclama cinco ventanas por transacción en lugar de diez, deja 400 000 de gas por cada acción que una ventana aún puede recibir, y añadía 150 000 de gas a la estimación de cada escritura, algo que el noveno bucle de auditoría sustituyó por el límite propio de cada escritura (más abajo)
La corrección se aplicó mediante upgrade al hub remoto y al vault espejo de la ejecución en testnet, y sirvió para sus ciclos posteriores. Consulta El keeper y El rail de Robinhood.
2026-10-06 — La ejecución de LayerZero en testnet
El protocolo se desplegó en Sepolia y en la testnet de Robinhood Chain, con los scripts de producción o con envoltorios de testnet que conservan su cuerpo, en 167 transacciones, todas con éxito, con acciones de prueba, adaptadores de prueba, un USDG de prueba y feeds simulados, y funcionó de 13:50 a 19:07 UTC: siete ventanas horarias, con el ETH de cada una convertido, pasado por el bridge sobre LayerZero y gastado en las acciones de prueba; seis ciclos del airdrop enviados de vuelta sobre LayerZero, los cuatro primeros reclamados por completo por cinco holders, cada pago exactamente la parte calculada a partir del registrador de tenencias; los simulacros de incidente se hicieron sobre mensajes reales y se recuperaron como está documentado, salvo dos mitades. Demuestra el código de StockFun sobre los endpoints, el DVN y el ejecutor reales de LayerZero. No demuestra el par USDG de Paxos, las acciones de Robinhood y sus adaptadores, feeds ni liquidez reales, ni el gas, las comisiones y la finalidad de mainnet: queda una prueba en mainnet. Lo que encontró en el código de producción es el reajuste de precios de Glamsterdam (más arriba) y parte del noveno bucle de auditoría (más abajo). Consulta El rail de Robinhood.
2026-10-06 — El noveno bucle de auditoría, y la puerta de verificación
El noveno bucle revisó las correcciones del octavo, y recogió los hallazgos del operador de la ejecución de LayerZero en testnet. Encontró dos problemas de gravedad media, el gas de la entrega del airdrop (más arriba) y el Worker de datos de la app, que reconstruía su conmutación de RPC en cada desalojo de su objeto de Cloudflare, lo que, durante una caída del RPC principal, le enviaba 37 peticiones en menos de siete minutos donde ahora salen 8; y problemas de gravedad baja en el keeper, el Worker y un script de testnet, cada uno corregido el mismo día con un test. Durante un minuto después de una de sus propias transacciones, el keeper lee lo que esta cambió, y estima el gas de lo que envía a continuación, en el bloque de esa transacción, así que un nodo con un bloque de retraso ya no convierte en un falso fallo el lote del bridge enviado justo después de una conversión; cada una de sus transacciones sale con su gas estimado más un 25 %; las alertas que no pudo entregar salen en el orden en que se lanzaron por última vez; un ticket que borró su propia reejecución ya no se alerta como vivo; una hora de la cadena que ninguna fecha puede representar se lee «an unknown time»; decodifica los errores del oráculo; y su preflight se ejecuta sobre el despliegue de la ejecución en testnet. El Worker registra el número de bloque propio de Robinhood Chain.
Desde este bucle, un segundo agente revisa el cambio de cada corrección antes de que se suba, frente a las clases de defectos que encontraron los bucles anteriores, la mayoría en las correcciones del bucle previo: la puerta de verificación. Lo que encuentra se corrige como un hallazgo de revisión, y esa corrección vuelve a pasar por la puerta. En este bucle encontró defectos de gravedad baja en varias correcciones, entre ellas una nueva ejecución que creía una alerta que cualquiera puede emitir, ahora creída solo si viene del ejecutor de LayerZero, y otra que decidía una ejecución fallida en el propio bloque de esa ejecución, algo que una reorganización del bloque podría haber convertido en un falso segundo fallo: ahora espera a que el bloque tenga unos pocos bloques de profundidad. Todos están corregidos.
La revisión del Worker y de la app en ese bucle encontró después un problema más de gravedad media, los 150 000 de gas que la app añadía a la estimación de una escritura, que se quedaban cortos cuando un trade encuentra más almacenamiento nuevo que la marca del supply de la hora, corregido el mismo día: cada escritura recibe ahora su estimación más 50 000 de gas y, un trade, también el gas de cada escritura que su estimación no puede ver y que aún puede producirse, leído en el bloque de la estimación; una escritura cuya estimación falla sale con un límite fijo, y un lanzamiento entonces espera. Sus dos hallazgos de gravedad baja también se corrigieron: un bote que es una estimación se marca con «+» dondequiera que aparezca, y una aprobación que no se puede leer nunca se toma por ninguna. El bucle no está limpio, y el recuento de bucles limpios sigue en cero. Consulta El keeper y La dapp.
2026-10-06 — El décimo bucle de auditoría
El décimo bucle revisó las correcciones del noveno y el trabajo sobre la actualización Glamsterdam de Ethereum, cada área desde un ángulo propio: los contratos con los nuevos precios del gas, cada mensaje cross-chain que falla en su destino, el keeper a lo largo de meses, la app con wallets reales, y los documentos frente al código. Encontró tres problemas de gravedad media y seis de gravedad baja, cada uno corregido el mismo día con un test, cada corrección revisada por la puerta de verificación, no desplegado en mainnet. Los contratos salieron limpios en el ángulo del gas con ambas tablas de precios.
- El procedimiento de despliegue con Glamsterdam. El despliegue documentado en Ethereum no podía salir bien: la herramienta de despliegue daba a cada transacción el gas de su propia simulación local, a los precios antiguos, cuando la creación de un contrato necesita ahora de cuatro a siete veces más. Cada difusión pide ahora al nodo el gas de cada transacción una vez minada la anterior; ejecutado en Sepolia
- El gas de compose de un lote del bridge. El último paso de un lote del bridge en Robinhood Chain recibía una cifra de gas fija, 1 200 000, fuera cual fuera el contenido del lote: cuatro nuevos mercados de cinco acciones lo dejaron sin gas, su USDG quedó entonces en el hub remoto sin ningún registro, y cada lote posterior con los mismos mercados fallaba de la misma manera. Ahora el gas es una base más una parte por mercado, 200 000 y 400 000 por defecto, ambos ajustes del owner de StockFun, y un lote lleva como máximo 17 mercados, lo que mantiene su mensaje por debajo del límite de tamaño de LayerZero y su gas por debajo del límite por transacción de Robinhood Chain; el keeper envía como máximo esa cantidad y deja el resto para su siguiente pasada, primero los mercados que más tiempo llevan esperando. El gas adicional cuesta poco: el ejecutor de LayerZero lo cobra al precio del gas de Robinhood Chain, 0,00001 ETH por millón de gas en la testnet. La alerta del keeper por una transferencia atascada indica ahora en qué punto está el mensaje del lote. El adaptador de la testnet se actualizó el mismo día y su siguiente lote pasó con el nuevo gas
- La vigilancia de emergencias. El keeper nombraba todos los vaults vigilados en una sola petición de logs, que un endpoint rechaza por encima de su límite: una vez que el registro lo hubiera superado, ninguna transferencia de emergencia se habría vuelto a retransmitir. Ahora los nombra por grupos, limitados por un nuevo parámetro
- Correcciones menores. Los textos de error del keeper conservan solo el host de una dirección RPC; sus lecturas de cada mercado pasan por Multicall3, cien mercados por llamada, en lugar de una a una en cada pasada; la app sigue una transacción que la wallet cancela o reemplaza, sin mostrar nunca una cancelación como hecha, y durante un minuto después de su propia transacción lee en un bloque no anterior al de esa transacción, así que una venta justo después de su aprobación ya no la rechaza un nodo con un bloque de retraso; y dos documentos se pusieron al día con el código
Con su valor por defecto de enviar después de la sesión estadounidense, el keeper ahora solo vuelve a leer un vault sin nada que enviar después del cierre en la siguiente sesión. Una consecuencia de ese ahorro, y no una regla nueva: una acción dada a un vault después del cierre, fuera de cualquier compra, sale con el envío de la siguiente sesión, a una ventana posterior; lo que traen las propias compras del vault sigue yendo a la ventana que terminó ese día.
La auditoría también sopesó una recomendación, no un defecto: reclamaciones que dejen un wei en cada una de las acumulaciones de comisiones del hook, para que el siguiente trade nunca pague por escribir esos slots desde cero. No se adopta por ahora. El gas adicional recae en el primer trade después de cada reclamación, unos 104 000 por slot, y el margen de la app para ello eleva el límite de un trade, no lo que paga; el cambio tocaría código de reclamación cuyas reglas formales no podrían volver a demostrarse sin una ejecución del prover; y el hook y el burner pueden incorporarlo más adelante mediante upgrade, sin migración. El bucle no está limpio, y el recuento de bucles limpios sigue en cero. Consulta El keeper, El rail de Robinhood y La dapp.