Задачка на день
Ну, и небольшая задачка на день. Сможете найти, в чем тут проблема?
Решение
В аудитах следует всегда обращать внимание на модификаторы функций, какие условия они нам ставят.
В текущем же примере, он просто сверяет msg.sender с другим параметров, а значит, что функция _safeMint() не защищена от reentrancy атак.
#security #task
Ну, и небольшая задачка на день. Сможете найти, в чем тут проблема?
Решение
В текущем же примере, он просто сверяет msg.sender с другим параметров, а значит, что функция _safeMint() не защищена от reentrancy атак.
👍2
Counter.sol
2.8 KB
Файл-хелпер для работы с Foundry
В недавнем аудите я снова столкнулся с некоторыми тестами в Foundry, которые тормозили весь процесс.
Сегодня я решил создать для себя небольшой файл подсказку для проведения тестов.
Думаю он может быть полезен всем, кто только начинает свою практику. Вы можете скачать его и в любой момент добавлять свои тесты или наработки.
Также прикрепляю файл с базовыми контрактами.
Обращаю внимание, что это простые тесты с комментариями, для общего понимания принципов работы Foundry. Позже добавлю туда практику с прокси контрактами, а также наработки с эксплойтами.
Всем хороших выходных!
#foundry
В недавнем аудите я снова столкнулся с некоторыми тестами в Foundry, которые тормозили весь процесс.
Сегодня я решил создать для себя небольшой файл подсказку для проведения тестов.
Думаю он может быть полезен всем, кто только начинает свою практику. Вы можете скачать его и в любой момент добавлять свои тесты или наработки.
Также прикрепляю файл с базовыми контрактами.
Обращаю внимание, что это простые тесты с комментариями, для общего понимания принципов работы Foundry. Позже добавлю туда практику с прокси контрактами, а также наработки с эксплойтами.
Всем хороших выходных!
#foundry
🔥5
День задач на канале
Сегодня я подготавливаю отчет для своего конкурсного аудита, поэтому на канале объявляется день задач.
Итак, первая: была помечена как High Risk на code4rena. Сможете понять в чем тут дело?
Решение
В этой задаче стоит обратить внимание не только на саму подпись (мы же помним, что с ними существует достаточное количество проблем?), но и на nonce.
Вроде бы, все правильно написано в коде. Но нет одной единственной проверки. Уже догадались?
Разработчики не проверяют return с call вызова. Это значит, что в случае неудачного вызова, nonce останется прежним, и хакер может использовать подпись с еще действующим nonce в своих целях.
Вот описание с code4rena.
#task #nonce
Сегодня я подготавливаю отчет для своего конкурсного аудита, поэтому на канале объявляется день задач.
Итак, первая: была помечена как High Risk на code4rena. Сможете понять в чем тут дело?
Решение
Вроде бы, все правильно написано в коде. Но нет одной единственной проверки. Уже догадались?
Разработчики не проверяют return с call вызова. Это значит, что в случае неудачного вызова, nonce останется прежним, и хакер может использовать подпись с еще действующим nonce в своих целях.
👍2
Более сложная задача от Immunefi
При аудите всегда следует обращать внимание на переменные и "откуда растут ноги" у токена. Получилось решить?
Решение
Хоть первая функция и оторвана от контекста, смысл бага все же можно уловить: недостаточная проверка токенов. Другими словами хакер может использовать фейковый токен, чтобы получить реальные токены.
#task #token
При аудите всегда следует обращать внимание на переменные и "откуда растут ноги" у токена. Получилось решить?
Решение
Еще одна с code4rena
Данный баг был обозначен как Medium risk. Поняли в чем дело?
Решение
Функция lendToProject может стать не доступной, если количество задач (tasks) будет слишком большим, что приведет к стопорению проекта.
Это происходит из-за того, что цикл расходует весь газ из функции. Такая вот DoS атака.
#task
Данный баг был обозначен как Medium risk. Поняли в чем дело?
Решение
Это происходит из-за того, что цикл расходует весь газ из функции. Такая вот DoS атака.
Простая, но серьезная
Данная задача одна из самых легких среди тех, что я видел. Тем не менее, она была помечена как High Risk. Решили?
Решение
Функция заканчивает свое действие на return и не доходит до проверки require. К чему это может привести, вы и сами знаете.
#task
Данная задача одна из самых легких среди тех, что я видел. Тем не менее, она была помечена как High Risk. Решили?
Решение
👍2
Задача на знание нюансов
Задача была помечена как Medium Risk. Ошибка не столько в самом коде, сколько в логике и знании, как работает язык. Поняли, о чем идет речь?
Решение
Проблема все в том же extcodesize. Нельзя полагаться на него при проверке "Контракт ли это?". В первом случае, хакер может все сделать через конструктор контакта, а в более сложном - поиграться с create2 и selfdestruct(). Т.е. проверку довольно просто обойти.
#task
Задача была помечена как Medium Risk. Ошибка не столько в самом коде, сколько в логике и знании, как работает язык. Поняли, о чем идет речь?
Решение
👍2
И последняя на сегодня
Последняя задача была помечена как Critical. Достаточно серьезная проблема многих контактов, которые используют переводы.
Решение
Заметили маппинги в начале? Как вы думаете, зачем они были указаны?
Да, их значения не обновляются при переводе. А значит, что пользователь может делать перевод несколько раз по одному id и опустошить контракт. Будьте внимательны в своих контрактах!
#task
Последняя задача была помечена как Critical. Достаточно серьезная проблема многих контактов, которые используют переводы.
Решение
Да, их значения не обновляются при переводе. А значит, что пользователь может делать перевод несколько раз по одному id и опустошить контракт. Будьте внимательны в своих контрактах!
👍4
Нет, не задача
Disclaimer. Сегодня я сменил название канала, так как мы уже давно вышли за рамки начального обучения, и материал теперь уже для более продвинутых пользователей.
Сегодня хочу обратить ваше внимание на стандарт ERC4626. По нему ранее была задача у Immunefi, с которой мне пришлось повозиться, чтобы понять в чем там дело.
ERC4626, объясняю своими словами, используется тогда, когда вам нужно выдать пользователям вашего проекта некоторое количество shares взамен их токенов, которые они внесли. Он используется и в играх, и в Dao, и на биржах. При аудитах он встречается довольно часто.
В контрактах, которые используют данный стандарт, нужно обращать внимание на формулу расчета количество shares.
Чаще всего разработчики упускают из вида проблему минта shares для первого пользователя, а он может оказаться хакером.
Хоть я сам и понял суть бага, но объяснить его немного затрудняюсь, поэтому предлагаю вам посмотреть часть видео, где он хорошо разбирается.
Видео разбор.
#erc4626
Disclaimer. Сегодня я сменил название канала, так как мы уже давно вышли за рамки начального обучения, и материал теперь уже для более продвинутых пользователей.
Сегодня хочу обратить ваше внимание на стандарт ERC4626. По нему ранее была задача у Immunefi, с которой мне пришлось повозиться, чтобы понять в чем там дело.
ERC4626, объясняю своими словами, используется тогда, когда вам нужно выдать пользователям вашего проекта некоторое количество shares взамен их токенов, которые они внесли. Он используется и в играх, и в Dao, и на биржах. При аудитах он встречается довольно часто.
В контрактах, которые используют данный стандарт, нужно обращать внимание на формулу расчета количество shares.
Чаще всего разработчики упускают из вида проблему минта shares для первого пользователя, а он может оказаться хакером.
Хоть я сам и понял суть бага, но объяснить его немного затрудняюсь, поэтому предлагаю вам посмотреть часть видео, где он хорошо разбирается.
Видео разбор.
#erc4626
👍1
Хэширование в EIP712
Все чаще встречаюсь с этим стандартом на просторах аудиторских отчетов, и стараюсь осмысливать его шаг за шагом.
Вообще EIP712 был создан для того, чтобы можно было подписывать сообщения, которые состоят не только из строк, но и более сложных параметров: например, struct.
И сегодня разберем, как шифруются структуры. Возьмем такой код:
struct Parent {
uint s;
Child[] children;
}
Child {
uint a;
uint b;
}
Сначала будет хешироваться каждый пункт в Child по отдельности, затем они соединяются (конкатенация) и еще раз хешируются. Из этого получается хеш структуры.
В самом конце, берется S и хеш структуры и высчитывается уже конечный хеш Parent.
#erc712 #struct
Все чаще встречаюсь с этим стандартом на просторах аудиторских отчетов, и стараюсь осмысливать его шаг за шагом.
Вообще EIP712 был создан для того, чтобы можно было подписывать сообщения, которые состоят не только из строк, но и более сложных параметров: например, struct.
И сегодня разберем, как шифруются структуры. Возьмем такой код:
struct Parent {
uint s;
Child[] children;
}
Child {
uint a;
uint b;
}
Сначала будет хешироваться каждый пункт в Child по отдельности, затем они соединяются (конкатенация) и еще раз хешируются. Из этого получается хеш структуры.
В самом конце, берется S и хеш структуры и высчитывается уже конечный хеш Parent.
#erc712 #struct
Читаем отчеты вместе. 1
Я тут подумал, а давайте читать аудиторские отчеты вместе всем каналом? За месяц у нас получится около 25 прочитанных отчетов (не считая выходные дни), что точно повысит наши знания.
Выкладывать буду по вечерам. В комментариях будем делиться, что кому понравилось, кто в чем не разобрался, объяснять друг другу моменты и т.д.
Для сегодняшнего вечера я выбрал отчет от Sherlock.
Кто что думает?
#report #audit
Я тут подумал, а давайте читать аудиторские отчеты вместе всем каналом? За месяц у нас получится около 25 прочитанных отчетов (не считая выходные дни), что точно повысит наши знания.
Выкладывать буду по вечерам. В комментариях будем делиться, что кому понравилось, кто в чем не разобрался, объяснять друг другу моменты и т.д.
Для сегодняшнего вечера я выбрал отчет от Sherlock.
Кто что думает?
#report #audit
👍7
Новый скам в NFT
Около недели назад наткнулся на пост, где рассказывалось о новом скаме с NFT. Более подробно о нем можно прочитать тут, а я расскажу в двух словах.
В общем, пользователи Open Sea, да и других бирж, стали замечать, что либо с их аккаунта, либо на их аккаунт идет перевод NFT. Порой даже предлагается подписать транзакцию в кошельке. Делать этого, конечно не стоит.
Дело в том, что практически все переводы NFT порождают событие transfer, которое и отлавливается биржами и другими сервисами. Однако, в случае скама, никакой транзакции не происходит. Злоумышленник просто в своем контракте override функцию transferFrom / safeTransferFrom, оставляя только emit event.
Для того чтобы не попасть в такую ловушку, нужно просмотреть транзакции (а был ли перевод вообще!), а также заглянуть в контракт, который и порождает это уведомление.
Будьте аккуратны, и не подписывайте подозрительные сообщения в кошельках.
#nft #scam
Около недели назад наткнулся на пост, где рассказывалось о новом скаме с NFT. Более подробно о нем можно прочитать тут, а я расскажу в двух словах.
В общем, пользователи Open Sea, да и других бирж, стали замечать, что либо с их аккаунта, либо на их аккаунт идет перевод NFT. Порой даже предлагается подписать транзакцию в кошельке. Делать этого, конечно не стоит.
Дело в том, что практически все переводы NFT порождают событие transfer, которое и отлавливается биржами и другими сервисами. Однако, в случае скама, никакой транзакции не происходит. Злоумышленник просто в своем контракте override функцию transferFrom / safeTransferFrom, оставляя только emit event.
Для того чтобы не попасть в такую ловушку, нужно просмотреть транзакции (а был ли перевод вообще!), а также заглянуть в контракт, который и порождает это уведомление.
Будьте аккуратны, и не подписывайте подозрительные сообщения в кошельках.
#nft #scam
Внимание на decimals в аудитах
Короткий пост для привлечения внимания разработчиков и аудиторов к проблеме decimals в Solidity и расчетах.
Очень и очень часто встречаются ошибки, в которых разработчики учитывали только 18 (WETH) или 6 (USDT) decimals в токенах. При этом их количество в разных токенах варьируется от 1 до 20 (максимальный, который я встречал), но, вполне вероятно, что может быть и больше.
Поэтому, если вы не ограничиваете работу своего смарт контракта whitelist токенами с конкретным значением decimals, то следует учитывать и другие варианты.
Вот один из примеров такого бага в контракте.
#decimals #audit
Короткий пост для привлечения внимания разработчиков и аудиторов к проблеме decimals в Solidity и расчетах.
Очень и очень часто встречаются ошибки, в которых разработчики учитывали только 18 (WETH) или 6 (USDT) decimals в токенах. При этом их количество в разных токенах варьируется от 1 до 20 (максимальный, который я встречал), но, вполне вероятно, что может быть и больше.
Поэтому, если вы не ограничиваете работу своего смарт контракта whitelist токенами с конкретным значением decimals, то следует учитывать и другие варианты.
Вот один из примеров такого бага в контракте.
#decimals #audit
Прочитать mapping в Foundry
Просто оставлю тут небольшую заметку про работу с памятью.
Я еще только учусь вместе с вами, и сегодня столкнулся с проблемой прочтения значений из памяти контракта.
Допустим есть такой маппинг:
mapping (uint256 => structInt) internal BlaBlaSt;
Я перерыл весь foundry и гугл, но так и не понял есть ли какие-нибудь команды, чтобы прочитать значения по нужному id.
В общем, если однажды столкнётесь с такой же проблемой, то проще всего будет написать функцию для вывода значений, а уже после использовать ее в своих тестах.
Получили значения из функции => сохранили в переменные => вывели в консоль.
Мне сегодня это стоило пары часов.
Если знаете более простой способ или команду, буду рад, если поделитесь в комментариях.
#foundry #mapping
Просто оставлю тут небольшую заметку про работу с памятью.
Я еще только учусь вместе с вами, и сегодня столкнулся с проблемой прочтения значений из памяти контракта.
Допустим есть такой маппинг:
mapping (uint256 => structInt) internal BlaBlaSt;
Я перерыл весь foundry и гугл, но так и не понял есть ли какие-нибудь команды, чтобы прочитать значения по нужному id.
В общем, если однажды столкнётесь с такой же проблемой, то проще всего будет написать функцию для вывода значений, а уже после использовать ее в своих тестах.
Получили значения из функции => сохранили в переменные => вывели в консоль.
Мне сегодня это стоило пары часов.
Если знаете более простой способ или команду, буду рад, если поделитесь в комментариях.
#foundry #mapping
Читаем отчеты вместе. 2
Фух, весь день провел в тестах и постижению новых принципов работы с Foundry. Потрясающая система, особенно, когда научишься с ней обращаться.
Вообще, тесты, которые учат писать в роликах на Ютуб, и тесты, которые требуются проводить аудитору - два абсолютно разных по сложности принципа. Завтра сделаю отдельный пост про это.
А пока, вечерний отчет для чтения вместе!
#report #audit
Фух, весь день провел в тестах и постижению новых принципов работы с Foundry. Потрясающая система, особенно, когда научишься с ней обращаться.
Вообще, тесты, которые учат писать в роликах на Ютуб, и тесты, которые требуются проводить аудитору - два абсолютно разных по сложности принципа. Завтра сделаю отдельный пост про это.
А пока, вечерний отчет для чтения вместе!
#report #audit
👍2
Тесты в обучении и аудите. Часть 1
Сегодня хочу поднять тему проведения тестов. В частности на Foundry, но подойдет и для HardHat.
В сети можно встретить достаточно большое количество уроков по темам проведения тестов. Даже ролики на Ютуб на русском языке есть, и по ним действительно можно научиться основам. Точнее установке пакетов, созданию файла и написанию простых тестов.
Немного попрактиковавшись, вы вполне себе сможете написать тест на функцию в своем контракте. Однако сложности начинаются, когда вы берете проект, где уже были проведены тесты и вам нужно либо дополнить их, либо написать свои, например, когда при аудите вы нашли потенциальную проблему и хотите проверить ее.
Что можно найти в серьезных проектах?
Во-первых, в папке с тестами чаще всего лежит не один файл, а несколько.
Во-вторых, там же еще присутствуют и другие папки.
В-третьих, появляются некие контракты хелперы.
И вот после простеньких тестов, с которыми мы игрались на своем проекте, в первый раз такое собрание файлов вызывает некоторую панику.
#tests
Сегодня хочу поднять тему проведения тестов. В частности на Foundry, но подойдет и для HardHat.
В сети можно встретить достаточно большое количество уроков по темам проведения тестов. Даже ролики на Ютуб на русском языке есть, и по ним действительно можно научиться основам. Точнее установке пакетов, созданию файла и написанию простых тестов.
Немного попрактиковавшись, вы вполне себе сможете написать тест на функцию в своем контракте. Однако сложности начинаются, когда вы берете проект, где уже были проведены тесты и вам нужно либо дополнить их, либо написать свои, например, когда при аудите вы нашли потенциальную проблему и хотите проверить ее.
Что можно найти в серьезных проектах?
Во-первых, в папке с тестами чаще всего лежит не один файл, а несколько.
Во-вторых, там же еще присутствуют и другие папки.
В-третьих, появляются некие контракты хелперы.
И вот после простеньких тестов, с которыми мы игрались на своем проекте, в первый раз такое собрание файлов вызывает некоторую панику.
#tests
Тесты в обучении и аудите. Часть 2
Хороший разработчик, как и хороший аудитор, на папку тестов уделят столько же времени, сколько и на сам проект. Хотя бы для того, чтобы понять, какие тесты проводились и что в голове у других разработчиков.
Итак, для каждого контракта в проекте чаще всего создается свой файл теста. Нельзя нагружать все в одно место, так будет проблематичнее потом.
Если есть какие либо библиотеки или сторонние файлы, которые требуют тестов, то также создаем отдельную папку для них (например, utils) и проверяем.
Далее идут файлы хелперы. Так сложно объяснить, что это такое, но в общем, это такие sol файлы в которых прописаны некоторые функции, с помощью которых будет легче проводить сами тесты. Чаще всего они так и называются Helpers.sol или с добавление имени контракта в начале. Тут прописываются переменные, импорты, структуры и функции.
При встрече с ними, крайне рекомендую начинать изучение именно с них.
Сложнее всего иногда бывает определить контракт входа, т.е. с какого контракта начинается взаимодействие с остальными. И от какого лица. Ведь некоторые контракты могут разворачивать только другие контракты (фабрики), или частные лица, или только Сейф и т.д.
При написание своих тестов, мы определяем изначальные условия: контракт входа, его настройки (нужно ли сминтить токены и забросить туда), его пользователей и т.д. В этом очень сильно помогают как раз те хелперы.
И только потом начинаем писать свои тесты.
Если вы хотите действительно научиться писать тесты, то возьмите конкурсный проект и просто сначала изучайте, а потом пробуйте писать свои.
Очень жаль, что нет полноценного курса по проведению тестов.
#tests
Хороший разработчик, как и хороший аудитор, на папку тестов уделят столько же времени, сколько и на сам проект. Хотя бы для того, чтобы понять, какие тесты проводились и что в голове у других разработчиков.
Итак, для каждого контракта в проекте чаще всего создается свой файл теста. Нельзя нагружать все в одно место, так будет проблематичнее потом.
Если есть какие либо библиотеки или сторонние файлы, которые требуют тестов, то также создаем отдельную папку для них (например, utils) и проверяем.
Далее идут файлы хелперы. Так сложно объяснить, что это такое, но в общем, это такие sol файлы в которых прописаны некоторые функции, с помощью которых будет легче проводить сами тесты. Чаще всего они так и называются Helpers.sol или с добавление имени контракта в начале. Тут прописываются переменные, импорты, структуры и функции.
При встрече с ними, крайне рекомендую начинать изучение именно с них.
Сложнее всего иногда бывает определить контракт входа, т.е. с какого контракта начинается взаимодействие с остальными. И от какого лица. Ведь некоторые контракты могут разворачивать только другие контракты (фабрики), или частные лица, или только Сейф и т.д.
При написание своих тестов, мы определяем изначальные условия: контракт входа, его настройки (нужно ли сминтить токены и забросить туда), его пользователей и т.д. В этом очень сильно помогают как раз те хелперы.
И только потом начинаем писать свои тесты.
Если вы хотите действительно научиться писать тесты, то возьмите конкурсный проект и просто сначала изучайте, а потом пробуйте писать свои.
Очень жаль, что нет полноценного курса по проведению тестов.
#tests
👍2
Про внешние контракты в Foundry
И еще один момент для проведения тестов. Мне сегодня попался контракт для аудита, в котором был внешний контракт токена, т.е. уже задеплоенный в mainnet.
Требовалось сделать форк mainnet к себе в рабочую среду и уже оттуда проводить тесты.
Для форка потребуется зарегистрировать на Alchemy или Infura и получить специальную ссылку, которую позже записать в .env файл, например, под переменной ETH_RPC_URL.
Но сейчас не об этом.
В общем, у меня была переменная:
IMainToken internal _token;
которая в SetUp функции определялась внешним контрактом:
_token = IMainToken (0x84385v475473...);
и импортировалась из файла интерфейса:
import { IMainToken} from "./utils/IMainToken.sol";
И вот для доступа к этому внешнему контракту и требовался форк. Но можно сделать и без него только с локальной сетью.
Нужно просто скопировать задеплоенный контракт, сохранить его в папке проекта и затем импортировать:
import { MainToken} from "./utils/MainToken.sol";
далее можно через
ptoken = new MainToken();
создать объект и работать с ним.
Однако, если в связанных с IMainToken других файлах есть обращения к токену, то они могут выкидывать ошибку при попытке провести тест. Поэтому потребуется немного доработать:
Оставить оба импорта:
import { MainToken} from "./utils/MainToken.sol";
import { IMainToken} from "./utils/IMainToken.sol";
Затем создать новый контракт токена:
ptoken = new MainToken();
и уже к к токену в файле определить созданный контракт:
_token = address(ptoken);
Тогда все будет работать. Проверил на двух проектах. Надеюсь и вам поможет.
#foundry
И еще один момент для проведения тестов. Мне сегодня попался контракт для аудита, в котором был внешний контракт токена, т.е. уже задеплоенный в mainnet.
Требовалось сделать форк mainnet к себе в рабочую среду и уже оттуда проводить тесты.
Для форка потребуется зарегистрировать на Alchemy или Infura и получить специальную ссылку, которую позже записать в .env файл, например, под переменной ETH_RPC_URL.
Но сейчас не об этом.
В общем, у меня была переменная:
IMainToken internal _token;
которая в SetUp функции определялась внешним контрактом:
_token = IMainToken (0x84385v475473...);
и импортировалась из файла интерфейса:
import { IMainToken} from "./utils/IMainToken.sol";
И вот для доступа к этому внешнему контракту и требовался форк. Но можно сделать и без него только с локальной сетью.
Нужно просто скопировать задеплоенный контракт, сохранить его в папке проекта и затем импортировать:
import { MainToken} from "./utils/MainToken.sol";
далее можно через
ptoken = new MainToken();
создать объект и работать с ним.
Однако, если в связанных с IMainToken других файлах есть обращения к токену, то они могут выкидывать ошибку при попытке провести тест. Поэтому потребуется немного доработать:
Оставить оба импорта:
import { MainToken} from "./utils/MainToken.sol";
import { IMainToken} from "./utils/IMainToken.sol";
Затем создать новый контракт токена:
ptoken = new MainToken();
и уже к к токену в файле определить созданный контракт:
_token = address(ptoken);
Тогда все будет работать. Проверил на двух проектах. Надеюсь и вам поможет.
#foundry
👍2
Читаем отчеты вместе. 3
На сегодня у нас отчет с code4reana, которые делали аудит для Olympus DAO. Он слегка сложноват, но можно читать и пытаться понять общий смысл того, что хотели донести аудиторы.
Были найдены 3 крупные уязвимости, 32 средних, а также некоторое количество мелких.
Что мне нравится в отчетах code3rena, что там всегда есть упоминания по экономии газа и те мелкие ошибки, на которые в других конкурсах не обращают внимания. А ведь за них тоже платят!
Читаем новый аудит и делаем заметки!
#report #audit
На сегодня у нас отчет с code4reana, которые делали аудит для Olympus DAO. Он слегка сложноват, но можно читать и пытаться понять общий смысл того, что хотели донести аудиторы.
Были найдены 3 крупные уязвимости, 32 средних, а также некоторое количество мелких.
Что мне нравится в отчетах code3rena, что там всегда есть упоминания по экономии газа и те мелкие ошибки, на которые в других конкурсах не обращают внимания. А ведь за них тоже платят!
Читаем новый аудит и делаем заметки!
#report #audit