Перейти к содержанию

Несоответствие десятичных разрядов оракула

Несоответствие разрядов применяет неверный масштаб единиц к ответу оракула, количеству токенов, курсу обертки или значению протокола, вызывая многопорядковые ошибки в займах, выпуске, погашении и ликвидации.

Обновлено

Только в образовательных целях; не является инвестиционным советом или инвестиционной рекомендацией. Инвестиции могут привести к убыткам.

Краткий ответ

Несоответствие десятичных разрядов оракула возникает, когда контракт интерпретирует исходное целое число с неверным показателем масштаба, направлением цены или внутренней шкалой. Разряды фида, токена и токена котировки, масштабы курса обертки или доли и принятые в протоколе форматы WAD либо RAY независимы. Правдоподобное отображение в интерфейсе не доказывает, что контракт-потребитель выполняет тот же расчет.

Для исходного количества базового токена A_raw с d_t разрядами и положительного ответа фида P_raw, котирующего один базовый токен в токенах котировки с d_p разрядами, исходное количество токена котировки с d_q разрядами равно V_raw = round(A_raw * P_raw * 10^d_q / 10^(d_t + d_p)). Формула верна только для указанного направления котировки и после проверки фида, единиц, типов и правила округления. Значение, уже нормализованное адаптером, нельзя масштабировать повторно.

Метод ERC-20 decimals() является необязательными метаданными отображения, а не всеобщей гарантией 18 разрядов. Метод decimals() фида описывает ответ этого фида, а не шкалу токена или протокола. Проверяемая арифметика может предотвратить переполнение откатом, но не обнаруживает формулу с неверной размерностью и способна вызвать отказ в обслуживании, если промежуточное произведение переполнится при представимом конечном результате.

Как это работает

  1. Зафиксируйте сеть, блок, потребителя, адаптер, прокси и агрегатор фида, токен или хранилище, версии компилятора и математической библиотеки, а также состояние обновления.
  2. Инвентаризируйте каждое целое число с типом и единицей: исходное количество токена, разряды токена, знаковый ответ фида, разряды фида, направление базового и котируемого активов, курс обертки или доли, внутренний масштаб протокола и разряды выходного токена.
  3. До преобразования проверьте источник: правильные адрес и направление, положительный ответ, время и статус, допустимые возраст и диапазон, семантику резервного источника и льготные правила секвенсора L2, если применимо.
  4. Выведите одну размерностную формулу от исходных единиц входа до исходных единиц выхода. Явно разделяйте повышение и понижение масштаба, ограничивайте каждый показатель степени десяти и нормализуйте каждое звено ровно один раз.
  5. Используйте доказанную операцию умножения-деления полной точности или ограниченную стратегию сокращения. Избегайте потери точности от деления до умножения, проверяемого переполнения промежуточного значения, непроверяемого зацикливания и небезопасных преобразований знака либо разрядности.
  6. Определите округление вниз, вверх или к ближайшему для каждого экономического действия. Обеспечение, долг, заимствование, выпуск, погашение, комиссии, ликвидация и конвертация долей хранилища могут требовать разных консервативных направлений.
  7. Проверяйте эталонные векторы и свойства на предельных количествах, сочетаниях разрядов, обратных и составных фидах, нулевых, отрицательных и устаревших ответах, обновлениях и пыли; сверяйте результаты в сети с независимой моделью высокой точности и ограничивайте затронутую экспозицию.

Нормализация — это анализ размерностей, а не форматирование. Для BTC/USD и USD/BTC нужны взаимно обратные формулы; замена подписи не обращает цену. Составные фиды требуют масштаба и времени каждого звена. Целочисленное деление Solidity усекает к нулю, поэтому алгебраически равносильные перестановки могут давать разные результаты в сети. Полноточный mulDiv решает проблему разрядности промежуточного результата, но вызывающая сторона все равно должна передать правильные числитель, знаменатель, единицы, границы и направление округления.

Примеры расчета

  • Восемь разрядов против восемнадцати. Фид BTC/USD возвращает 6,000,000,000,000 при d_p = 8, поэтому цена равна 60,000 USD/BTC. Интерпретация исходного ответа как 18-разрядного дает 0.000006 USD/BTC, то есть занижение в 10^10, а не 10^9 раз. Масштабирование цены до WAD дает 6,000,000,000,000 * 10^(18 - 8) = 60,000,000,000,000,000,000,000.
  • Единицы количества, цены и результата. A_raw = 2,500,000 означает 2.5 токена при d_t = 6; P_raw = 200,000,000 означает 2 токена котировки при d_p = 8. Для внутренней стоимости котировки с 18 разрядами 2,500,000 * 200,000,000 * 10^18 / 10^(6 + 8) = 5,000,000,000,000,000,000, то есть 5 quote tokens. Пропуск знаменателя токена завышает позицию в 10^6 раз.
  • Обратная цена и усечение. ETH/USD в масштабе WAD равен 2,000 * 10^18. USD/ETH в том же масштабе равен floor(10^36 / (2,000 * 10^18)) = 500,000,000,000,000, то есть 0.0005 ETH/USD. Отдельно при A_raw = 999,999, d_t = 6 и цене 2 * 10^18 полноточное умножение-деление дает 1,999,998,000,000,000,000; деление количества на 10^6 сначала дает 0 и теряет всю стоимость.
  • Промежуточное переполнение и округление. Пусть x = 2^200, y = 2^100, а знаменатель равен 2^100. Точный результат 2^200 помещается в uint256, однако x * y = 2^300 не помещается. Проверяемое умножение откатывается, непроверяемое зацикливается, а полноточный mulDiv возвращает 2^200. Целочисленное 5 / 2 округляется вниз до 2, тогда как округление вверх дает 3, поэтому правило округления входит в экономический инвариант.

Риски

  • Неверная сеть, фид, прокси, адаптер, токен, хранилище или адрес потребителя.
  • Направление базового и котируемого активов обращено без преобразования к обратной цене.
  • Разряды токена считаются равными 18 либо необязательные метаданные отсутствуют или ошибочны.
  • Разряды фида считаются равными 8 вместо чтения и фиксации.
  • Разряды токена котировки смешиваются со шкалой WAD, RAY, рынка или учета протокола.
  • Разряды обертки, доли, индекса или обменного курса пропущены.
  • Коэффициент масштаба применяется дважды после нормализации значения адаптером.
  • Необходимый коэффициент масштаба или знаменатель пропущен.
  • Знаковый ответ преобразуется в беззнаковый до проверки положительности.
  • Принимается нулевой, устаревший, незавершенный, ограниченный или недействительный ответ фида.
  • Показатель десятичной степени или расчет степени десяти уходит ниже нуля, переполняется или превышает границы.
  • Промежуточное произведение переполняется, хотя итоговый частный результат поместился бы.
  • Непроверяемая арифметика, битовые сдвиги или явное сужение незаметно зацикливают либо усекают значение.
  • Деление до умножения уничтожает точность или превращает пыль в ноль.
  • Округление вниз, вверх или к ближайшему неверно для экономического действия.
  • Повторные преобразования накапливают потерю точности или систематическую утечку стоимости.
  • Цены, лимиты, коэффициенты, проценты, базисные пункты, WAD и RAY сравниваются в разных единицах.
  • Обновления фида, токена, прокси, адаптера или хранилища делают закэшированные предположения о разрядах недействительными.
  • Форматирование интерфейса, кошелька, RPC или индексатора скрывает иной расчет в сети.
  • Ошибочная оценка усиливает заимствование, выпуск, погашение, ликвидацию, лимиты, безнадежный долг или несправедливый выпуск долей.

Распространенные заблуждения

  • «Каждый токен ERC-20 использует 18 разрядов». Метод метаданных ERC-20 необязателен, а развернутые активы используют разные значения и поведение.
  • «Каждый долларовый ценовой фид использует 8 разрядов». Точность фида — свойство интерфейса конкретного развертывания, которое нужно читать и версионировать.
  • «Большое исходное целое число доказывает манипуляцию». Исходная величина лишена смысла без единиц, направления, разрядов, времени и масштаба потребителя.
  • «Solidity 0.8 делает масштабирование правильным». Проверка переполнения может откатить транзакцию, но не исправляет неверные единицы, усечение, преобразование типов или политику округления.
  • «Умножение до деления или добавление разрядов всегда повышает точность». Это может вызвать переполнение, двойное масштабирование или сохранить неверную единицу; полноточной арифметике также нужна правильная формула.

Связанные темы

Источники

  • Data Feeds API Reference - Chainlink Documentation (дата обращения: 2026-08-13)
  • Chainlink Data Feeds - Chainlink Documentation (дата обращения: 2026-08-13)
  • ERC-20: Token Standard - Ethereum Improvement Proposals (дата обращения: 2026-08-13)
  • Types - Solidity Documentation (дата обращения: 2026-08-13)
  • Expressions and Control Structures - Solidity Documentation (дата обращения: 2026-08-13)
  • Utils - OpenZeppelin Contracts Documentation (дата обращения: 2026-08-13)
  • Oracles - Aave Protocol Documentation (дата обращения: 2026-08-13)
  • Compound v2 Price Feed - Compound Documentation (дата обращения: 2026-08-13)
Навигация

Поиск по вики...