May 17, 2024

Хак Hyperlane

Обо мне

  • Веду канал @findmeonchain о крипте. Там можно найти актуальные инвест идеи, забавные истории моих успехов и факапов, а также немного кода.
  • Есть опыт работы Solidity разработчиком, последнее время пишу на js/ts.

TLDR

  • Нашел баг в контракте Hyperlane уровня medium. С его помощью можно было отправлять средства из одной сети в другую бесплатно.
  • Связался с командой и получил выплату в 5000$ на площадке Immunefi.

Как был найден баг?

Мой товарищ делает небольшие проекты, связанные с мостами. Некоторое время назад я помогал ему с контрактами для LayerZero, а в начале апреля пришла очередь Hyperlane.

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

На следующий день приходит товарищ и говорит:

У нас какая-то ошибка в контракте. Посмотри, у конкурентов транзакция имеет 4 трансфера эфира, а у нас один. Причем с нас не взымается плата.

Наша транзакция с "багом":

Правильная транзакция через чужой контракт:

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

Откуда он взялся?

Пришлось детально изучить различие вызовов при помощи tenderly. Тогда и стало ясно, что баг не у нас, а в контрактах Hyperlane. Тем не менее, я пошел дальше и изучил свой код. Подумал где бы могла быть ошибка. Оказалось, что я по невнимательности поставил нулевую оплату за мост.

function transferRemote(
        uint32 _dstChain,
        bytes32 _receiver,
        uint256 _tokenId
) external payable override(TokenRouter) returns (bytes32 messageId) {
        ... // very important bridge checks 
        messageId = _transferRemote(
                          _dstChain,
                          _receiver,
                          _tokenId,
                          0  // !HERE IT IS!
                     );
}

Согласно комментарию в коде контракта TokenRouter, написанным командой Hyperlane, параметры должны быть такими:

/**
     * @notice Transfers `_amountOrId` token to `_recipient` on `_destination` domain.
     * @dev Delegates transfer logic to `_transferFromSender` implementation.
     * @dev Emits `SentTransferRemote` event on the origin chain.
     * @param _destination The identifier of the destination chain.
     * @param _recipient The address of the recipient on the destination chain.
     * @param _amountOrId The amount or identifier of tokens to be sent to the remote recipient.
     * @param _gasPayment The amount of native token to pay for interchain gas.
     * @return messageId The identifier of the dispatched message.
     */

@param _gasPayment The amount of native token to pay for interchain gas — параметр, в котором была ошибка. Туда должна идти какая-то плата за услуги моста, но я поставил 0!

Казалось бы, это точно должно выдавать ошибку транзакции, но у нас всё проходило и контракты работали.

Почему это всё тестируется на проде, а не в тестнете или локально?

Зачастую, тестнет транзакции у мостов исполняются очень медленно. Поскольку они бесплатные, проекты ставят ограничения на их исполнение. Локально же ситуация может отличаться от той, что есть в реальности. К тому же в мейннете есть удобные инструменты вроде etherscan/tenderly, через которые легче задебагать какие-то моменты. Я пришел к выводу, что лучший путь — деплоить контракты в дешевых сетях и тестировать их там.

Это не относится к логике контракта, которую можно протестировать локально. Так я тестирую только cross chain функционал.

Обращение к команде

Покопавшись в архитектуре Hyperlane я понял, что у них довольно сложная система. На изучение всех контрактов и нюансов ушло бы очень много времени, которого у меня не было. Недолго думая я пишу им в дискорд сообщение такого содержания:

I've found high/critical bug in mailbox/hook contract. User funds are not affected. Is there anyone I could talk to?

В ответ на которое мне кидают ссылку на immunefi — платформу для репорта багов и выплат наград по ним. Команда довольно быстро посмотрела мой отчет но не поняла суть (как и я в первый раз). Они тоже не заметили ничего странного!

Пришлось также на примерах им объяснить, что я совершаю транзакции бесплатно. Они подтвердили, что что-то не так и взяли больше времени на изучение.

Финал

Спустя некоторое время я получаю ответ:

After reviewing your bug report, we believe that it is in scope for our bug bounty program and the threat level is Medium.

Определение уязавимости medium уровня:

- Smart contract unable to operate due to lack of token funds
- Block stuffing for profit
- Griefing (e.g. no profit motive for an attacker, but damage to the users or the protocol) — В эту категорию попадает найденный баг
- Theft of gas — В эту категорию попадает найденный баг
- Unbounded gas consumption

Я очень обрадовался, ведь баг даже Medium уровня обещает солидную награду.

В архитектуре Hyperlane есть набор контрактов-хуков, которые позволяют выполнять какую-либо особую и заданную логику. В частности, делать refuel, считать комиссии за транзакцию и тд.

Вызываются все хуки по очереди после вызова функции моста. Ни в одном из стандартных хуков не было проверок на достаточное количество оплаты перед переходом дальше, поэтому вызов доходил вплоть до самого последнего, который и оплачивал транзакцию из своего кармана (если на нем остались средства после refuel-ов). Обычно команда быстро забирала средства с контракта, однако иногда оставались 30$-50$, которыми можно было воспользоваться.

Таким образом удавалось практически бесплатно отправить транзакцию через Hyperlane — оплатив лишь комиссию сети.

Успех! 🎉

Через некоторое время росыпаюсь, проверяю телегу и понимаю, что день начался хорошо:

Списываемся с товарищем и делим награду пополам.

Итоги

Для меня это первый подобный опыт. Раньше мне никогда не удавалось найти багов в уже используемых контрактах проектов. В этой ситуации мне, безусловно, повезло обнаружить его из-за ошибки с моей стороны. Прямо ощутил себя крутым Whitehat-ом из крипто твиттера!

Спасибо команде Hyperlane за сотрудничество, приятно было с ними работать. На мой вгляд, они создают важный продукт — один из самых децентрализованных и технологически многогранных мостов (как для средств, так и сообщений), желаю им успеха в дальнейшем развитии.

Спасибо за уделенное время!

Если вам понравилась статья, подписывайтесь на мой канал. Вряд ли я найду ещё один баг на проде у крупного проекта, но ещё точно будет что почитать и обсудить :)