1 декабря 2021
UMA — это платформа, которая позволяет пользователям заключать финансовые контракты с минимальным доверием в блокчейне Ethereum. Ранее мы проверяли децентрализованный оракул, конкретный шаблон финансового контракта, некоторые специальные запросы на включение, шаблон «Вечная многопартийность» и различные дополнительные запросы на включение в течение более длительного взаимодействия. В этом аудите мы рассмотрели новый механизм быстрой отправки токенов из цепочки уровня 2 в основную сеть Ethereum и связанные с ним изменения в Optimistic Oracle. Проверка была завершена двумя аудиторами в течение 2 недель.
Объем
Проверяемый коммит f24ad501c8e813cf685f72217e7f13c8f3c366df
и объем включает следующие контракты:
- контракты/insured-bridge/* (исключая тестовые контракты)
- контракты-овм/insured-bridge/реализация/*
- контракты/common/реализация/AncillaryData.sol
- контракты/оракул/реализация/SkinnyOptimisticOracle.sol
Мы также рассмотрели изменения в файлах Solidity в Запрос на извлечение 3445.
Предполагалось, что весь внешний код и зависимости контрактов работают, как задокументировано.
Системный Обзор
Поддерживаемые цепочки уровня 2 (L2), Optimism и Arbitrum, предоставляют механизм перевода средств в основную сеть Ethereum (L1). Однако по соображениям безопасности существует значительная задержка, прежде чем эта передача будет завершена. Чтобы решить эту проблему, держатели токенов L2 могут внести средства в контракт UMA, «депозитный ящик», зная, что токены в конечном итоге будут переведены (как пакет) в контракт UMA L1, «мостовой пул». Для каждого передаваемого токена существует отдельный пул Bridge Pool.
После внесения депозита L2 любой может передать данные в пул мостов L1, который ждет короткий период времени на случай, если кто-то захочет оспорить переданную информацию. Все споры рассматриваются Тощим Оптимистическим Оракулом (описано ниже). Прежде чем принять ретрансляцию, поставщики ликвидности должны предварительно профинансировать контракт Bridge Pool в обмен на токены LP. Бесспорные ретрансляторы считаются действительными, и мостовой пул завершает перевод, используя свои собственные резервы, при этом часть перевода перенаправляется ретранслятору, а часть сохраняется в качестве комиссий за ликвидность. Средства в конечном итоге будут пополнены после завершения депозита L2, а держателям токенов LP будет назначена комиссия за ликвидность.
Бридж-пул также позволяет любому индивидуально финансировать перевод (без резервов Бридж-пула) до истечения периода спора в обмен на часть суммы перевода. Поскольку реле все еще можно оспорить, эти средства будут потеряны, если реле будет признано неправильным. Ожидается, что в большинстве случаев этот механизм позволит пользователям осуществлять немедленную передачу токенов L2-L1.
Тощий оптимистический оракул концептуально очень похож на существующего оптимистического оракула. Он предоставляет пользователям механизм стимулирования просто утверждать результат запроса оракула, который считается точным, если не оспаривается. Споры разрешаются более медленным механизмом DVM, описанным в наших предыдущих аудиторских отчетах. Основное отличие состоит в том, что новая версия требует от пользователей предоставления всей необходимой информации при выполнении вызовов функций, поэтому значения не нужно сохранять или извлекать из хранилища. Это также лишает инициаторов запроса возможности изменять параметры конфигурации в активных запросах.
Ранее мы рассмотрели контракт Long-Short-Pair, который предоставляет общий механизм для создания различных финансовых инструментов. Эти контракты могут быть решены, когда истечет срок их действия и станет известна расчетная цена. Изменения, внесенные Pull Request 3445, предоставляют возможность досрочного разрешения контрактов, если расчетная цена известна до истечения срока действия.
Привилегированные роли
Депозитные ячейки L2 имеют несколько параметров конфигурации, включая поддерживаемые токены и максимальную скорость отправки пакетных токенов через мост в L1. Их также необходимо настроить для обеспечения согласованности между контрактом токена L1, контрактом токена L2 и соответствующим пулом мостов. Эти параметры устанавливаются контрактом администратора на уровне L1, который также параметризирует процесс разрешения споров в пулах мостов. Ожидается, что контракт будет контролироваться механизмом управления UMA, поэтому пользователи должны доверять этому процессу, чтобы управлять системой разумно и справедливо.
Экосистемные зависимости
Все рассмотренные компоненты используют логику, основанную на времени, что означает, что они зависят от доступности Ethereum. В частности, если спорные транзакции существенно задерживаются, недействительные реле или ценовые предложения могут быть неправильно подтверждены.
Кроме того, токен-мост неявно предполагает, что все средства, отправленные в депозитные ячейки L2, в конечном итоге будут переведены в соответствующий пул моста L1. Это зависит от правильного и постоянного функционирования мостов Оптимизма и Арбитрума, а также их механизмов разрешения споров.
Наконец, токены, отправленные в депозитный ящик L2, назначаются мостовому пулу в L1, а не предполагаемому получателю. Чтобы получить средства из пула, держатели токенов L1 должны сначала сопоставить их с дополнительными токенами. Таким образом, механизм опирается на достаточно глубокий рынок токенов L1, чтобы обеспечить всегда наличие ликвидности.
Проблемы, о которых сообщил клиент
В ходе аудита команда UMA независимо выявила ряд проблем и особенностей поведения, на которые стоит обратить внимание:
Если параметры Optimistic Oracle или Bridge Admin изменяются в течение периода оспаривания ретранслятора, то при оспаривании ретранслятора ретранслятор удаляется без каких-либо дополнительных обращений ни для предлагающего, ни для спорящего. Например, представьте, что реле отправляется для залогового токена.
TOKEN_A
, но в середине эстафетыTOKEN_A
удаляется из белого списка обеспечения. Теперь спор будет возобновлен, поскольку вы не сможете подавать какие-либо ценовые запросы ОО или DVM в отношении обеспечения, не включенного в белый список. Поскольку мы не хотим блокировать действительные запросы на оспаривание,BridgePool
удалит ожидающее реле дляTOKEN_A
в случае спора. Последствиями такого дизайнерского решения являются:
1. Увеличение окончательной комиссии приведет к тому, что: Любая незавершенная передача по этому токену будет «отменена» из-за спора о том, правильная или неправильная. Отмена не приносит преимуществ ни одной из сторон, поэтому она предполагает наличие честных спорщиков, которые готовы уничтожить (редкий) неверный запрос, который случается во время окончательного изменения размера комиссии. Это также означает, что грифер может потратить бензин на отмену реле и принудительное их повторное реле.
2. Удаление идентификатора или токена из белого списка, чего не должно происходить, если только что-то не пойдет не так, может привести к:
3. Длительный период бесспорных запросов, когда любой запрос может быть отменен и нет никаких экономических стимулов для оспаривания. Это кажется лучше, чем альтернатива полной блокировки споров, но, по общему признанию, это довольно плохо, поскольку любой грифер может блокировать ретрансляторы на неопределенный срок, заплатив бензин, или отправлять плохие ретрансляторы без наказания (кроме платы за газ).Примечание: это альтернатива ОО, которая «замораживает» на некоторое время такие параметры, как окончательная комиссия или белый список обеспечения, но это потребует дополнительных вызовов ОО, что будет дорого стоить для счастливого пути.
Реле можно ускорить с помощью
speedUpRelay()
после того, как они пройдут жизнеспособность. Хотя мы не видим в этом какого-либо риска, это открывает возможность получения срочных кредитов + ускорения + погашения после завершения срока действия, предоставляя мгновенному заемщику мгновенную комиссию за ретрансляцию «бесплатно». Мы предотвращаем это в предлагаемом PR.
On
settle
, ЕслиBridgePool
- этоWETH
пул, а получателем является контракт, который не являетсяpayable
(не принимает ETH), затемsettle
не удастся. Мы планируем это исправить и отказаться от отправкиWETH
, но в этом направлении еще не проделано никакой выдающейся работы.
In
relayDeposit
, мы проверяем, чтоBridgePool
Баланс компании превышает сумму, передаваемую ПЛЮС залог предлагающего. Это устаревшая проверка и слишком консервативная, поскольку после проверки у пользователя снимается залог предлагающего. Мы обращаемся к этому в предлагаемом PR.
Я только что обнаружил ошибку, когда
chainId
inBridgePool
, включенный в составDeposit
структуру и в качестве входной функции для всех функций, связанных с реле (т. е.relayDeposit
,speedUpRelay
,settle
) — это типuint8
. Это слишком маленький тип для обработки, например, Arbitrum с идентификатором 421611. Мы действительно обнаружили эту ошибку и исправили ее на стороне L2:BridgeDeposit
установил свойchainId
введите вuint256
. Этот PR сделаетchainId
onBridgePool
соответствовать типу наBridgeDepositBox
: UMAпротокол/протокол#3463
Раньше функция диспута не вычитала сумму депозита из
pendingReserves
(это переменная, которая отслеживает, какая часть резервного пула заблокирована из-за еще не установившихся реле). В результате каждый спор блокировал сумму ретрансляции в пуле на неопределенный срок. Он не может быть отозван LP или использован будущими реле. Исправление здесь: UMAпротокол/протокол#3473.
Мы нашли ошибку в
BridgeDepositBox
в которомhasEnoughTimeElapsedToBridge
не проверяет, есть лиuint256
значение равно0
по умолчанию: Исправлено в PR 3484.
Метод обменного курса (который изменяет состояние) вызывается между передаваемыми токенами и выпускаемыми токенами LP в методе addLiquidity контракта мостового пула. Это вычисление необходимо переместить в начало метода. Это вызывает очень странные государственные ценности. См. PR здесь исправить.
Метод просмотра
liquidityUtilizationPostRelay
(который используется только оффчейн), сообщает о неправильном номере использования. Знаменатель на эта линия не должно быть простоliquidReserves
вместо этого это должно быть представление неиспользованных и использованных резервов. Зафиксированный здесь.
Обновление ПО
Помимо исправлений проблем, мы также рассмотрели следующие дополнительные изменения:
- PR72 удаляет избыточный параметр токена из
BridgePool
Мероприятия. - PR72 добавляет окончательную плату DVM в список локально кэшированных переменных.
- PR72 учитывает возможный крайний случай отрицательного использования ликвидности (в дополнение к решению N04)
- PR72 удаляет лишние файлы и обновляет константы OVM в соответствии с изменениями OVM 2.0.
- PR72 обновляет
BridgeDepositBox
интерфейс для согласованности и использует OpenZeppelinSafeERC20
библиотека.
При проверке исправлений мы обнаружили еще одну проблему. При определении стоимости BridgePool
токены LP, есть промежуточный расчет, который может неожиданно вызвать отрицательное переполнение, что временно отключит добавление и удаление ликвидности. Порядок расчета следует изменить, чтобы добавить использованные резервы перед вычитанием нераспределенных сборов.
Критическая степень тяжести
[C01] Награда за попавшего в ловушку предложения
Ассоциация LongShortPair
контракт получает вознаграждение предлагающего с какого адреса истечет срок действия, который используется для стимулирования ценовых предложений в Оптимистическом оракуле. Однако LongShortPairCreator
контракт также получает и пересылает средства с адреса развертывания. Эти дополнительные средства не передаются Оптимистическому Оракулу, а вместо этого остаются в ловушке внутри LongShortPair
контракт.
Рассмотрите возможность удаления дублирующего перевода.
Обновление: Исправлено на момент фиксации 9bab1ff353a417952ba8c96a098773f340d9da17
in PR72.
Высокая степень тяжести
[H01] Параллельные реле истощают резервы
Ассоциация relayDeposit
функции BridgePool
контракт обеспечивает наличие в контракте достаточных средств выполнить перевод. Однако это не учитывает ожидающие резервы, который отслеживает средства, предназначенные для активных реле. Таким образом, несколько одновременных эстафет могут полагаться на одни и те же средства, и не все они могут быть урегулированы немедленно. В частности, при устойчивом потоке передач мгновенные возвраты ретранслятора могут задерживаться на неопределенный срок.
Рассмотрите возможность предотвращения реле, которое может привести к тому, что ожидаемые резервы превысят ликвидные резервы.
Обновление: Исправлено на момент фиксации 6290f3facbca8d878605a1d390ed59d4b6b6db02
in PR72.
[H02] Границы параметров моста не совпадают
Ассоциация deposit
функция BridgeDepositBox
Контракт, развернутый в цепочках уровня 2, используется для соединения средств между L2 и L1. В частности, ретрансляторы заинтересованы в том, чтобы реле детали транзакции на связанном L1 BridgePool
. Тем не менее, депозитная ячейка использует инклюзивные границы чтобы ограничить комиссию за ретрансляцию, в то время как пул мостов использует эксклюзивные границы. Это означает, что некоторые депозиты (с комиссией за передачу 25%) не могут быть переданы, и средства будут недоступны на обоих уровнях.
Рассмотрите возможность синхронизации проверок на обоих уровнях, чтобы обеспечить возможность передачи всех действительных депозитов.
Обновление: Исправлено в коммите 2345966b3a2ace0159379b3a13256cc1a4c5d52f
of PR72. Первоначально уровень серьезности был отнесен к критическому, но был понижен, когда команда UMA указала, что средства не будут строго блокироваться и могут быть высвобождены, если избиратели DVM согласятся принять измененное описание реле для затронутых депозитов.
Средней степени тяжести
[M01] Обратные вызовы на неверный адрес
Ассоциация SkinnyOptimisticOracle
вызывает функции обратного вызова в запрашивающей стороне цены, если они существуют, чтобы запрашивающая сторона могла реагировать на значительные изменения состояния. Однако обратный вызов неправильно вызывается у предлагающего цену, а не у запрашивающего цену в домен proposePriceFor
функция. Это означает, что запросчик цен не может ответить на ценовые предложения.
К счастью, эта функция не используется в текущей базе кода. Тем не менее, рассмотрите возможность вызова priceProposed
обратный вызов отправителю запроса.
Обновление: Исправлено при фиксации 7bd3faeb6f3706132f77b9ba2dce192d1a151e74
in PR72.
[M02] Неверная функция добавления
Ассоциация appendKeyValueBytes32
функция должен объединить свои входные данные в отформатированный bytes
множество. Однако currentAncillaryData
is неправильно отброшено.
Поскольку вспомогательные данные влияет на процесс разрешения оракула, неправильное значение может подорвать результаты оракула. К счастью, существует только один звонок в appendKeyValueBytes32
в базе кода и использует пустой currentAncillaryData
буфер, поэтому ошибка не затрагивает этот случай.
Рассмотрите возможность обновления appendKeyValueBytes32
функционировать так, чтобы currentAncillaryData
включается в возвращаемый массив байтов.
Обновление: Исправлено в коммите 5609433c154f47e8ee9c52f9b6d7c787fbe3e455
of PR72.
[M03] Неполная проверка вспомогательных данных
Ассоциация LongShortPair
конструктор подтверждает, что customAncillaryData
достаточно мал. Однако это не учитывает поле досрочного истечения. Это означает Оптимистический Оракул может неожиданно отклонить запросы цен с досрочным сроком действия, что отключит эту функцию.
Рассмотрите возможность обновления проверки для учета дополнительного поля.
Обновление: Исправлено на момент фиксации 4a56e66492f40e20254cebb145c2d91304f7cb43
in PR72.
[M04] Неправильная обработка нулевой временной метки
В LongShortPair
Контракт имеет нулевую временную метку досрочного истечения. используется как флаг чтобы указать, что никто не запустил механизм досрочного истечения срока действия. Однако возможно запустить этот механизм с нулевой меткой времени. В этом сценарии будет вызван Оптимистический Оракул, но защита от последующих ценовых запросов не будет эффективным. К счастью, однажды расчетная цена выбрана, оно не будет переопределено, поэтому это не приведет к противоречивым расчетам. Тем не менее, последующий запрос цены может изменить записанную метку времени досрочного истечения, даже если для определения расчетной цены используется нулевая отметка времени. Это также могло бы выдать вводящее в заблуждение событие.
Рассмотрите возможность предотвращения досрочного истечения срока действия с помощью нулевой отметки времени.
Обновление: Исправлено на момент фиксации 11d287c07c93c04f534b2ef3c869966d9f18ac60
in PR72.
[M05] Возможна нулевая связь
Ассоциация requestPrice
функции SkinnyOptimisticOracle
контракт использует окончательную комиссию в качестве залога если залог не указан. Однако requestAndProposePriceFor
функция может использовать нулевую облигацию, что противоречит его @notice
и @param
Комментарии. Нулевая связь ослабляет стимул против недействительных предложений или споров.
К счастью, только вызов этой функции в базе кода устанавливается связь предлагающего. Тем не менее, рассмотрите возможность использования окончательной комиссии, если залог не указан.
Обновление: Исправлено на момент фиксации daaabfc342ba1395a577159b6eb26adb20fcd232
in PR72.
[M06] Ненужные права администратора
Ассоциация BridgePool
контракт наследуется от ExpandedERC20
чтобы он мог выпускать токены LP поставщикам ликвидности. Это наследует функциональность OpenZeppelin. ERC20
контракт, а также предоставляет права администратора разработчику контракта, что позволяет им чеканить и сжигать токены LP. Однако это право не является обязательным и, если оно будет реализовано, может несправедливо наказать поставщиков ликвидности.
Рассмотрите возможность изменения BridgePool
наследовать непосредственно от ERC20
вместо ExpandedERC20
.
Обновление: Исправлено в коммите 370e8b21b660543eadbd764fed984a5bdeddce24
in PR72.
Низкая степень серьезности
[L01] Невозможно рассчитаться по истечении срока действия
Ассоциация settle
функции LongShortPair
контракт учитывает условия расчета когда текущее время находится строго до или после отметки времени истечения срока действия. Однако он неправильно возвращается, когда текущее время совпадает с меткой времени истечения срока действия.
Рассмотрите возможность использования инклюзивной границы, соответствующей postExpiration
изменение.
Обновление: Исправлено в коммите f03cdaa50b16d29e8f42f000bf7cd50a042cf616
in PR72.
[L02] Отсутствует сообщение об ошибке в операторе require
В операторе require есть BridgePool
контракт без сообщения об ошибке.
Рассмотрите возможность включения конкретных и информативных сообщений об ошибках во все операторы require.
Обновление: Исправлено на момент фиксации 67e60faa3a44c842c37211d2e903a983ff192e57
in PR72.
[L03] Отсутствуют строки документации
В кодовой базе есть несколько случаев, когда Спецификация Ethereum Natural отсутствует или является неполным. Примеры включают в себя:
Рассмотрите возможность тщательного документирования всех функций (и их параметров), которые являются частью общедоступного API контрактов.
Обновление: Выделенные комментарии были исправлены в коммите. e943e85a7dae60acd17a6d6aa027fbb1017c95ee
of PR72. Мы не проверяли полноту NatSpec в остальной части базы кода.
Примечания и дополнительная информация
[N01] Возвращаемое значение вызова не проверено
В deposit
функция L2 BridgeDepositBox
контракте происходит низкоуровневый вызов l2Token
когда окно l1Token
is l1Weth
. Этот низкоуровневый вызов предназначен для deposit()
функция, принадлежащая WETH интерфейс. Если это l2Token
ведет себя точно так же, как WETH, он никогда не должен выходить из строя. Но в случае l2Token
ведет себя по-другому и не завершается с ошибкой, возврата не будет, поскольку флаг успеха этого низкоуровневого вызова никогда не проверяется.
Рассмотрите возможность проверки и соответствующей реакции на возвращаемые значения всех вызовов низкого уровня.
[N02] Отсутствие индексированных параметров в событиях
Многие события, определенные в этой базе кода, имеют параметры, которые следует индексировать:
Рассматривать параметры события индексации чтобы не мешать выполнению задачи поиска и фильтрации оффчейн-сервисов по конкретным событиям.
Обновление: Частично исправлено в коммите d156b40b2ddb109806336c4d169dbdea91ed1c3e
of PR72, chainId
параметр WhitelistToken
не обновлялся.
[N03] Неявное несоответствие приведения типов
Ассоциация LongShortPair
контракт в целом рассматривает временные метки как uint64
ценности, которые неявно приводятся к uint256
значения, когда перешел к Оптимистическому Оракулу. Тем не менее, requestTimestamp
параметр домен _requestOraclePrice
функция преждевременно отбрасывается в uint256
. Это не имеет никаких функциональных последствий.
Тем не менее, в интересах единообразия, рассмотрите возможность использования uint64
для этого параметра и позволяя неявно привести его к uint256
при передаче к Оптимистическому Оракулу.
Обновление: Исправлено в коммите 1c3c5c000ef450f5e2da056e41caff468c3fcdcb
of PR72. Временная метка теперь указывается явно.
[N04] Неправильный тип
Ассоциация sendMessage
функции iOptimism_CrossDomainMessenger
интерфейс использует uint256
газовый лимит в то время как Оптимизм OVM_CrossDomainEnabled
использует uint32
газовый лимит.
Для обеспечения последовательности и предсказуемости рассмотрите возможность обновления iOptimisim_CrossDomainMessenger
sendMessage
функция для использования uint32
лимит газа.
Обновление: Исправлено на момент фиксации 381951aad988bbba6b2ef1b136ed5c48df50aa88
in PR72.
[N05] Отсутствие проверки
Все функции в BridgeAdmin
этот звонок _relayMessage
предположим, что стоимость транзакции соответствует l1CallValue
параметр, но это не применяется.
Подумайте об обеспечении правильного msg.value
установлен.
Обновление: Исправлено на момент фиксации f19b8d04c2343051ff2a8145abd41c39bd025063
in PR72.
[N06] Читабельность
Ассоциация _getDepositHash
функция BridgePool
контракт разворачивает depositData
структура для пересечения l1Token
в качестве аргумента в составе keccak256
с abi
кодировка. Это делает операцию излишне многословной и может привести к ошибкам при повторной реализации на других уровнях.
Рассмотрите возможность упрощения аргументов, чтобы они были просто упорядоченной парой. depositData
и l1Token
.
Обновление: Исправлено на момент фиксации 31754be4a818109fa12131f854c3f70d6c72dba7
in PR72.
[N07] Функция реентерабельности
Ассоциация requestAndProposePriceFor
функция SkinnyOptimisticOracle
контракт совершает вызов ненадежному msg.sender
но не охраняется nonReentrant
модификатор. Хотя в данном случае это не кажется проблемой безопасности, это может привести к неожиданному поведению.
Рассмотрите возможность добавления nonReentrant
модификатор для всех функций, которые вызывают возможно ненадежные контракты.
Обновление: Исправлено в коммите b744d24e7579b7afa2c778f4dd680f26117b3990
of PR72.
[Н08] seqNum
не зарегистрирован
Ассоциация relayMessage
функция Arbitrum_Messenger
контракт не генерирует соответствующее событие после выполнения конфиденциального действия. relayMessage
вызовы функций как подпрограмма sentTxToL2NoAliasing
который сам возвращает uint256
ценностное seqNum
, но это возвращаемое значение не регистрируется в relayMessage
функции.
Рассмотрите возможность отправки событий после внесения конфиденциальных изменений, чтобы облегчить отслеживание и уведомление клиентов вне сети о действиях контракта.
Обновление: Исправлено на момент фиксации 30343f33532a6c255dc4cc18c3b497d9b2767a7c
in PR72.
[N09] Типографические ошибки
Кодовая база содержит следующие опечатки:
Рассмотрите возможность исправления этих опечаток, чтобы улучшить читаемость кода.
Обновление: Исправлено на момент фиксации 2dccbe1c2c82fe2a21c179ac06c2d4f0d911a2ca
in PR72.
[N10] Недокументированное требование одобрения ERC20
Ассоциация requestEarlyExpiration
и expire
Функции LongShortPair
Каждый контракт предполагает, что вызывающая сторона предоставила контракту разрешение на получить награду предлагающему.
В целях предсказуемости рассмотрите возможность документирования этого требования в комментариях к функции.
Обновление: Исправлено в коммите da3754f50284480df57b90b80002da06a1ce0d02
in PR72.
[N11] Неиспользуемый модификатор
В BridgePool
контракт, onlyFromOptimisticOracle
изменение определен, но никогда не используется в базе кода и поэтому должен быть удален.
Обновление: Исправлено в коммите 7abece6377637e8c4cd3bd07ab9adcfa051d4e94
in PR72.
Выводы
Обнаружено 2 критических и 1 проблема высокой степени серьезности. Были предложены некоторые изменения, чтобы следовать передовому опыту и уменьшить потенциальную поверхность атаки.
- &
- 7
- Учетная запись
- Действие
- активный
- Ad
- дополнительный
- адрес
- Администратор
- плюс
- Все
- Позволяющий
- API
- Аргументы
- аудит
- свободных мест
- не являетесь
- ЛУЧШЕЕ
- лучшие практики
- блокчейн
- Коробка
- МОСТ
- Ошибка
- ошибки
- призывают
- случаев
- пойманный
- Вызывать
- вызов
- изменение
- контроль
- код
- Комментарии
- Конфигурация
- содержит
- контракт
- контрактов
- может
- Текущий
- данным
- децентрализованная
- задерживать
- Проект
- определения
- DID
- спор
- не
- Рано
- Экономические
- Edge
- Эффективный
- ERC20
- ETH
- Эфириума
- Ethereum blockchain
- События
- События
- пример
- обмена
- ожидаемый
- опыт
- Особенность
- Сборы
- финансовый
- First
- фиксированный
- Flash
- следовать
- найденный
- функция
- фонд
- средства
- будущее
- ГАЗ
- плата за газ
- Отдаете
- управление
- счастливый
- имеющий
- здесь
- High
- Выделенные
- держатели
- Как
- HTTPS
- стимулировать
- включены
- В том числе
- Увеличение
- информация
- интерес
- Интерфейс
- вопросы
- IT
- известный
- вести
- Библиотека
- жидкость
- Ликвидность
- провайдеры ликвидности
- Список
- Кредиты
- в местном масштабе
- запертый
- LP
- Пластинок
- рынок
- Совпадение
- самых
- открытый
- оракул
- Другое
- Платформа
- бассейн
- Пулы
- мощностью
- предупреждение
- цена
- процесс
- рассматривается
- обеспечивать
- приводит
- что такое варган?
- причины
- уменьшить
- Отчеты
- ОТДЫХ
- Итоги
- Возвращает
- обзоре
- Снижение
- безопасность
- Услуги
- набор
- поселок
- Короткое
- значительный
- аналогичный
- небольшой
- So
- основательность
- Кто-то
- удалось
- скорость
- тратить
- Область
- заявление
- диск
- успех
- Поддержанный
- Поверхность
- система
- тестXNUMX
- Через
- по всему
- время
- знак
- Лексемы
- топ
- Отслеживание
- сделка
- Сделки
- Доверие
- Обновление ПО
- Updates
- UPS
- пользователей
- ценностное
- Вид
- Белый список
- КТО
- в
- без
- Работа
- стоимость
- нуль