The Open Dev Blog
917 subscribers
13 photos
1 video
65 links
Security audits: @TheOpenDevTeam

Contact: @rends_east, @therealmaloleg or @bazrov
Download Telegram
🔥 Выводим депозиты.

Недавно мы провели аудит смарт-контрактов проекта webdom. Среди найденных багов один был наивысшего приоритета — Critical. Что мы нашли?

Для многих из видов контрактов (аукционы, продажи доменов, etc) webdom предусмотрели возможность закрытия сделки не только с помощью internal, но и через external сообщение. То есть любой желающий может обратиться на контракт по external интерфейсу и уведомить его, что все условия сделки выполнены, пора ее исполнять. Это крайне полезно, например, для аукционов, когда время аукциона может выйти, но без внешнего вызова смарт-контракт сам не сможет реализовать окончание сделки.

Что такое external сообщение? Когда вы делаете свап на @bidask, ваш wallet контракт посылает internal сообщение от себя к пулу ликвидности. Но сам wallet контракт вызывается external сообщением, которое вы подписываете в кошельке. Любая цепочка транзакций в TON вызвана сообщением, которое приходит извне блокчейна — оно и называется external.

Следующий закономерный вопрос — почему злой Пескарь не может послать на мой wallet контракт 100 миллиардов external сообщений, чтобы сжечь на газ блокчейна мой 1 миллиард TON? Для этого предусмотрена защита — у каждого external вызова есть бесплатные 10000 газа (это 0.004 TON). Этот газ может быть потрачен без списания с аккаунта. Он тратится, например, на проверку подписи wallet контрактом. Если подпись верна, то контракт вызывает инструкцию acceptExternalMessage. Даже если злой Пескарь будет слать на ваш кошелек сообщения, то все они не будут приниматься контрактом, пока у злого Пескаря не появится ваш приватный ключ.

С webdom всё интереснее. Аукцион может завершить кто угодно. Это означает, что контракт всегда принимает external сообщение. В таком случае очень важно, чтобы любое external сообщение обрабатывалось корректно после того, как вызовется acceptExternalMessage. Иначе можно будет послать сообщение с ошибкой, контракт его примет, потратит свой газ, а аукцион не закроется — и продолжать так можно до бесконечности.

Именно в этом и заключалась ошибка webdom. В контрактах аукционов сначала external сообщение принималось, а затем из сообщения считывался queryId — 64 бита информации. Это означало, что можно было составить сообщение с недостаточным количеством бит, и контракт бы падал с ошибкой 9 (Cell underflow), тратя при этом газ. Это крайне критично для, например, аукционов в TON, где сумма за домен хранилась на контракте продажи, и могла быть потрачена полностью на газ. Итогом была бы потеря домена и суммы, которую за него заплатили. Такую ошибку мог бы совершить каждый, это необычный баг, ничьей вины в этом нет.

Баг был крайне оперативно исправлен.

В ближайшую субботу (08.11) один из авторов канала будет разбирать работу контрактов webdom в онлайн формате (там есть интересные нюансы) — вы сможете узнать что-то новое, спросить интересующие вас вопросы. Анонс в @toncishub будет чуть позже, мы приложим его к посту.

@TheOpenDevBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
4🔥4119👍13😁31