Solo con fines educativos; no constituye asesoramiento de inversión. Invertir puede ocasionar pérdidas.
Respuesta directa
Un desajuste de decimales de un oráculo se produce cuando un contrato interpreta un entero bruto con un exponente de unidad, una dirección del precio o una escala interna incorrectos. Los decimales del feed, del token y del token cotizado, las escalas del tipo de cambio de un wrapper o de participaciones y las convenciones WAD o RAY del protocolo son independientes. Que una interfaz muestre un valor correcto no demuestra que el contrato consumidor aplique la misma aritmética.
Para un importe del token base A_raw con d_t decimales y una respuesta positiva del feed P_raw que cotiza un token base en tokens cotizados con d_p decimales, un importe bruto del token cotizado con d_q decimales es V_raw = round(A_raw * P_raw * 10^d_q / 10^(d_t + d_p)). La fórmula solo es válida para la dirección de cotización indicada y tras validar feed, unidades, tipos y regla de redondeo. Un adaptador que ya normalizó un valor no debe volver a escalarlo.
En ERC-20, decimals() son metadatos de visualización opcionales, no una garantía universal de 18 decimales. Los decimals() de un feed describen su respuesta, no la escala del token ni la del protocolo. La aritmética comprobada puede detener un desbordamiento mediante revert, pero no detecta una fórmula dimensionalmente errónea y puede convertir un resultado representable en una denegación de servicio si desborda un producto intermedio.
Cómo funciona
- Fije cadena, bloque, consumidor, adaptador, proxy y agregador del feed, token o vault, versiones del compilador y de la biblioteca matemática y estado de actualización.
- Inventaríe cada entero con su tipo y unidad: importe bruto del token, decimales del token, respuesta con signo del feed, decimales del feed, orientación base/cotizada, tasa del wrapper o participación, escala interna del protocolo y decimales del token de salida.
- Valide la fuente antes de convertir: dirección y sentido correctos, respuesta positiva, timestamp y estado, antigüedad e intervalo aceptables, semántica del fallback y reglas de gracia del secuenciador L2 cuando proceda.
- Derive una única fórmula dimensional desde las unidades brutas de entrada hasta las de salida. Separe explícitamente el aumento y la reducción de escala, acote cada exponente de potencia de diez y normalice cada componente exactamente una vez.
- Use una multiplicación-división de precisión completa demostrada o una cancelación acotada. Evite el truncamiento por dividir antes de multiplicar, el desbordamiento intermedio comprobado, el wraparound no comprobado y las conversiones con signo o estrechas inseguras.
- Especifique redondeo hacia abajo, arriba o al más próximo para cada acción económica. Garantía, deuda, préstamo, acuñación, reembolso, comisiones, liquidación y conversiones de participaciones pueden requerir sentidos conservadores distintos.
- Pruebe vectores conocidos y propiedades con importes extremos, combinaciones de decimales, recíprocos, feeds compuestos, respuestas cero, negativas y obsoletas, actualizaciones y dust; concilie los resultados onchain con un modelo independiente de alta precisión y limite la exposición afectada.
La normalización es análisis dimensional, no formato. BTC/USD y USD/BTC requieren fórmulas recíprocas; cambiar una etiqueta no invierte el precio. Los feeds compuestos exigen la escala y el timestamp de cada componente. La división entera de Solidity trunca hacia cero, por lo que reordenamientos algebraicamente equivalentes pueden producir resultados onchain distintos. Un mulDiv de precisión completa resuelve el ancho intermedio, pero quien lo invoca aún debe proporcionar numerador, denominador, unidades, límites y sentido de redondeo correctos.
Ejemplos resueltos
- Ocho frente a dieciocho decimales. Un feed BTC/USD devuelve
6,000,000,000,000cond_p = 8, por lo que el precio es60,000 USD/BTC. Interpretar la respuesta bruta con 18 decimales da0.000006 USD/BTC, una infravaloración por10^10, no por10^9. Escalar el precio a WAD da6,000,000,000,000 * 10^(18 - 8) = 60,000,000,000,000,000,000,000. - Unidades de importe, precio y salida.
A_raw = 2,500,000representa2.5tokens cond_t = 6;P_raw = 200,000,000representa2tokens cotizados cond_p = 8. Para un valor cotizado interno de 18 decimales,2,500,000 * 200,000,000 * 10^18 / 10^(6 + 8) = 5,000,000,000,000,000,000, o5 quote tokens. Omitir el denominador del token sobrevalora la posición por10^6. - Recíproco y truncamiento. ETH/USD a escala WAD es
2,000 * 10^18. USD/ETH a la misma escala esfloor(10^36 / (2,000 * 10^18)) = 500,000,000,000,000, o0.0005 ETH/USD. Por separado, conA_raw = 999,999,d_t = 6y precio2 * 10^18, la multiplicación-división completa da1,999,998,000,000,000,000; dividir primero el importe por10^6da0y pierde todo el valor. - Desbordamiento intermedio y redondeo. Sean
x = 2^200,y = 2^100y el denominador2^100. El resultado exacto es2^200, que cabe enuint256, perox * y = 2^300no. La multiplicación comprobada revierte y la no comprobada hace wrap; unmulDivde precisión completa devuelve2^200. La división entera5 / 2redondea hacia abajo a2, mientras que una regla de techo devuelve3, de modo que el redondeo forma parte del invariante económico.
Riesgos
- Cadena, feed, proxy, adaptador, token, vault o consumidor incorrectos.
- Orientación base/cotizada invertida sin conversión recíproca.
- Se supone que el token tiene 18 decimales o sus metadatos opcionales no están disponibles o son erróneos.
- Se supone que el feed tiene 8 decimales en vez de leerlos y fijarlos.
- Se confunden los decimales del token cotizado con la escala WAD, RAY, de mercado o contable del protocolo.
- Se omiten los decimales del wrapper, participación, índice o tasa de cambio.
- Se aplica dos veces un factor después de que el adaptador ya haya normalizado el valor.
- Se omite un factor de escala o denominador necesario.
- Una respuesta con signo se convierte a unsigned antes de verificar que sea positiva.
- Se acepta una respuesta cero, obsoleta, incompleta, limitada o inválida.
- Un exponente decimal o potencia de diez sufre underflow, overflow o excede los límites.
- Un producto intermedio desborda aunque el cociente final quepa.
- Aritmética unchecked, desplazamientos de bits o estrechamientos explícitos hacen wrap o truncan silenciosamente.
- Dividir antes de multiplicar destruye precisión o convierte dust en cero.
- El redondeo hacia abajo, arriba o al más próximo es incorrecto para la acción económica.
- Conversiones repetidas acumulan pérdida de precisión o fuga sistemática de valor.
- Precios, límites, ratios, porcentajes, puntos básicos, WAD y RAY se comparan en unidades distintas.
- Actualizaciones de feed, token, proxy, adaptador o vault invalidan supuestos de decimales almacenados.
- El formato de interfaz, wallet, RPC o indexador oculta un cálculo onchain diferente.
- La valoración errónea amplifica préstamos, acuñaciones, reembolsos, liquidaciones, límites, deuda incobrable o emisión injusta de participaciones.
Errores frecuentes
- «Todos los tokens ERC-20 usan 18 decimales». El método de metadatos ERC-20 es opcional y los activos desplegados emplean valores y comportamientos distintos.
- «Todos los feeds de precios en USD usan 8 decimales». La precisión es una propiedad de interfaz del despliegue exacto y debe leerse y versionarse.
- «Un entero bruto grande demuestra manipulación». Su magnitud carece de significado sin unidades, dirección, decimales, timestamp y escala del consumidor.
- «Solidity 0.8 hace correcto el escalado». El overflow comprobado puede revertir, pero no corrige unidades, truncamiento, conversiones ni política de redondeo.
- «Multiplicar antes de dividir o añadir decimales siempre mejora la precisión». Puede desbordar, duplicar la escala o conservar una unidad incorrecta; incluso la aritmética de precisión completa exige una fórmula correcta.
Temas relacionados
Fuentes
- Data Feeds API Reference - Chainlink Documentation (consulta: 2026-08-13)
- Chainlink Data Feeds - Chainlink Documentation (consulta: 2026-08-13)
- ERC-20: Token Standard - Ethereum Improvement Proposals (consulta: 2026-08-13)
- Types - Solidity Documentation (consulta: 2026-08-13)
- Expressions and Control Structures - Solidity Documentation (consulta: 2026-08-13)
- Utils - OpenZeppelin Contracts Documentation (consulta: 2026-08-13)
- Oracles - Aave Protocol Documentation (consulta: 2026-08-13)
- Compound v2 Price Feed - Compound Documentation (consulta: 2026-08-13)