Solo a scopo educativo; non costituisce consulenza né raccomandazione d’investimento. Gli investimenti possono comportare perdite.
Risposta diretta
Un disallineamento dei decimali dell’oracolo si verifica quando un contratto interpreta un intero grezzo con l’esponente dell’unità, la direzione del prezzo o la scala interna errati. I decimali del feed, del token e del token di quotazione, le scale dei tassi di wrapper o quote e le convenzioni WAD o RAY del protocollo sono indipendenti. Un frontend apparentemente corretto non dimostra che il contratto consumer esegua la stessa aritmetica.
Per una quantità grezza del token base A_raw con d_t decimali e una risposta positiva del feed P_raw che quota un token base in token di quotazione con d_p decimali, la quantità grezza del token di quotazione con d_q decimali è V_raw = round(A_raw * P_raw * 10^d_q / 10^(d_t + d_p)). La formula vale solo per la direzione indicata e dopo aver validato feed, unità, tipi e regola di arrotondamento. Un adapter che ha già normalizzato un valore non deve scalarlo di nuovo.
In ERC-20, decimals() è un metadato di visualizzazione facoltativo, non una garanzia universale di 18 decimali. Il decimals() di un feed descrive la risposta del feed, non la scala del token o del protocollo. L’aritmetica controllata può bloccare un overflow con un revert, ma non rileva una formula dimensionalmente errata e può trasformare un risultato rappresentabile in denial of service se trabocca un prodotto intermedio.
Come funziona
- Fissare chain, blocco, consumer, adapter, proxy e aggregatore del feed, token o vault, versioni del compilatore e della libreria matematica e stato dell’upgrade.
- Inventariare ogni intero con tipo e unità: quantità grezza, decimali del token, risposta con segno e decimali del feed, orientamento base/quotazione, tasso di wrapper o quota, scala interna e decimali del token di output.
- Validare la fonte prima della conversione: indirizzo e direzione corretti, risposta positiva, timestamp e stato, età e intervallo accettabili, semantica del fallback e regole del periodo di grazia del sequencer L2.
- Derivare un’unica formula dimensionale dalle unità grezze di input a quelle di output. Distinguere esplicitamente aumento e riduzione della scala, limitare ogni esponente di dieci e normalizzare ogni componente una sola volta.
- Usare un multiply-divide a precisione completa verificato o una cancellazione limitata. Evitare troncamento da divisione anticipata, overflow intermedio controllato, wraparound unchecked e cast con segno o restrittivi non sicuri.
- Specificare arrotondamento per difetto, eccesso o al più vicino per ogni azione. Garanzia, debito, prestito, emissione, rimborso, commissioni, liquidazione e conversione di quote possono richiedere direzioni conservative diverse.
- Testare vettori noti e proprietà su importi estremi, combinazioni di decimali, reciproci, feed composti, risposte nulle, negative e obsolete, upgrade e dust; riconciliare i risultati onchain con un modello indipendente ad alta precisione e limitare l’esposizione.
La normalizzazione è analisi dimensionale, non formattazione. BTC/USD e USD/BTC richiedono formule reciproche; cambiare etichetta non inverte un prezzo. I feed composti richiedono scala e timestamp di ogni componente. La divisione intera di Solidity tronca verso zero, quindi riordinamenti algebricamente equivalenti possono produrre risultati onchain diversi. Un mulDiv a precisione completa risolve il problema della larghezza intermedia, ma richiede comunque numeratore, denominatore, unità, limiti e direzione di arrotondamento corretti.
Esempi svolti
- Otto contro diciotto decimali. Un feed BTC/USD restituisce
6,000,000,000,000cond_p = 8, quindi il prezzo è60,000 USD/BTC. Interpretare la risposta grezza a 18 decimali produce0.000006 USD/BTC, una sottovalutazione di10^10, non10^9. La scalatura a WAD dà6,000,000,000,000 * 10^(18 - 8) = 60,000,000,000,000,000,000,000. - Unità di quantità, prezzo e output.
A_raw = 2,500,000rappresenta2.5token cond_t = 6;P_raw = 200,000,000rappresenta2token di quotazione cond_p = 8. Per un valore interno a 18 decimali,2,500,000 * 200,000,000 * 10^18 / 10^(6 + 8) = 5,000,000,000,000,000,000, ossia5 quote tokens. Omettere il denominatore del token sopravvaluta la posizione di10^6. - Reciproco e troncamento. ETH/USD in scala WAD è
2,000 * 10^18. USD/ETH alla stessa scala èfloor(10^36 / (2,000 * 10^18)) = 500,000,000,000,000, ossia0.0005 ETH/USD. Separatamente, conA_raw = 999,999,d_t = 6e prezzo2 * 10^18, il multiply-divide completo produce1,999,998,000,000,000,000; dividere prima la quantità per10^6produce0e perde tutto il valore. - Overflow intermedio e arrotondamento. Siano
x = 2^200,y = 2^100e il denominatore2^100. Il risultato esatto2^200rientra inuint256, max * y = 2^300no. La moltiplicazione controllata effettua revert e quella unchecked va in wrap;mulDiva precisione completa restituisce2^200. La divisione intera5 / 2arrotonda per difetto a2, mentre una regola per eccesso restituisce3; l’arrotondamento fa quindi parte dell’invariante economica.
Rischi
- Indirizzo errato di chain, feed, proxy, adapter, token, vault o consumer.
- Orientamento base/quotazione invertito senza conversione reciproca.
- Si presumono 18 decimali del token oppure i metadati facoltativi sono assenti o errati.
- Si presumono 8 decimali del feed anziché leggerli e fissarli.
- I decimali del token di quotazione sono confusi con scala WAD, RAY, di mercato o contabile.
- Decimali di wrapper, quota, indice o tasso di cambio omessi.
- Fattore di scala applicato due volte dopo la normalizzazione dell’adapter.
- Fattore di scala o denominatore necessario omesso.
- Risposta con segno convertita in unsigned prima di verificarne la positività.
- Risultato nullo, obsoleto, incompleto, limitato o non valido accettato.
- Esponente decimale o potenza di dieci va in underflow, overflow o supera i limiti.
- Prodotto intermedio va in overflow sebbene il quoziente finale sia rappresentabile.
- Aritmetica unchecked, bit shift o narrowing cast effettuano wrap o troncano silenziosamente.
- Dividere prima di moltiplicare distrugge precisione o riduce il dust a zero.
- Arrotondamento per difetto, eccesso o al più vicino errato per l’azione.
- Conversioni ripetute accumulano perdita di precisione o dispersione sistematica di valore.
- Prezzi, cap, rapporti, percentuali, punti base, WAD e RAY sono confrontati in unità diverse.
- Upgrade di feed, token, proxy, adapter o vault invalidano ipotesi sui decimali in cache.
- Formattazione di frontend, wallet, RPC o indexer nasconde un calcolo onchain diverso.
- Valutazione errata amplifica prestiti, emissioni, rimborsi, liquidazioni, cap, crediti inesigibili o emissione iniqua di quote.
Idee errate comuni
- «Ogni token ERC-20 usa 18 decimali». Il metodo dei metadati ERC-20 è facoltativo e gli asset implementati usano valori e comportamenti differenti.
- «Ogni feed di prezzo in USD usa 8 decimali». La precisione è una proprietà dell’interfaccia dello specifico deployment e deve essere letta e versionata.
- «Un grande intero grezzo dimostra manipolazione». La grandezza non significa nulla senza unità, direzione, decimali, timestamp e scala del consumer.
- «Solidity 0.8 rende corretta la scalatura». L’overflow controllato può effettuare revert, ma non corregge unità, troncamento, cast o regole di arrotondamento.
- «Moltiplicare prima di dividere o aggiungere decimali migliora sempre la precisione». Può causare overflow, doppia scalatura o preservare l’unità errata; anche l’aritmetica a precisione completa richiede la formula corretta.
Argomenti correlati
Fonti
- Data Feeds API Reference - Chainlink Documentation (consultato: 2026-08-13)
- Chainlink Data Feeds - Chainlink Documentation (consultato: 2026-08-13)
- ERC-20: Token Standard - Ethereum Improvement Proposals (consultato: 2026-08-13)
- Types - Solidity Documentation (consultato: 2026-08-13)
- Expressions and Control Structures - Solidity Documentation (consultato: 2026-08-13)
- Utils - OpenZeppelin Contracts Documentation (consultato: 2026-08-13)
- Oracles - Aave Protocol Documentation (consultato: 2026-08-13)
- Compound v2 Price Feed - Compound Documentation (consultato: 2026-08-13)