Back to Blog

Resumen Semanal de Incidentes de Seguridad Web3 | 9 – 15 de Feb, 2026

Code Auditing
February 18, 2026
16 min read

Durante la semana pasada (9 de feb.–15 de feb. de 2026), BlockSec detectó y analizó tres incidentes de ataque, con pérdidas totales estimadas de ~$657K. La tabla a continuación resume estos incidentes, y los análisis detallados de cada caso se presentan en las subsecciones siguientes.

Fecha Incidente Tipo Pérdida Estimada
2026/02/10 Incidente Desconocido Lógica de Negocio Defectuosa ~$10K
2026/02/14 Incidente OCA Lógica de Negocio Defectuosa ~$422K
2026/02/14 Incidente SOF Lógica de Negocio Defectuosa ~$225K

1. Incidente Desconocido

Breve Resumen

El 10 de febrero de 2026, el contrato 0x560d39 en BNB Smart Chain fue explotado, resultando en una pérdida estimada de ~$10K. La causa raíz fue una lógica de negocio defectuosa en la función 0xb1a87f2c(), que hizo que su proceso de adición de liquidez fuera vulnerable a un ataque de sándwich.

Antecedentes

En el contrato 0x560d39, la función 0xb1a87f2c() transfiere una cantidad correspondiente de USDT del usuario según el parámetro de entrada. El USDT recibido es procesado, y el 85% del total se destina a operaciones de liquidez posteriores.

De este 85%, la mitad se intercambia por AFX a través de un pool de PancakeSwap, y el AFX adquirido se transfiere al contrato 0x671ce4. La función luego retira AFX de 0x671ce4.

A continuación, mediante el Router V2 de PancakeSwap, la mitad restante del 85% en USDT y el AFX retirado de 0x671ce4 se utilizan para agregar liquidez al par de trading USDT-AFX. Cualquier excedente de USDT o AFX es reembolsado al usuario.

Tras completar la adición de liquidez USDT–AFX, la función obtiene tokens AFX adicionales de la dirección 0x146933. La cantidad de AFX obtenida de 0x146933 se establece para coincidir con la cantidad previamente retirada de 0x671ce4. Luego, la función calcula la cantidad requerida de AHT según la relación de precios actual en el pool de liquidez AFX–AHT de PancakeSwap V2. Posteriormente, suministra el AFX obtenido de 0x146933, junto con la cantidad correspondiente de AHT (también proveniente de 0x146933), para agregar liquidez al par AFX–AHT.

Análisis de Vulnerabilidad

El contrato vulnerable es 0x560d39. El contrato 0x146933 sirve como fuente de financiación para el AFX utilizado en la adición de liquidez AFX-AHT y es quien en última instancia sufre la pérdida.

La causa raíz radica en la lógica de negocio defectuosa de la función 0xb1a87f2c() en 0x560d39. Al recuperar el AFX obtenido mediante el intercambio de USDT a través del contrato 0x671ce4, la función no verifica el cambio en el saldo de AFX en 0x671ce4 antes y después del intercambio. En su lugar, retira todo el AFX que posee 0x671ce4.

Esto permite que un atacante done una gran cantidad de AFX a 0x671ce4 de antemano y luego invoque 0xb1a87f2c() con solo una pequeña cantidad de USDT. Dado que la cantidad de AFX obtenida de 0x146933 se define para coincidir con el AFX retirado de 0x671ce4, inflar el retiro de 0x671ce4 obliga directamente a 0x146933 a aportar una cantidad inflada de AFX en la adición de liquidez AFX-AHT.

El atacante puede recuperar su donación mediante los reembolsos de USDT y AFX restantes de 0x560d39, mientras que 0x146933 absorbe el costo de la provisión de liquidez sobredimensionada.

El atacante obtiene ganancias realizando un sándwich en la adición de liquidez AFX-AHT, ejecutando primero un intercambio de AFX a AHT y luego un intercambio de AHT a AFX alrededor de la transacción víctima.

Análisis del Ataque

Los pasos clave de la transacción de ataque se resumen a continuación:

  • Paso 1: El atacante obtuvo un préstamo flash de 1,130,500e18 tokens AFX en PancakeSwap V2.

  • Paso 2: El atacante transfirió 511,965e18 AFX al contrato 0x671ce4.

  • Paso 3: El atacante usó el AFX restante para intercambiarlo por 52,316e18 AHT en el pool AFX-AHT de PancakeSwap V2. Dado que AHT es un token con comisión en transferencia, el atacante finalmente recibió solo 26,158e18 AHT.

  • Paso 4: El atacante llamó al contrato 0x560d39, invocando la función 0xb1a87f2c() con el parámetro establecido en 100. Debido a que la función retiró todo el AFX de 0x671ce4 (incluidos los tokens donados por el atacante), intentó agregar una cantidad desproporcionadamente grande de liquidez tanto en los pares USDT-AFX como AFX-AHT. Cualquier USDT y AFX restante que no pudo ser emparejado fue reembolsado al atacante, permitiéndole recuperar la mayor parte de su costo.

  • Paso 5: El atacante intercambió 26,158e18 AHT por 1,129,417e18 AFX.

  • Paso 6: El atacante reembolsó el préstamo flash e intercambió el AFX restante por USDT, obteniendo una ganancia de ~$10K.

Conclusión

Este incidente fue causado porque el contrato 0x560d39 retira directamente todo el AFX del contrato 0x671ce4 al recuperar el AFX obtenido mediante el intercambio de USDT, sin verificar el cambio en el saldo de AFX del contrato 0x671ce4 antes y después del intercambio.


2. Incidente OCA

Breve Resumen

El 14 de febrero de 2026, un protocolo desconocido en BNB Smart Chain sufrió un exploit, resultando en una pérdida de ~$422K. La causa raíz fue una lógica de negocio defectuosa: tras completarse un intercambio, el protocolo llama a una función de reciclaje en el contrato del Token OCA para recuperar tokens del DEX y devolverlos al llamador y otras direcciones designadas. Esta retirada unilateral de Token OCA reduce artificialmente las reservas de OCA del pool, inflando su precio en cadena y permitiendo que un atacante drene USDC del pool repetidamente.

Antecedentes

El contrato del protocolo (0xe0d5ec) expone una función sellOCA() (selector 0x9c1dad28) que vende una cantidad de OCA especificada por el usuario a cambio de USDC en un DEX. OCA incluye un mecanismo deflacionario de "reciclaje": tras el intercambio, el contrato recupera la misma cantidad de OCA que acaba de venderse al pool y la redistribuye al llamador y otras direcciones designadas. Dado que el OCA se retira del pool después de que ya se ha pagado el USDC, las reservas de OCA del pool disminuyen mientras que sus reservas de USDC permanecen más bajas, lo que artificialmente eleva el precio de OCA en cadena.

Análisis de Vulnerabilidad

La vulnerabilidad central es que la recuperación posterior al intercambio en sellOCA() crea un mecanismo repetible de manipulación de precios. Cada invocación tiene el siguiente efecto neto sobre el pool del DEX: el pool pierde USDC durante el intercambio y también pierde OCA cuando el mecanismo deflacionario reclama tokens del pool, mientras que el llamador recibe los ingresos en USDC y recupera OCA mediante la redistribución. Dado que las reservas de OCA del pool se reducen sin ninguna entrada correspondiente de USDC para equilibrar el intercambio, cada ciclo infla artificialmente el precio de OCA/USDC en el DEX. Un atacante puede repetir este proceso comprando OCA, llamando a sellOCA() para activar la recuperación, y luego vendiendo el OCA recuperado al precio inflado, drenando progresivamente la liquidez de USDC del pool.

Análisis del Ataque

Los pasos clave de la transacción de ataque se resumen a continuación:

  • Paso 1: Se obtuvo un préstamo flash de 8,704,860e18 USDC.

  • Paso 2: Se intercambiaron 8,704,860e18 USDC por 940,991e18 OCA en PancakeSwap.

  • Paso 3: Se llamó a sellOCA() con todos los 940,991e18 OCA. La función intercambió el OCA por USDC en el DEX, luego el mecanismo de reciclaje deflacionario recuperó el OCA vendido del pool y lo redistribuyó, devolviendo OCA al llamador. Como resultado, el atacante recibió los ingresos en USDC del intercambio mientras también recuperaba sus tokens OCA. Las reservas de OCA del pool cayeron bruscamente, inflando el precio de OCA.

  • Paso 4: Se intercambiaron los 940,991e18 OCA recuperados de vuelta a USDC en PancakeSwap al precio ahora inflado, y se repitieron los pasos 2–4 para drenar progresivamente el pool.

  • Paso 5: En la iteración final, el atacante intercambió solo 9,999e18 OCA por 433,238e18 USDC (reflejando el precio masivamente inflado de OCA), luego reembolsó el préstamo flash para completar el exploit.

Conclusión

La causa fundamental de este exploit fue un fallo lógico en el flujo sellOCA del protocolo: tras intercambiar el OCA suministrado por el usuario por USDC, el contrato recuperaba esencialmente todo el OCA ingresado desde el DEX a través del mecanismo de ``recuperación'' deflacionaria de OCA y lo redistribuía al llamador y otras direcciones designadas. Esta recuperación posterior al intercambio redujo artificialmente el saldo de OCA que permanecía en el pool de liquidez, provocando que el precio en cadena de OCA se disparara bruscamente. Al ciclar repetidamente "comprar OCA → invocar sellOCA para activar la recuperación → vender OCA de vuelta al precio inflado", el atacante pudo extraer casi toda la liquidez de USDC con relativamente poco OCA.


3. Incidente SOF

Breve Resumen

El 14 de febrero de 2026, el token SOF en BNB Smart Chain fue explotado por ~$225K debido a un mecanismo de lista blanca incorrecto en su lógica _update() y su sistema de exención de comisiones. La vulnerabilidad permitió a un atacante eludir las restricciones de compra usando una dirección exenta de comisiones, activando posteriormente un mecanismo de quema al vender que manipuló las reservas del pool de Uniswap V2 (PancakeSwap). Al forzar al pool a transferir sus propios tokens a una dirección de quema e inmediatamente llamar a sync(), el atacante infló artificialmente el precio del token. Esto permitió drenar USDT del pool intercambiando una pequeña cantidad de SOF a la tasa manipulada. El exploit fue facilitado adicionalmente por una protección inadecuada contra préstamos flash que no rastreaba tx.origin, permitiendo que las fases de compra y venta del ataque ocurrieran dentro de la misma transacción usando múltiples direcciones.

Antecedentes

SOF es un token BEP-20 desplegado en BNB Smart Chain, diseñado con mecánicas deflacionarias personalizadas y gestión automatizada de comisiones. El token interactúa con un par de liquidez compatible con Uniswap V2 (específicamente PancakeSwap con USDT) para facilitar el trading.

Para los usuarios exentos de comisiones, las operaciones de compra y venta son gratuitas. Para todos los demás usuarios, las operaciones de compra están restringidas y serán revertidas.

Durante las operaciones de venta, el contrato transfiere el 90% del monto de venta del par a una _destroyAddress directamente y llama a sync() para actualizar inmediatamente las reservas y reflejar el saldo reducido.

Análisis de Vulnerabilidad

La causa raíz proviene del mecanismo de lista blanca defectuoso en la función _update() del contrato 0x1f3863 en la línea 438. Si la dirección to está en la lista blanca, cualquier from puede procesar una operación de compra.

 /// SOF.sol:433-480
433|      function _update(
434|          address from,
435|          address to,
436|          uint256 amount
437|      ) internal override {
438|          if (isExcludedFromFees[to] || isExcludedFromFees[from]) {
439|              super._update(from, to, amount);
440|              return;
441|          }
442|  
443|          require(!_blackList[from] && !_blackList[to], "refuse address");
444|  
445|          if (!inSwap && _isPairs[to]) {
446|              if (feeAmount1 >= swapTokensAtAmount) {
447|                  swapTokenForUsdt(feeAmount1, feeAddress);
448|                  feeAmount1 = 0;
449|              }
450|              if (feeAmount2 >= swapTokensAtAmount) {
451|                  swapTokenForUsdt(feeAmount2, feeAddress2);
452|                  feeAmount2 = 0;
453|              }
454|          }
455|  
456|          bool isSell;
457|          uint256 taxAmount;
458|  
459|          if (_isPairs[from]) {
460|              //buy
461|              revert("not alw buy");
462|          } else if (_isPairs[to]) {
463|              //sell
464|  
465|              isSell = true;
466|              taxAmount = takeFee(from, amount);
467|              super._update(_uniswapV2Pair, _destroyAddress, amount - taxAmount);
468|              IUniswapV2Pair(_uniswapV2Pair).sync();
469|          }
470|  
471|          emit TranserFeeLog(amount, taxAmount);
472|  
473|          if (isSell) {
474|              _antiFlashloanGuard(from, to, false, isSell);
475|          }
476|  
477|          amount = amount - taxAmount;
478|  
479|          super._update(from, to, amount);
480|      }

Análisis del Ataque

Los pasos clave de la transacción de ataque se resumen a continuación:

  • Paso 1: El atacante obtuvo un préstamo flash de 315,520,309e18 USDT para el paso 2, y transfirió 875e18 SOF a la dirección 0xc4DB5B para el paso 3.

  • Paso 2: Se intercambiaron 313,567,718e18 USDT por 991,223e18 SOF mediante swapTokensForExactTokens(). La dirección to era una dirección exenta de comisiones, lo que satisface la verificación isExcludedFromFees[to] en el contrato SOF, omitiendo así la verificación _isPairs[from] (de lo contrario, la operación de compra sería revertida). Esto permite al atacante quemar casi todo el token SOF en el pool en el Paso 3. Esto también elude la verificación _antiFlashloanGuard() — el contrato no registra esta operación de compra, permitiendo que el paso 3 proceda sin ser bloqueado. De manera crucial, esta compra masiva fue diseñada para dejar el par con solo 787e18 SOF (junto con 313,816,344e18 USDT).

  • Paso 3: Desde la dirección 0xc4DB5B, se intercambiaron 875e18 SOF por USDT mediante swapExactTokensForTokensSupportingFeeOnTransferTokens(). El Router V2 de PancakeSwap ejecuta primero SOF.transferFrom() y luego procesa el intercambio. Durante SOF.transferFrom(), la lógica de venta en _update() transfiere el 90% de 875e18 (es decir, 787e18) del par a _destroyAddress — que, tal como se diseñó en el paso 2, era casi todo el saldo de SOF del par. Tras esta quema y sync(), el par tenía 313,816,344e18 USDT y solo 10e9 SOF. Con el precio de SOF ahora astronómicamente inflado, el intercambio posterior generó un pago masivo de USDT.

  • Paso 4: El atacante reembolsó el préstamo flash y retuvo la ganancia de ~$225K.

Conclusión

La vulnerabilidad demuestra que para los tokens que admiten un mecanismo de quema antes de vender, controlar quién puede comprar el token es fundamental. Cualquiera capaz de vender el token puede obtener ganancias; si un atacante puede comprar tokens del pool, puede inflar artificialmente el precio y luego intercambiarlos de vuelta para drenar todo el pool.

La investigación señaló que la función _antiFlashloanGuard() está implementada incorrectamente. Solo restringe que el mismo msg.sender compre y venda, en lugar de rastrear el tx.origin. Esto permite a un atacante eludir la protección seleccionando una dirección exenta de comisiones como dirección to (receptora) durante la operación de compra.

Para prevenir exploits similares, los desarrolladores deben asegurarse de que solo los roles autorizados puedan comprar desde el pool. Además, la implementación de _antiFlashloanGuard() debe registrar tanto el tx.origin como la dirección del usuario para evitar que los atacantes usen múltiples direcciones para ejecutar operaciones de compra y venta dentro de la misma transacción.


Acerca de BlockSec

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

BlockSec ha publicado múltiples artículos de seguridad blockchain en conferencias prestigiosas, 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