# Ликбез по базовому аудиту операций в мультиподписи Gnosis Safe ## Короткая версия на примерах Пример с транзакцией добавления ликвидности. Это вызов функции addLiquidity в контракте PancakeSwap Router v2 (0x10ED..): ![](https://i.imgur.com/O920RBe.png) Пример с транзакцией, разрешающей пользоваться токеном в нашем Сейфе третьему лицу/контракту. Вызывается функция approve (часть стандарта ERC20) у контракта токена (в данном случае это Cake-LP токен по адресу 0xD1718..) с параметрами sender = 0xa5f8.. и длинным value. Этой транзакцией мы разрешаем аккаунту 0xa5f8.. пользоваться нашими токенами Cake-LP в размере value (значение указано в копейках, если поделить это значение на 10^18 увидим сумму в токенах): ![](https://i.imgur.com/JnNJ4bd.png) ## Подробная версия :::info Это не техническая документация, тут много упрощений для понятности. ::: :::info Здесь и далее будет идти речь про Эфириум, но инструкция так же применима к любой другой эфироподобной сети, например Binance Smart Chain. ::: ## Немного про базовые примитивы Эфириума Любая операция в сети эфириум, которая меняет состояние системы, — это транзакция. У каждой транзакции всегда есть отправитель и получатель, также _могут_ быть указаны сумма в валюте сети (value) и данные для транзакции (message data). То, какие из этих атрибутов транзакции заданы, определяет вид транзакции. В Эфириуме фундаментально есть два вида транзакций: перевод базовой валюты сети (т.н. нативного токена) и вызов смарт-контракта. ### Перевод нативного токена с одного аккаунта на другой. У каждой сети свой нативный токен, в нём обычно платится комиссия за транзакции (за газ). Нативный токен Эфириума — эфир (ETH). Нативный токен Binance Smart Chain — BNB. У такой транзакции есть отправитель, получатель и value транзакции, но нет message data. Это всегда только перевод эфира, ничего более. ### Вызов функции у смарт-контракта. Если у траназакции получателем указан адрес смарт-контракта и так же заданы message data, то такая транзакция является вызовом функции смарт-контракта. То, какая именно функция вызывается и с какими параметрами, указано в message data. Такая транзакция так же может иметь value, в этом случае эфир будет перечислен на адрес смарт-контракта. Это самый важный для нас тип транзакций, потому что по сути всё, что мы делаем в эфириуме, кроме перевода чистого эфира, — это вызов смарт-контрактов. Любые токены типа USDT — это тоже смарт-контракт. Каждый раз, когда мы переводим USDT или другой токен, мы вызываем функцию transfer у смарт-контракта токена (название transfer диктуется стандартом ERC20, но вообще функция передачи может назвываться и иначе, название функции не имеет значения — имеет значение, что именно делает функция). Разрешая кому-то пользоваться нашими токенами, мы вызываем функцию approve на контракте токена и т.д. ## Gnosis safe Решение для мультиподписи Gnosis safe — это по сути смарт-контракт плюс дополнительный код поверх него для координации подписантов. Когда активы лежат в Сейфе, они находятся на аккаунте смарт-контракта (например, смарт-контракт сейфа MTL DeFI: https://bscscan.com/address/0x0358d265874b5cf002d1801949f1cee3b08fa2e9#code). Соответственно всё взаимодействия с сейфом — это создание, подпись и отправка транзакций в смарт-контракт сейфа. Любой подписант сейфа может предложить транзакцию на подпись, она будет отображаться в очереди на подпись (вкладка Queue в разделе Transactions). Предложенная транзакция пока в смарт-контракт не попадает, а хранится в приложении Сейфа пока идёт сбор подписей. Сбор подписей тоже происходит офчейн (без участия блокчейна) — подписанты подписывают своим ключом сообщение и отправляют его в приложение Сейфа. После того, как транзакция собрала кворум подписей, любой подписант может отправить её в сеть (Execute), заплатив за это газ (комиссию сети). ## Возможная процедура аудита Интерфейс Сейфа декодирует message data транзакции для нас, так что мы можем видеть какая функция какого смарт-контракта вызывается и с какими параметрами. **По сути именно это нам и нужно для аудита — проверить, что будет вызвано то, что нужно с теми параметрами, которые нужны.** Нет точной инструкции как чётко проверить произвольную функцию, поскольку нужно знать, что и как делает конкретный смарт-контракт. Уже будет неплохо, если подписант удостоверится, что идёт взаимодействие со смарт-контрактом заявленной платформы (например один из контрактов Pancake Swap), либо с заявленным токеном (например BTCB). Если выдаются разрешения третьим лицам (approve) на трансфер токенов, то стоит проверить, что это за третье лицо (обычно это один из контрактов платформы, с которой заявлено взаимодействие). Все транзакции в сейфе можно условно разделить на два вида: манипуляции с настройками самого сейфа (например, изменение кворума или изменение списка подписантов) и собственно рабочие транзакции (взаимодействие с другими DEFI проектами, внешние переводы активов и т.п.). Сейф их отображает немного по-разному. Пример транзакции первого типа (внутренняя), добавляющей подписанта и изменяющей кворум: ![](https://i.imgur.com/vDVGkf3.png) Эта транзакция самого сейфа, поэтому он знает её семантику и отображает иначе. Обратите внимание, что транзакция помечена как потенциально опасная, потому что меняет политику безопасности Сейфа. Пример транзакции второго типа ![](https://i.imgur.com/D9WZCnD.png) В данном случае Сейф ничего не знает про семантику вызываемой функции, а просто влоб декодирует и показывает нам параметры вызова.