Zum Inhalt springen

Abweichende Dezimalstellen bei Oracles

Eine Dezimalstellenabweichung wendet den falschen Einheitenmaßstab auf Oracle-Antwort, Token-Menge, Wrapper-Kurs oder Protokollwert an und verursacht Größenordnungsfehler bei Krediten, Prägungen, Rücknahmen und Liquidationen.

Aktualisiert

Nur zu Bildungszwecken; stellt keine Anlageberatung oder Anlageempfehlung dar. Anlagen können zu Verlusten führen.

Direkte Antwort

Eine Oracle-Dezimalstellenabweichung liegt vor, wenn ein Vertrag eine rohe Ganzzahl mit falschem Einheitenexponenten, falscher Preisrichtung oder falschem internen Maßstab interpretiert. Dezimalstellen von Feed, Token und Quotierungs-Token, Wechselkursskalen von Wrappern oder Anteilen sowie WAD- oder RAY-Konventionen des Protokolls sind unabhängig. Eine korrekt wirkende Oberfläche beweist nicht, dass der Verbraucher dieselbe Arithmetik ausführt.

Für eine rohe Basis-Token-Menge A_raw mit d_t Dezimalstellen und eine positive Feed-Antwort P_raw, die ein Basis-Token in Quotierungs-Token mit d_p Dezimalstellen bewertet, lautet die rohe Quotierungs-Token-Menge mit d_q Dezimalstellen V_raw = round(A_raw * P_raw * 10^d_q / 10^(d_t + d_p)). Die Formel gilt nur für diese Preisrichtung und nach Prüfung von Feed, Einheiten, Typen und Rundungsregel. Ein bereits vom Adapter normalisierter Wert darf nicht erneut skaliert werden.

ERC-20-decimals() sind optionale Anzeigemetadaten, keine universelle Garantie für 18 Dezimalstellen. Die decimals() eines Feeds beschreiben dessen Antwort, nicht Token- oder Protokollskala. Geprüfte Arithmetik kann bei Überlauf revertieren, erkennt aber keine dimensional falsche Formel und kann bei überlaufendem Zwischenprodukt aus einem darstellbaren Ergebnis einen Denial of Service machen.

Funktionsweise

  1. Chain, Block, Verbraucher, Adapter, Feed-Proxy und Aggregator, Token oder Vault, Compiler- und Mathematikbibliotheksversionen sowie Upgrade-Stand festlegen.
  2. Jede Ganzzahl mit Typ und Einheit erfassen: rohe Token-Menge, Token-Dezimalstellen, vorzeichenbehaftete Feed-Antwort, Feed-Dezimalstellen, Basis-/Quotierungsrichtung, Wrapper- oder Anteilskurs, interne Protokollskala und Dezimalstellen des Ausgabe-Tokens.
  3. Quelle vor der Umrechnung prüfen: richtige Adresse und Richtung, positive Antwort, Zeitstempel und Status, zulässiges Alter und Intervall, Rückfallsemantik und gegebenenfalls L2-Sequencer-Karenzregeln.
  4. Eine dimensionale Formel von rohen Eingabe- zu rohen Ausgabeeinheiten herleiten. Hoch- und Herunterskalierung ausdrücklich verzweigen, jeden Zehnerpotenzexponenten begrenzen und jedes Glied genau einmal normalisieren.
  5. Bewährtes Multiply-divide mit voller Genauigkeit oder begrenzte Kürzung verwenden. Division vor Multiplikation, geprüften Zwischenüberlauf, ungeprüften Wraparound und unsichere vorzeichenbehaftete oder verengende Casts vermeiden.
  6. Abrunden, Aufrunden oder nächste Rundung für jede wirtschaftliche Aktion festlegen. Sicherheiten, Schulden, Kreditaufnahme, Prägung, Rücknahme, Gebühren, Liquidation und Anteilskonvertierung können unterschiedliche konservative Richtungen erfordern.
  7. Referenzvektoren und Eigenschaften mit Extrembeträgen, Dezimalkombinationen, Kehrwerten, zusammengesetzten Feeds, Null-, Negativ- und veralteten Antworten, Upgrades und Dust testen; Onchain-Ergebnisse mit einem unabhängigen Hochpräzisionsmodell abstimmen und betroffene Exposition begrenzen.

Normalisierung ist Dimensionsanalyse, keine Formatierung. BTC/USD und USD/BTC erfordern Kehrwertformeln; eine geänderte Bezeichnung invertiert keinen Preis. Zusammengesetzte Feeds benötigen Skala und Zeitstempel jedes Glieds. Ganzzahldivision in Solidity schneidet gegen null ab, sodass algebraisch gleichwertige Umstellungen andere Onchain-Ergebnisse liefern können. mulDiv mit voller Genauigkeit löst das Zwischenbreitenproblem, verlangt aber weiterhin korrekte Zähler, Nenner, Einheiten, Grenzen und Rundungsrichtung.

Durchgerechnete Beispiele

  • Acht gegenüber achtzehn Dezimalstellen. Ein BTC/USD-Feed liefert 6,000,000,000,000 mit d_p = 8, also 60,000 USD/BTC. Als 18 Dezimalstellen interpretiert ergibt die Antwort 0.000006 USD/BTC, eine Unterbewertung um 10^10, nicht 10^9. Auf WAD skaliert ergibt sich 6,000,000,000,000 * 10^(18 - 8) = 60,000,000,000,000,000,000,000.
  • Mengen-, Preis- und Ausgabeeinheiten. A_raw = 2,500,000 steht für 2.5 Token bei d_t = 6; P_raw = 200,000,000 steht für 2 Quotierungs-Token bei d_p = 8. Für einen internen Quotierungswert mit 18 Dezimalstellen gilt 2,500,000 * 200,000,000 * 10^18 / 10^(6 + 8) = 5,000,000,000,000,000,000, also 5 quote tokens. Ohne Token-Nenner wird die Position um 10^6 überbewertet.
  • Kehrwert und Abschneiden. ETH/USD auf WAD-Skala ist 2,000 * 10^18. USD/ETH auf derselben Skala ist floor(10^36 / (2,000 * 10^18)) = 500,000,000,000,000, also 0.0005 ETH/USD. Bei A_raw = 999,999, d_t = 6 und Preis 2 * 10^18 liefert vollständiges Multiply-divide 1,999,998,000,000,000,000; vorherige Division der Menge durch 10^6 ergibt 0 und vernichtet den gesamten Wert.
  • Zwischenüberlauf und Rundung. Sei x = 2^200, y = 2^100 und der Nenner 2^100. Das exakte Ergebnis 2^200 passt in uint256, x * y = 2^300 jedoch nicht. Geprüfte Multiplikation revertiert, ungeprüfte wickelt um; mulDiv mit voller Genauigkeit liefert 2^200. Ganzzahliges 5 / 2 rundet auf 2 ab, eine Aufrundungsregel auf 3; Rundung ist daher Teil der wirtschaftlichen Invariante.

Risiken

  • Falsche Chain-, Feed-, Proxy-, Adapter-, Token-, Vault- oder Verbraucheradresse.
  • Umgekehrte Basis-/Quotierungsrichtung ohne Kehrwertumrechnung.
  • 18 Token-Dezimalstellen angenommen oder optionale Metadaten fehlen beziehungsweise sind falsch.
  • Acht Feed-Dezimalstellen angenommen, statt sie auszulesen und festzuhalten.
  • Quotierungs-Token-Dezimalstellen mit WAD-, RAY-, Markt- oder Buchhaltungsskala verwechselt.
  • Wrapper-, Anteil-, Index- oder Wechselkursdezimalstellen ausgelassen.
  • Skalenfaktor nach Adapter-Normalisierung doppelt angewendet.
  • Erforderlicher Skalenfaktor oder Nenner ausgelassen.
  • Vorzeichenbehaftete Antwort vor Positivitätsprüfung in unsigned umgewandelt.
  • Null-, veraltetes, unvollständiges, begrenztes oder ungültiges Feed-Ergebnis angenommen.
  • Dezimalexponent oder Zehnerpotenz unterläuft, überläuft oder überschreitet Grenzen.
  • Zwischenprodukt überläuft, obwohl der Endquotient passt.
  • Unchecked-Arithmetik, Bitverschiebungen oder Verengungen wickeln um oder schneiden still ab.
  • Division vor Multiplikation vernichtet Präzision oder macht Dust zu null.
  • Falsche Abrundung, Aufrundung oder nächste Rundung für die wirtschaftliche Aktion.
  • Wiederholte Umrechnungen summieren Präzisionsverlust oder systematische Wertabflüsse.
  • Preise, Obergrenzen, Verhältnisse, Prozente, Basispunkte, WAD und RAY werden in verschiedenen Einheiten verglichen.
  • Feed-, Token-, Proxy-, Adapter- oder Vault-Upgrades entwerten gespeicherte Dezimalannahmen.
  • Frontend-, Wallet-, RPC- oder Indexer-Formatierung verdeckt eine andere Onchain-Berechnung.
  • Fehlbewertung verstärkt Kredite, Prägung, Rücknahme, Liquidation, Limits, uneinbringliche Schulden oder unfaire Anteilsausgabe.

Häufige Missverständnisse

  • „Jeder ERC-20-Token verwendet 18 Dezimalstellen.“ Die Metadatenmethode ist optional; eingesetzte Assets verwenden unterschiedliche Werte und Verhaltensweisen.
  • „Jeder USD-Preis-Feed verwendet acht Dezimalstellen.“ Die Genauigkeit ist eine Schnittstelleneigenschaft des konkreten Deployments und muss gelesen und versioniert werden.
  • „Eine große rohe Ganzzahl beweist Manipulation.“ Ohne Einheiten, Richtung, Dezimalstellen, Zeitstempel und Verbraucherskala ist ihre Größe bedeutungslos.
  • „Solidity 0.8 macht Skalierung korrekt.“ Geprüfter Überlauf kann revertieren, korrigiert aber keine Einheiten, Abschneidung, Casts oder Rundungsregeln.
  • „Multiplikation vor Division oder mehr Dezimalstellen verbessert stets die Genauigkeit.“ Das kann überlaufen, doppelt skalieren oder die falsche Einheit bewahren; auch volle Genauigkeit braucht eine korrekte Formel.

Verwandte Themen

Quellen

Navigation

Wiki durchsuchen...