Back to Blog

Acuñación de ONE entre fragmentos de Harmony + ~$47M en pérdidas de claves | BlockSec

Code Auditing
August 19, 2026
9 min read
Key Insights
  • Se destacan 5 incidentes de seguridad importantes esta semana, con pérdidas cuantificadas de aproximadamente $47M. Tres fueron compromisos de claves privadas que movieron fondos de usuarios directamente (Unknown Whale Wallet ~$25M, Kite ~$14M, y Coinsbuy ~$7.9M), mientras que el incidente destacado, Harmony, fue una falla de implementación en la cadena cuyo ONE falsificado no tiene una cifra de pérdida realizable o confirmada (ver la nota de la tabla).

  • Los shards de destino de Harmony derivaban el marcador de "gastado" del recibo entre shards a partir de campos de prueba no autenticados (MerkleProof.ShardID y MerkleProof.BlockNum) en lugar del encabezado de bloque firmado de origen, por lo que un atacante podía repetir un recibo ya acreditado modificando únicamente esos campos y acuñar ONE nativo sin un débito correspondiente en el shard de origen. Una segunda falla, de verificación de quórum previa al staking, contaba el tamaño completo del comité en lugar de los validadores realmente habilitados en el bitmap de firmantes.

  • Una implementación de cadena debe autenticar cada campo que utiliza para identificar el estado ya consumido, y debe evaluar el quórum según los validadores que realmente firmaron, en lugar del comité completo.

Durante la semana pasada (10/08/2026 - 16/08/2026), se destacan los siguientes 5 incidentes de seguridad notables, que involucran aproximadamente $47M en pérdidas totales.

Fecha Incidente Tipo Pérdida Estimada
10/08/2026 Coinsbuy Compromiso de Clave Privada ~$7.9M
10/08/2026 Billetera Ballena Desconocida Compromiso de Clave Privada ~$25M
12/08/2026 Harmony Problema de Validación Desconocido*
13/08/2026 Kite Compromiso de Clave Privada ~$14M
15/08/2026 Fox Falla de Lógica de Negocio ~$117K

*Harmony reportó una primera ola confirmada de acuñación de 4B ONE y una reconstrucción más amplia de aproximadamente 3.01T ONE falsificados, de los cuales aproximadamente 2.385T ONE fueron transferidos [1]. Al precio previo al incidente de ~$0.001183, la cantidad falsificada tiene un valor nominal de ~$3.56B, pero eso equivale aproximadamente a 200 veces el suministro total de ONE y excede ampliamente la capitalización de mercado del token, por lo que no es una pérdida realizable ni confirmada como realizada. Desde entonces, Harmony ha revertido la cadena a un punto de control previo al ataque, descartando el estado falsificado [2]. Por lo tanto, Harmony queda excluido de las pérdidas totales.

Razones de la selección

  • Harmony: Seleccionado porque una falla de protección contra repetición en la implementación de la cadena permitió la emisión no autorizada de tokens nativos a gran escala en todo el ecosistema de Harmony. Durante la investigación se identificó una debilidad separada en la verificación de quórum previa al staking, aunque su papel en el exploit no está confirmado.

El Mejor Auditor de Seguridad para Web3

Valide el diseño, el código y la lógica de negocio antes del lanzamiento

Destacado de la Semana: Harmony

Harmony es destacado esta semana porque la falla residía en la propia implementación de la cadena en lugar de en un contrato de aplicación, un modo de fallo de impacto inusualmente alto porque puede inflar el activo base de una Capa 1 completa.

El 12 de agosto de 2026, Harmony, una blockchain de Capa 1 fragmentada (sharded), sufrió una acuñación no autorizada de su token nativo ONE a través de una falla de repetición de recibos entre shards (cross-shard). Los shards de destino identificaban un recibo ya consumido usando campos que no estaban cubiertos por la firma del comité de origen, por lo que un atacante podía volver a presentar un recibo genuino, previamente acreditado, mutando únicamente esos campos y hacer que se acreditara nuevamente sin el débito correspondiente en el shard de origen. Harmony estaba reconciliando una primera ola confirmada de acuñación de 4B ONE con una reconstrucción más amplia de aproximadamente 3.01T ONE falsificados y aproximadamente 2.385T ONE transferidos por una billetera de acuñación falsificada; ninguna de estas cifras es una pérdida realizada confirmada, y el impacto final sigue sujeto a la reversión (rollback) y a la reconciliación con los exchanges [1][2]. Durante la investigación, Harmony identificó una falla separada en la verificación de quórum previa al staking, aunque no ha confirmado si el exploit dependió de ella.

Antecedentes

Harmony es una blockchain de Capa 1 fragmentada (sharded). Cada shard mantiene su propio estado independiente, por lo que un shard de origen no puede modificar directamente una cuenta en un shard de destino. Para mover valor entre shards, Harmony utiliza un diseño asíncrono basado en recibos: el shard de origen debita al remitente y emite un recibo entre shards, y el shard de destino posteriormente acredita al destinatario.

Un recibo entre shards registra la propia transferencia:

type CXReceipt struct {
    TxHash    common.Hash
    From      common.Address
    To        *common.Address
    ShardID   uint32
    ToShardID uint32
    Amount    *big.Int
}

El shard de destino no confía en un recibo simple. El recibo viaja dentro de un CXReceiptsProof, que lleva una prueba de Merkle, el encabezado del bloque de origen y la firma de confirmación del comité de origen sobre ese encabezado:

type CXMerkleProof struct {
    BlockNum      *big.Int
    BlockHash     common.Hash
    ShardID       uint32
    CXReceiptHash common.Hash
    ShardIDs      []uint32
    CXShardHashes []common.Hash
}

type CXReceiptsProof struct {
    Receipts     CXReceipts
    MerkleProof  *CXMerkleProof
    Header       *block.Header
    CommitSig    []byte
    CommitBitmap []byte
}

La ruta de verificación normal valida la prueba contra el encabezado de origen firmado y la firma de su comité:

VerifyIncomingReceipts()
  -> IsSpent()
  -> ValidateCXReceiptsProof()
      -> VerifyHeaderSignature()
          -> verifySignature()
              -> DecodeSigBitmap()
              -> IsQuorumAchievedByMask()
              -> aggSig.VerifyHash()

Dado que el shard de origen realiza el débito exactamente una vez, el shard de destino debe asegurarse de que cada recibo entre shards se consuma solo una vez.

Análisis de la Vulnerabilidad

La ruta de liquidación entre shards contenía dos problemas: una debilidad en la protección contra repetición en cómo se identificaba un recibo consumido, y una debilidad en la verificación de quórum previa al staking.

Repetición de Recibos Entre Shards

La protección contra repetición registraba y buscaba el marcador de "gastado" de un recibo, pero su clave provenía de dos campos mutables de la prueba de Merkle:

CXMerkleProof.ShardID
CXMerkleProof.BlockNum

El hardfork Bloom fortaleció esto en la mainnet en la época 2964 (13 de julio de 2026), controlado por IsCXMerkleProofReplayFixEpoch [3]: para una prueba cuyo Header.Epoch() firmado sea igual o posterior a esa época, IsSpent() y WriteCXReceiptsProofSpent() derivan la clave del marcador de gastado a partir del encabezado de origen firmado (Header.ShardID y Header.Number) en lugar de esos dos campos. Sin embargo, el nuevo esquema de clave más robusto nunca se aplicó retroactivamente: para una prueba cuyo Header.Epoch() fuera anterior al hardfork, ambas funciones mantuvieron el respaldo heredado a MerkleProof.ShardID y MerkleProof.BlockNum, que ValidateCXReceiptsProof() nunca vinculó al encabezado firmado para esas épocas.

Esos dos campos están fuera de la firma de confirmación, que solo cubre el Header de origen. Alterar el Header fallaría en VerifyHeaderSignature(), pero mutar MerkleProof.ShardID o MerkleProof.BlockNum no rompe ninguna verificación en absoluto — ni la firma del encabezado, ni la validación de la prueba, que para esas épocas nunca los vinculó de vuelta al Header. Dado que la clave heredada del marcador de gastado se derivaba de estos campos no autenticados, la identidad de protección contra repetición de un recibo estaba desacoplada de la firma que autenticaba el resto de la prueba: dos pruebas que llevaban el mismo encabezado firmado y los mismos recibos, pero diferentes valores de MerkleProof.ShardID o MerkleProof.BlockNum, se trataban como distintas a efectos del seguimiento de gastado.

Verificación de Quórum Previa al Staking

Una segunda falla afectó a la verificación de quórum previa al staking. La lógica de uniformVerifier.IsQuorumAchievedByMask() comparaba el umbral con

len(mask.Publics)

tratándolo como el número de firmantes. Pero mask.Publics es la lista completa de claves públicas del comité para un shard y época, no el conjunto de validadores que realmente firmaron; ese conjunto está representado por el mapa de bits de firmantes. Como resultado, un mapa de bits de firmantes vacío aún podía superar el umbral de quórum, porque la verificación medía el tamaño del comité en lugar de los bits habilitados en el mapa de bits. Combinado con una firma BLS agregada de identidad (todo ceros), esto podía hacer que un encabezado de origen de la era previa al staking pareciera tener el quórum suficiente.

Análisis del Ataque

El atacante partió de un recibo entre shards genuino y ya procesado, de un bloque del shard de origen anterior al hardfork, y luego lo repitió mutando únicamente su identidad de prueba no autenticada. El ONE falsificado se acuñó en cuatro billeteras del explotador. El siguiente análisis se basa en las transacciones 0xf3d4e8b1...8242c7f y 0x9a756ef9...b0a4d678.

  • Paso 1: El atacante obtuvo un CXReceiptsProof histórico válido de un bloque del shard de origen anterior al hardfork. La prueba contenía recibos válidos, un encabezado de bloque de origen válido y una firma de confirmación válida del comité de origen.

  • Paso 2: El shard de destino ya había consumido este recibo una vez y había escrito su marcador de gastado, cuya clave provenía de los campos de la prueba de Merkle.

  • Paso 3: El atacante mutó únicamente los campos de identidad de prueba no autenticados, dejando intactos el encabezado firmado y todos los campos cubiertos por la firma:

    MerkleProof.ShardID
    MerkleProof.BlockNum
  • Paso 4: La prueba mutada se envió como un recibo entrante en un bloque posterior del shard de destino. IsSpent() derivó la clave del marcador de gastado a partir de los campos mutados y no encontró el marcador anterior, por lo que el recibo pareció no gastado.

  • Paso 5: ValidateCXReceiptsProof() aún aceptó la prueba, porque los campos de identidad mutados no estaban cubiertos por la firma mientras que todos los campos autenticados permanecieron sin cambios: el hash del encabezado y el hash del recibo saliente, el hash del bloque y el hash del recibo de la prueba de Merkle, el hash de los recibos, y la firma y el mapa de bits de confirmación.

  • Paso 6: ApplyIncomingReceipt() se ejecutó en el shard de destino y acreditó al destinatario nuevamente a través de db.AddBalance(*cx.To, cx.Amount). No ocurrió ningún débito correspondiente en el shard de origen, porque la transacción original entre shards ya se había ejecutado exactamente una vez, produciendo una inflación nativa de ONE en el shard de destino.

Conclusión

La causa raíz confirmada por el proyecto fue un fallo de protección contra repetición a nivel de protocolo: la identidad del estado consumido de un recibo entre shards se derivaba de campos de prueba no autenticados en lugar del encabezado de origen firmado, por lo que un recibo ya procesado podía acreditarse una segunda vez. Harmony también confirmó una falla separada en la verificación de quórum previa al staking, aunque las divulgaciones públicas no establecen si el atacante la utilizó en este caso.

Los parches cierran ambas brechas [4][5][6]. En términos más generales, la implementación de una cadena debe autenticar cada campo que utiliza para identificar el estado ya consumido, y debe juzgar el quórum según los validadores que realmente firmaron, en lugar del comité completo.

Comience con Phalcon Explorer

Sumérjase en las Transacciones para Actuar con Sabiduría

Pruébelo gratis ahora

Comience con Phalcon Security

Detecte cada amenaza, alerte lo que importa y bloquee ataques.

Pruébelo gratis ahora

Referencias

Acerca de BlockSec

BlockSec es un proveedor integral de seguridad blockchain y cumplimiento de criptomonedas. Desarrollamos productos y servicios que ayudan a los clientes a realizar auditorías de código (incluyendo contratos inteligentes, blockchain y billeteras), interceptar ataques en tiempo real, analizar incidentes, rastrear fondos ilícitos y cumplir con las obligaciones de AML/CFT, a lo largo de todo el ciclo de vida de los protocolos y plataformas.

BlockSec ha publicado múltiples artículos sobre seguridad blockchain en conferencias de prestigio, ha reportado varios ataques de día cero en aplicaciones DeFi, ha bloqueado múltiples hackeos para rescatar más de 20 millones de dólares, y ha asegurado miles de millones en criptomonedas.

Best Security Auditor for Web3

Validate design, code, and business logic before launch. Aligned with the highest industry security standards.

BlockSec Audit