Перейти к основному содержанию
В этом руководстве мы разберёмся в первопричине сбоя транзакции и проверим исправление. Рассмотрим транзакцию Uniswap. Эта транзакция пытается выполнить swapExactTokensForTokens.
1
Вставьте хеш транзакции в поиске Tenderly dashboard
2
Хеш транзакции: 0xbe082dcc8ae59868f5b2330173902bb88c6643b5c2fdf0d8a9f43d03dbca0c36
3
Изучите ошибку
4
Revert произошёл в swapExactTokensForTokens, при проверке условия, включающего amountOutMin — входной параметр. Она откатилась со следующим сообщением об ошибке: Сообщение об ошибке: UniswapV2Router: INSUFFICIENT_OUTPUT_AMOUNT
5
Из раздела inputs видно, что amountOutMin имел значение 1102820622890207119.
6
7
Изучите условие revert
8
Перейдите в представление debugger. Обратите внимание, что require использует amounts[amounts.length - 1].
9
10
Вычислите выражение
11
Чтобы получить значение этого выражения, можно использовать Evaluate:
12
  • Убедитесь, что debugger находится на строке revert,
  • Вставьте выражение `amounts[amounts.length - 1],
  • Нажмите кнопку «Evaluate».
  • 13
    Значение: Значение — 1029855063181377015.
    14
    15
    Получите значение из информации о вызове
    16
    Значение рассматриваемого выражения также можно извлечь, проанализировав функцию, которая его сформировала:
    17
  • Переместите debugger на getAmountsOut из Execution trace слева
  • Найдите output в нижней панели
  • Поскольку выражение amounts[amounts.length - 1] получает последний элемент массива, заключаем, что искомое значение — 1029855063181377015.
  • 18
    19
    Возможное решение
    20
    Эта транзакция была бы успешной, если бы значение amountOutMin было 1029855063181377015.
    21
    Проверка решения
    22
    Чтобы проверить решение, нажмите кнопку «Re-Simulate»:
    23
  • Вставьте значение 1029855063181377015 во второй аргумент
  • Нажмите Simulate.
  • 24
    Симуляция прошла успешно — значит, мы нашли правильное значение аргумента.
    25
    Swap-транзакции чувствительны ко времени, они учитывают значение block.timestamp. Симуляции по умолчанию выполняются на исходном блоке и с исходным timestamp. Только если вам нужны кастомные значения блока и timestamp, можно использовать для этого переопределения заголовка блока.