Подборка инструментов для web3
Прекрасная подборка от аудиторской компании Quill Audits включает в себя: Blockchain Explorers, декомпиляторы, раcширения для браузера, проверки на rug pull, визуализаторы транзакций и много чего еще.
Сохраните себе, чтобы не потерять.
#tools #toolbox
Прекрасная подборка от аудиторской компании Quill Audits включает в себя: Blockchain Explorers, декомпиляторы, раcширения для браузера, проверки на rug pull, визуализаторы транзакций и много чего еще.
Сохраните себе, чтобы не потерять.
#tools #toolbox
GitHub
GitHub - Quillhash/Web3-Security-Tools: This repository contains a list of the most popular and widely used tools in web3 security.…
This repository contains a list of the most popular and widely used tools in web3 security. If you find any tools missing, you can create a pull request and be a contribute the project. - Quillhash...
👍2
Небольшая дата для канала
Сегодня ровно пять месяцев, как был создан этот канал! Я даже не думал тогда, что он продержится так долго, учитывая что я никогда не вел блоги, а изначальная задумка была просто выучить солидити в компании единомышленников.
На канале вышло более 550 постов!
Выложено более 50 уроков!
Расписано огромное количество материала!
Освещены практически все темы, которые можно найти на популярных курсах!
В нашей компании 143 участника!
Это невероятно круто! Спасибо, что вы с нами! Ваша поддержка и комментарии очень сильно помогают мне не бросать канал и двигаться дальше!
🥳🥳🥳🥳🥳🥳🥳🥳🥳
Сегодня ровно пять месяцев, как был создан этот канал! Я даже не думал тогда, что он продержится так долго, учитывая что я никогда не вел блоги, а изначальная задумка была просто выучить солидити в компании единомышленников.
На канале вышло более 550 постов!
Выложено более 50 уроков!
Расписано огромное количество материала!
Освещены практически все темы, которые можно найти на популярных курсах!
В нашей компании 143 участника!
Это невероятно круто! Спасибо, что вы с нами! Ваша поддержка и комментарии очень сильно помогают мне не бросать канал и двигаться дальше!
🥳🥳🥳🥳🥳🥳🥳🥳🥳
🔥10👍3
Задачи на уязвимости
В некоторых чатах и группах часто встречал вопросы о том, какие вообще существуют сайты, где можно порешать задачки, по типу популярного Ethernaut.
Я собрал в один пост самые популярные. Конечно, есть еще более мелкие, но они, так или иначе повторяют задачи из этого списка.
Вообще я заметил, что есть некая пропасть между задачками стартового уровня и профессионального. Нет, такого знаете ли, середнячка.
Более того, после этих задач вы начнете видеть месте, где могут скрываться потенциальные уязвимости, но чтобы делать аудит, скажем на code4arena, то нужно будет некоторое время потратить на изучение прошедших отчетов.
Итак, популярные сборники задач:
Capture the Ether
The Ethernaut
CryptoZombies
Damn Vulnerable DeFi
DeFiHack
CryptoHack
EtherHack
Cipher Shastra
Speedrun Ethereum
CTF Blockchain Challenges
Как обычно, можете спокойно делать репосты и делиться среди своих групп.
#security #challenges #task
В некоторых чатах и группах часто встречал вопросы о том, какие вообще существуют сайты, где можно порешать задачки, по типу популярного Ethernaut.
Я собрал в один пост самые популярные. Конечно, есть еще более мелкие, но они, так или иначе повторяют задачи из этого списка.
Вообще я заметил, что есть некая пропасть между задачками стартового уровня и профессионального. Нет, такого знаете ли, середнячка.
Более того, после этих задач вы начнете видеть месте, где могут скрываться потенциальные уязвимости, но чтобы делать аудит, скажем на code4arena, то нужно будет некоторое время потратить на изучение прошедших отчетов.
Итак, популярные сборники задач:
Capture the Ether
The Ethernaut
CryptoZombies
Damn Vulnerable DeFi
DeFiHack
CryptoHack
EtherHack
Cipher Shastra
Speedrun Ethereum
CTF Blockchain Challenges
Как обычно, можете спокойно делать репосты и делиться среди своих групп.
#security #challenges #task
👍2
Новая задача
Давно что-то не было новых задач на поиск уязвимостей. Попробуйте решить вот эту. Достаточно простая и скорее тренирует наблюдательность.
Подсказка
А что, если пользователь захочет вызвать эту функцию для самого себя? Потребуется ли какая-нибудь проверка, чтобы никто не смог нажиться на нас?
#task #challenge
Давно что-то не было новых задач на поиск уязвимостей. Попробуйте решить вот эту. Достаточно простая и скорее тренирует наблюдательность.
Подсказка
👍2
И еще одна задача
Сложнее, чем предыдущая. В комментах писали, что это взято из кода одной из популярных бирж, которую взломали в этом году, как раз таки из-за этой уязвимости. Сможете понять, в чем тут проблема?
Подсказка
Не зря в смарт контрактах основный принцип "ноль доверия" и любой пользовательский вводи данных нужно проверять. Вы бы допустили ли бы, чтобы в вашем контракте пользователь мог указывать любой токен или сделали бы какой-нибудь фильтр или проверку?
#task #challenge
Сложнее, чем предыдущая. В комментах писали, что это взято из кода одной из популярных бирж, которую взломали в этом году, как раз таки из-за этой уязвимости. Сможете понять, в чем тут проблема?
Подсказка
👍2
И последняя на сегодня
Забавная и легкая задача. особенно для тех, кто проходил Capture The Ether. Как можно взломать этот контракт?
Подсказка
Вспомните, за что отвечает unchecked.
#task #challenge
Забавная и легкая задача. особенно для тех, кто проходил Capture The Ether. Как можно взломать этот контракт?
Подсказка
👍2
Следующая ступень аудитора
В общем, мне немного надоело решать задачи и читать аудиты, а заниматься этим каждый день до Нового года перестало казаться хорошим планом. И я решил пойти чуть дальше и зарегистрироваться на bug bounty площадках: code4rena, sherlock и Immunefi.
В Твиттере / Медиум / Миррор очень часто пользователи пишут, что они занимают такое-то место в этих проектах, и, как я понял, это тоже играет некую бонусную роль при получении работы.
Более того, если сможешь найти баг, то тебе заплатят за него, что не может не радовать.
По регистрации, самая простая система в Immunefi: в разделе Explore bounties показаны все текущие контесты. Вы заполняете небольшую анкету, подключаете свой кошелек и можете начинать аудит.
На Шерлоке все примерно также с кошельком и анкетой, но у меня вызвал вопросы одно из полей при регистрации, а именно то, где нужно указать Handle. Для этого пришлось писать им в Дискорд. Ответили в течение часа.
С code4rena чуть сложнее. Вы идете на сайт, заполняете анкету, затем присоединяетесь к их Дискорд каналу, в определенной ветке пишите что-то типа I-want-to-be-a-warden, и админ проверяет данные. Если все ок, то через пару часов доступ будет открыт.
Как я понял, найденные баги оформляются на специальной форме на сайте, при этом обязательно написать PoC - Proof of Concept - доказательство бага. Это может быть простое пошаговое описание действий взлома, тест в hh или foundry.
Сегодня хочу немного "покрутить" контесты, понять, как подготовить рабочую зону, как все устроено при скачивании контрактов и т.д.
Также, не могу объяснить, но в сообществе началась какая-то повальная любовь к foundry. Хочу почитать про него чуть больше. Если будет что-то интересно, то выложу здесь.
Всем приятного дня и легкого обучения!
В общем, мне немного надоело решать задачи и читать аудиты, а заниматься этим каждый день до Нового года перестало казаться хорошим планом. И я решил пойти чуть дальше и зарегистрироваться на bug bounty площадках: code4rena, sherlock и Immunefi.
В Твиттере / Медиум / Миррор очень часто пользователи пишут, что они занимают такое-то место в этих проектах, и, как я понял, это тоже играет некую бонусную роль при получении работы.
Более того, если сможешь найти баг, то тебе заплатят за него, что не может не радовать.
По регистрации, самая простая система в Immunefi: в разделе Explore bounties показаны все текущие контесты. Вы заполняете небольшую анкету, подключаете свой кошелек и можете начинать аудит.
На Шерлоке все примерно также с кошельком и анкетой, но у меня вызвал вопросы одно из полей при регистрации, а именно то, где нужно указать Handle. Для этого пришлось писать им в Дискорд. Ответили в течение часа.
С code4rena чуть сложнее. Вы идете на сайт, заполняете анкету, затем присоединяетесь к их Дискорд каналу, в определенной ветке пишите что-то типа I-want-to-be-a-warden, и админ проверяет данные. Если все ок, то через пару часов доступ будет открыт.
Как я понял, найденные баги оформляются на специальной форме на сайте, при этом обязательно написать PoC - Proof of Concept - доказательство бага. Это может быть простое пошаговое описание действий взлома, тест в hh или foundry.
Сегодня хочу немного "покрутить" контесты, понять, как подготовить рабочую зону, как все устроено при скачивании контрактов и т.д.
Также, не могу объяснить, но в сообществе началась какая-то повальная любовь к foundry. Хочу почитать про него чуть больше. Если будет что-то интересно, то выложу здесь.
Всем приятного дня и легкого обучения!
👍3
Как искать уязвимости
Нашел для себя прикольный способ поиска уязвимостей в контракте, который подходит больше всего к проверке функций. Назвал его "А что если".
Вот смотрите вы на свою функцию или на ту, что в контракте аудита, и начинаете:
А что если... :
- Ввести нулевой адрес;
- Ввести свой адрес;
- Не вносить вообще ничего;
- Не тому пользователю отправляются деньги;
- Повлиять на сумму в transfer;
- Деньги / токены / не дойдут;
- Вызвать переполнение;
- Получить права админа;
- Зайти в функцию дважды;
- Подменить логику;
- Нет белого списка;
- Остались апрувы;
- Взять флеш займ;
- Обнулить счет;
- Обойти require;
и так далее. В моем случае, мне так легче сформировать цель атаки, чем вычитывать строку за строкой, пытаясь понять, что с этим кодом не так.
Надеюсь и вам поможет мой способ.
#hint #security
Нашел для себя прикольный способ поиска уязвимостей в контракте, который подходит больше всего к проверке функций. Назвал его "А что если".
Вот смотрите вы на свою функцию или на ту, что в контракте аудита, и начинаете:
А что если... :
- Ввести нулевой адрес;
- Ввести свой адрес;
- Не вносить вообще ничего;
- Не тому пользователю отправляются деньги;
- Повлиять на сумму в transfer;
- Деньги / токены / не дойдут;
- Вызвать переполнение;
- Получить права админа;
- Зайти в функцию дважды;
- Подменить логику;
- Нет белого списка;
- Остались апрувы;
- Взять флеш займ;
- Обнулить счет;
- Обойти require;
и так далее. В моем случае, мне так легче сформировать цель атаки, чем вычитывать строку за строкой, пытаясь понять, что с этим кодом не так.
Надеюсь и вам поможет мой способ.
#hint #security
👍2
Чуть больше о Foundry
Ранее я упоминал, что Foundry становиться все более популярным у зарубежных разработчиков. И это действительно так.
Во-первых, для него не нужно учить дополнительный язык, типа javanoscript или python, все тесты и деплой происходит с помощью Solidity и встроенных опций.
Во-вторых, там уже есть свои крутые настройки, которые использовать намного легче, чем в hardhat.
В-третьих, я только сегодня узнал, что и сам hardhat можно встроить в foundry для локальных тестов в блокчейне.
Короче, крутая штука.
Вот еще одно интересное видео от Патрика Коллинса, который объясняет некоторые моменты foundry. Хоть оно и на английском, но по действиям на экране все предельно понятно.
Уверен, стоит потратить пару дней, чтобы получить базовые навыки работы с ним.
#foundry #hardhat
Ранее я упоминал, что Foundry становиться все более популярным у зарубежных разработчиков. И это действительно так.
Во-первых, для него не нужно учить дополнительный язык, типа javanoscript или python, все тесты и деплой происходит с помощью Solidity и встроенных опций.
Во-вторых, там уже есть свои крутые настройки, которые использовать намного легче, чем в hardhat.
В-третьих, я только сегодня узнал, что и сам hardhat можно встроить в foundry для локальных тестов в блокчейне.
Короче, крутая штука.
Вот еще одно интересное видео от Патрика Коллинса, который объясняет некоторые моменты foundry. Хоть оно и на английском, но по действиям на экране все предельно понятно.
Уверен, стоит потратить пару дней, чтобы получить базовые навыки работы с ним.
#foundry #hardhat
YouTube
Intro to Foundry | The FASTEST Smart Contract Framework
We build a minimal foundry project using a staking application. Showing you how to work with foundry.
How's my thumbnail game? Do I need MOAR RAW POWA?
👩🏻💻 Code: https://github.com/PatrickAlphaC/foundry-play
📚 Learn Foundry: https://book.getfoundry.sh/…
How's my thumbnail game? Do I need MOAR RAW POWA?
👩🏻💻 Code: https://github.com/PatrickAlphaC/foundry-play
📚 Learn Foundry: https://book.getfoundry.sh/…
👍3
Моя базовая настройка Foundry
Немного посидев с Foundry, и попробовав настроить изначальную среду для себя, я пришел к следующей последовательности действий.
P.S. Чуть позже хочу сделать так, чтобы настройка была еще быстрее. Уже есть представление, но нужна практика.
P.S.S. Полагаю, что к данному посту у вас уже будет установлен Foundry. Как это сделать - смотрите посты выше.
Итак идем по шагам.
1. Создаем папку проекта, например Project. Заходим в нее и открываем терминал. Я использую bash (можно и PowerShell).
2. Прописываем forge init и ждем пока установятся все файлы.
3. Пишем yarn init для создание json файла.
4. Далее yarn add hardhat. Он понадобится нам для деплоя контракта в тестовые и локальную сети.
5. npx hardhat и выбираем последний пункт с Create empty hardhat config. Я полностью в тестах перехожу на foundry, поэтому не требуется устанавливать js или ts проекты для дальнейших тестов.
6. yarn add dotenv - устанавливает зависимости для переменных среды. Удобно хранить приватные ключи и доступы к Alchemy.
7. touch remappings.txt (для bash или New-Item remappings.txt powershell) - создание файла для определения путей.
8. Открываем этой файл и прописываем:
@openzeppelin/=lib/openzeppelin-contracts/
@std=lib/forge-std/src/
@chainlink/=lib/chainlink-brownie-contracts/
forge-std/=lib/forge-std/src/
Это пути для файлов forge, и библиотек openzeppelin и chainlink, на случай, если они понадобятся вам в своем проекте.
9. Для установки библиотек прописываем forge install и название репозитария на github, например
forge install OpenZeppelin/openzeppelin-contracts
Все! Среда для написания контрактов, проведения тестов и аудитов готова.
Если захотите сделать деплой контракта в локальную сеть, то создайте узел hardhat через:
yarn hardhat node
получите приватные ключи и аккаунты, затем в консоли можно написать:
forge create projectContract --private-key 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80
или, если работаете с .env:
forge create projectContract --private-key PRIVATE-KEY
Если делаете деплой в сеть, то указываете, например, url Alchemy для этого так:
forge create projectContract --private-key PRIVATE-KEY --rpc-url http://bla.bla.bla
Надеюсь это поможет вам в обучении.
#foundry #hardhat
Немного посидев с Foundry, и попробовав настроить изначальную среду для себя, я пришел к следующей последовательности действий.
P.S. Чуть позже хочу сделать так, чтобы настройка была еще быстрее. Уже есть представление, но нужна практика.
P.S.S. Полагаю, что к данному посту у вас уже будет установлен Foundry. Как это сделать - смотрите посты выше.
Итак идем по шагам.
1. Создаем папку проекта, например Project. Заходим в нее и открываем терминал. Я использую bash (можно и PowerShell).
2. Прописываем forge init и ждем пока установятся все файлы.
3. Пишем yarn init для создание json файла.
4. Далее yarn add hardhat. Он понадобится нам для деплоя контракта в тестовые и локальную сети.
5. npx hardhat и выбираем последний пункт с Create empty hardhat config. Я полностью в тестах перехожу на foundry, поэтому не требуется устанавливать js или ts проекты для дальнейших тестов.
6. yarn add dotenv - устанавливает зависимости для переменных среды. Удобно хранить приватные ключи и доступы к Alchemy.
7. touch remappings.txt (для bash или New-Item remappings.txt powershell) - создание файла для определения путей.
8. Открываем этой файл и прописываем:
@openzeppelin/=lib/openzeppelin-contracts/
@std=lib/forge-std/src/
@chainlink/=lib/chainlink-brownie-contracts/
forge-std/=lib/forge-std/src/
Это пути для файлов forge, и библиотек openzeppelin и chainlink, на случай, если они понадобятся вам в своем проекте.
9. Для установки библиотек прописываем forge install и название репозитария на github, например
forge install OpenZeppelin/openzeppelin-contracts
Все! Среда для написания контрактов, проведения тестов и аудитов готова.
Если захотите сделать деплой контракта в локальную сеть, то создайте узел hardhat через:
yarn hardhat node
получите приватные ключи и аккаунты, затем в консоли можно написать:
forge create projectContract --private-key 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80
или, если работаете с .env:
forge create projectContract --private-key PRIVATE-KEY
Если делаете деплой в сеть, то указываете, например, url Alchemy для этого так:
forge create projectContract --private-key PRIVATE-KEY --rpc-url http://bla.bla.bla
Надеюсь это поможет вам в обучении.
#foundry #hardhat
👍4
Вечерний опрос
Хочу узнать, кто на кого учится в web3. Может позже попробуем замутить что-то командное, или практику для работы организовать.
В общем, кто учится кликаем ниже)
Хочу узнать, кто на кого учится в web3. Может позже попробуем замутить что-то командное, или практику для работы организовать.
В общем, кто учится кликаем ниже)
👍2💯1
На кого учитесь в web3?
Anonymous Poll
35%
Разработчик (фронт и контракты)
2%
Разработчик (только фронт)
18%
Разработчик (только контракты)
18%
Аудитор
27%
Просто слежу за сферой web3
👍1
Что нужно для аудита на Code4rena?
Сегодня я впервые провел аудит контрактов на данном ресурсе, и хотел бы поделиться впечатлениями.
Во-первых, foundry и forge используются в большинстве случаев, поэтому нужно знать хотя бы, как подготовить рабочую среду.
Во-вторых, очень важно знать, как писать тесты и подтверждения своим находкам уязвимостей. Я, вероятно, смог найти две, но так и не понял, как протестировать свою гипотезу. Поэтому я подумываю потратить эту неделю на изучение тестов в foundry.
Тесты - это не простое действие, типа: "А давайте проверим, дойдет ли токен до контракта...", это логическая пошаговая операция с функциями. Зачастую требуется проверить пути из двух и трех контрактов. Например, мы пишем хакерский контракт, затем проверяем результат выполнения его функций на контракт жертвы.
В-третьих, на ремикс не перекинешь. Точнее можешь, но "гемора" будет очень много, да и тесты для подтверждения, вроде как, не напишешь.
В общем, тесты - тесты - тесты. Вот, что самое сложное в работе аудитора.
А так, мои рекомендации - хотите научиться писать хороший код: читайте аудиторские отчеты. Там вы сможете наглядно увидеть все ошибки, которые возникают в "боевых" проектах, а также получить кучу советов по оптимизации газа.
Начинаем штудировать тесты в foundry.
Сегодня я впервые провел аудит контрактов на данном ресурсе, и хотел бы поделиться впечатлениями.
Во-первых, foundry и forge используются в большинстве случаев, поэтому нужно знать хотя бы, как подготовить рабочую среду.
Во-вторых, очень важно знать, как писать тесты и подтверждения своим находкам уязвимостей. Я, вероятно, смог найти две, но так и не понял, как протестировать свою гипотезу. Поэтому я подумываю потратить эту неделю на изучение тестов в foundry.
Тесты - это не простое действие, типа: "А давайте проверим, дойдет ли токен до контракта...", это логическая пошаговая операция с функциями. Зачастую требуется проверить пути из двух и трех контрактов. Например, мы пишем хакерский контракт, затем проверяем результат выполнения его функций на контракт жертвы.
В-третьих, на ремикс не перекинешь. Точнее можешь, но "гемора" будет очень много, да и тесты для подтверждения, вроде как, не напишешь.
В общем, тесты - тесты - тесты. Вот, что самое сложное в работе аудитора.
А так, мои рекомендации - хотите научиться писать хороший код: читайте аудиторские отчеты. Там вы сможете наглядно увидеть все ошибки, которые возникают в "боевых" проектах, а также получить кучу советов по оптимизации газа.
Начинаем штудировать тесты в foundry.
👍3
Тесты с Foundry
Сегодня несколько часов провел, изучая, как пишутся тесты с Foundry. Мало того, что в ру сегменте достаточно мало подробной информации об этом, так еще и в видео, в том числе и зарубежных, показывают крайне простые примеры.
Если брать общее впечатление ото всех материалов, просмотренных мною сегодня, то выигрывают видео от Ильи и официальная документация Foundry.
Что мне мешало с тестами?
Во-первых, не хватало какого-то визуала для отслеживания результата. Например, в Ремиксе очень удобная система с кнопками-функциями и консоли, где отображаются транзакции. Нажал кнопку и смотришь, как все прошло. Есть проблема? Открываешь дебаггер. Да и баланс сразу можно проверить.
В тестах с ethers у меня так не получалось. Возможно, мало практики. Возможно, мое не желание возвращаться к js и прописывать эти длинные строки с await.
Во-вторых, typenoscript, typechain, deploy - все это потрясающие вещи для работы. И вполне можно было подготавливать файл-скелет для каждого проекта и его теста, но что-то не то для меня.
Хочу уточнить, я считаю hardhat, ethers и всю эту структуру очень и очень классной, обязательной для изучения разработчику. И если вы решите остаться на ней и достичь про уровня, то это будет огромным плюсом в резюме.
Почему я решил перейти на Foundry?
Во-первых, пару тестовых заданий на собеседованиях я получал с преднастройками Foundry.
Во-вторых, для аудита на площадках типа code4rena, он используется чаще, а именно аудитом я и хочу заниматься.
В-третьих, написание тестов и их проведение тут быстрее. По крайней мере для меня.
Далее опишу, к чему я пока пришел за день практики.
#foundry
Сегодня несколько часов провел, изучая, как пишутся тесты с Foundry. Мало того, что в ру сегменте достаточно мало подробной информации об этом, так еще и в видео, в том числе и зарубежных, показывают крайне простые примеры.
Если брать общее впечатление ото всех материалов, просмотренных мною сегодня, то выигрывают видео от Ильи и официальная документация Foundry.
Что мне мешало с тестами?
Во-первых, не хватало какого-то визуала для отслеживания результата. Например, в Ремиксе очень удобная система с кнопками-функциями и консоли, где отображаются транзакции. Нажал кнопку и смотришь, как все прошло. Есть проблема? Открываешь дебаггер. Да и баланс сразу можно проверить.
В тестах с ethers у меня так не получалось. Возможно, мало практики. Возможно, мое не желание возвращаться к js и прописывать эти длинные строки с await.
Во-вторых, typenoscript, typechain, deploy - все это потрясающие вещи для работы. И вполне можно было подготавливать файл-скелет для каждого проекта и его теста, но что-то не то для меня.
Хочу уточнить, я считаю hardhat, ethers и всю эту структуру очень и очень классной, обязательной для изучения разработчику. И если вы решите остаться на ней и достичь про уровня, то это будет огромным плюсом в резюме.
Почему я решил перейти на Foundry?
Во-первых, пару тестовых заданий на собеседованиях я получал с преднастройками Foundry.
Во-вторых, для аудита на площадках типа code4rena, он используется чаще, а именно аудитом я и хочу заниматься.
В-третьих, написание тестов и их проведение тут быстрее. По крайней мере для меня.
Далее опишу, к чему я пока пришел за день практики.
#foundry
👍2
Тесты с Foundry. Часть 2
Прежде всего тесты пишутся на Solidity. Если вы только начали учить блокчейн разработку, то вам не придется дополнительно изучать JavaScript, typenoscript и node, а это еще 3-6 месяцев дополнительного времени обучения минимум.
После того, как вы выполнили forge init в папке проекта, там появятся структура из нескольких директорий.
В lib хранятся все подключенные библиотеки (например, openzeppelin), в noscript можно будет найти json файл с abi контракта, в src пишутся контракты проекта, а в test - соответственно тесты.
Файлы для тестов следует называть по определённому шаблону. Например, контракт у вас под именем Day.sol, следовательно контракт для теста будет - Day.t.sol, т.е. название проекта, потом буква t, потом sol.
Открыв файл теста, мы делаем практически все также как и при написании обычного контракта. Пишем SPDX-License, pragma, импортируем библиотеку для тестов:
import "forge-std/Test.sol";
и наши контракты
import {Day} from "../src/Day.sol";
Далее нужно назвать наш контракт, как оригинальный и добавить Test, например DayTest, подключив наследование от контракта Test.sol, например:
contract DayTest is Test {}
Далее начинается самое интересное с тестами.
#foundry
Прежде всего тесты пишутся на Solidity. Если вы только начали учить блокчейн разработку, то вам не придется дополнительно изучать JavaScript, typenoscript и node, а это еще 3-6 месяцев дополнительного времени обучения минимум.
После того, как вы выполнили forge init в папке проекта, там появятся структура из нескольких директорий.
В lib хранятся все подключенные библиотеки (например, openzeppelin), в noscript можно будет найти json файл с abi контракта, в src пишутся контракты проекта, а в test - соответственно тесты.
Файлы для тестов следует называть по определённому шаблону. Например, контракт у вас под именем Day.sol, следовательно контракт для теста будет - Day.t.sol, т.е. название проекта, потом буква t, потом sol.
Открыв файл теста, мы делаем практически все также как и при написании обычного контракта. Пишем SPDX-License, pragma, импортируем библиотеку для тестов:
import "forge-std/Test.sol";
и наши контракты
import {Day} from "../src/Day.sol";
Далее нужно назвать наш контракт, как оригинальный и добавить Test, например DayTest, подключив наследование от контракта Test.sol, например:
contract DayTest is Test {}
Далее начинается самое интересное с тестами.
#foundry
👍2
Тесты с Foundry. Часть 3
Я также рекомендовал бы сразу подключить еще один служебный контракт в файл с тестами, а именно:
import "forge-std/console.sol";
Он позволит в тестах вызывать console.log() и получать нужные данные в терминале. Очень удобно, особенно, если вы хотите посмотреть какую-нибудь информацию об адресе или балансе.
Далее создаем переменные нашего контракта для теста:
Day public day;
По сути, благодаря Foundry нам не нужно прописывать getContractFactory, deploy, deployed, loadFixture, it тесты и много чего еще.
Идем дальше.
Порой нам нужно создать изначальные условия для контракта, что-то вроде положить на баланс токены, сделать минт nft и т.д. Для этого тут есть специальная функция:
function setUp() public {}
Именно в нее мы можем записать создание контрактов и передачу в их конструкторы какие-либо параметры. Например:
function setUp() public {
day = new Day(constructor params);
}
Теперь в остальных функциях тестов мы можем вызывать функции в контракте, как и обычно: day.increment().
Также существуют специальные Foundry Cheat Codes, которые позволяют выполнять специальные действия, в том числе эмулировать вызовы функций от имени других пользователей или контрактов, а также управлять block.timestamp, block.number, difficulty и остальными.
При этом не нужно писать длинные строки с await, достаточно в функции вызвать, например, vm.roll(100) и номер блока сразу изменится.
Также можно читать переменные, которые определяются в начале контракта, такие как owner. Для этого можно сделать так:
console.log(day.owner());
С помощью дополнительной библиотеки StdStorage можно также читать значения из слотов памяти.
Для того чтобы подключиться к вызову функции от другого аккаунта или контракта, как мы делали в hh connect(hacker), тут мы можем эмулировать действие, вызвав служебную функцию vm.prank(hacker). Дальше вызовы будут от данного адреса.
С адресами также все просто. Не обязательно запускать узел или использовать предустановленные адреса, можно также создать адрес для теста:
adderess alisa = address(0x01);
и дальше действовать уже от имени Алисы.
Это еще далеко не все, что можно делать с Foundry. Думаю завтра я посмотрю как делать fuzz тесты и напишу сюда.
А в следующем посте просто расскажу про команды для тестов в терминале.
#foundry
Я также рекомендовал бы сразу подключить еще один служебный контракт в файл с тестами, а именно:
import "forge-std/console.sol";
Он позволит в тестах вызывать console.log() и получать нужные данные в терминале. Очень удобно, особенно, если вы хотите посмотреть какую-нибудь информацию об адресе или балансе.
Далее создаем переменные нашего контракта для теста:
Day public day;
По сути, благодаря Foundry нам не нужно прописывать getContractFactory, deploy, deployed, loadFixture, it тесты и много чего еще.
Идем дальше.
Порой нам нужно создать изначальные условия для контракта, что-то вроде положить на баланс токены, сделать минт nft и т.д. Для этого тут есть специальная функция:
function setUp() public {}
Именно в нее мы можем записать создание контрактов и передачу в их конструкторы какие-либо параметры. Например:
function setUp() public {
day = new Day(constructor params);
}
Теперь в остальных функциях тестов мы можем вызывать функции в контракте, как и обычно: day.increment().
Также существуют специальные Foundry Cheat Codes, которые позволяют выполнять специальные действия, в том числе эмулировать вызовы функций от имени других пользователей или контрактов, а также управлять block.timestamp, block.number, difficulty и остальными.
При этом не нужно писать длинные строки с await, достаточно в функции вызвать, например, vm.roll(100) и номер блока сразу изменится.
Также можно читать переменные, которые определяются в начале контракта, такие как owner. Для этого можно сделать так:
console.log(day.owner());
С помощью дополнительной библиотеки StdStorage можно также читать значения из слотов памяти.
Для того чтобы подключиться к вызову функции от другого аккаунта или контракта, как мы делали в hh connect(hacker), тут мы можем эмулировать действие, вызвав служебную функцию vm.prank(hacker). Дальше вызовы будут от данного адреса.
С адресами также все просто. Не обязательно запускать узел или использовать предустановленные адреса, можно также создать адрес для теста:
adderess alisa = address(0x01);
и дальше действовать уже от имени Алисы.
Это еще далеко не все, что можно делать с Foundry. Думаю завтра я посмотрю как делать fuzz тесты и напишу сюда.
А в следующем посте просто расскажу про команды для тестов в терминале.
#foundry
👍6
Тесты с Foundry. Часть 4
Команды в тестах также предельно просты:
forge build - собирает проект и создает abi контаркта;
forge test - проводит тесты контрактов из папки test;
forget test -v (-vv, -vvv, -vvvv) - дает больше информации по проведенным тестам;
forge test -vv -m funcName - проведение теста конкретной функции;
forge test --gas-report - отчет по газу;
forge coverage - покрытие тестами;
Также можно дополнительно подключить библиотеки для расширения списка возможных функций для всяких тестов: для логирования, для assertions, cheat codes, ошибок, памяти и математики.
Для деплоя можно пользоваться внутренними функциями Foundry, или же подключить HardHat и использовать его средства для деплоя в разные сети.
Это то, что получилось узнать и попробовать за день. Надеюсь, позже еще смогу написать больше про работу с Foundry.
#foundry
Команды в тестах также предельно просты:
forge build - собирает проект и создает abi контаркта;
forge test - проводит тесты контрактов из папки test;
forget test -v (-vv, -vvv, -vvvv) - дает больше информации по проведенным тестам;
forge test -vv -m funcName - проведение теста конкретной функции;
forge test --gas-report - отчет по газу;
forge coverage - покрытие тестами;
Также можно дополнительно подключить библиотеки для расширения списка возможных функций для всяких тестов: для логирования, для assertions, cheat codes, ошибок, памяти и математики.
Для деплоя можно пользоваться внутренними функциями Foundry, или же подключить HardHat и использовать его средства для деплоя в разные сети.
Это то, что получилось узнать и попробовать за день. Надеюсь, позже еще смогу написать больше про работу с Foundry.
#foundry
👍5
Тесты с Foundry. Часть 5
Еще одна классная штука, которая есть в Foundry и нет в hardhat или remix, это проведение fuzz тестов.
Fuzz тесты - это такие операции с функциями, когда в ее параметры подставляют разные случайные значения и пытаются сломать выполнение.
Ранее для подобных тестов использовались сторонние сервисы, типа Echidna от Trail of Bits. Это, конечно, очень крутая программа, но если вам нужно сделать простые тесты, то Foundry подойдет, как нельзя кстати.
Возьмем к примеру такую функцию:
function testWithdraw() public {
payable(address(safe)).transfer(1 ether);
uint256 preBalance = address(this).balance;
safe.withdraw();
uint256 postBalance = address(this).balance;
assertEq(preBalance + 1 ether, postBalance);
}
Если мы переводим 1-2 Эфира, то все ок. А если кто-то захочет сломать функцию и перевести другие суммы?
И вот как она будет выглядеть в fuzz тестах:
function testWithdraw(uint256 amount) public {
payable(address(safe)).transfer(amount);
uint256 preBalance = address(this).balance;
safe.withdraw();
uint256 postBalance = address(this).balance;
assertEq(preBalance + amount, postBalance);
}
Т.е. мы разрешаем Foundry вставлять в параметры функции свои значения под uint amount и проверять исполнение.
Если прогнать этот тест, то мы увидим, что он провалится, так как на одном из шагов будет предложено значение 2**96 wei, что вызовет overflow.
В документации сказано, что так можно проверять и другие типы данных: строки и булево значения. Но чаще всего используют именно для чисел.
Также в тестах можно определять границы подставляемых значений с помощью команды vm.assume(), например, для нашего случая:
vm.assume(amount > 0.1 ether);
Сами тесты прогоняются 256 раз по умолчанию. Другими словами, программа попробует подставить 256 различных значений и проверить их.
Мы можем изменить этот параметр в файле конфигурации, добавив строку:
fuzz_runs = 10000 (количество тестов)
Подобные тесты очень помогают для проверки расчетов и транзакций в наших функциях, так как мы никогда не сможем предугадать, кто и как будет использовать наш контракт.
В общем, Foundry сильно облегчает нам работу!
#foundry
Еще одна классная штука, которая есть в Foundry и нет в hardhat или remix, это проведение fuzz тестов.
Fuzz тесты - это такие операции с функциями, когда в ее параметры подставляют разные случайные значения и пытаются сломать выполнение.
Ранее для подобных тестов использовались сторонние сервисы, типа Echidna от Trail of Bits. Это, конечно, очень крутая программа, но если вам нужно сделать простые тесты, то Foundry подойдет, как нельзя кстати.
Возьмем к примеру такую функцию:
function testWithdraw() public {
payable(address(safe)).transfer(1 ether);
uint256 preBalance = address(this).balance;
safe.withdraw();
uint256 postBalance = address(this).balance;
assertEq(preBalance + 1 ether, postBalance);
}
Если мы переводим 1-2 Эфира, то все ок. А если кто-то захочет сломать функцию и перевести другие суммы?
И вот как она будет выглядеть в fuzz тестах:
function testWithdraw(uint256 amount) public {
payable(address(safe)).transfer(amount);
uint256 preBalance = address(this).balance;
safe.withdraw();
uint256 postBalance = address(this).balance;
assertEq(preBalance + amount, postBalance);
}
Т.е. мы разрешаем Foundry вставлять в параметры функции свои значения под uint amount и проверять исполнение.
Если прогнать этот тест, то мы увидим, что он провалится, так как на одном из шагов будет предложено значение 2**96 wei, что вызовет overflow.
В документации сказано, что так можно проверять и другие типы данных: строки и булево значения. Но чаще всего используют именно для чисел.
Также в тестах можно определять границы подставляемых значений с помощью команды vm.assume(), например, для нашего случая:
vm.assume(amount > 0.1 ether);
Сами тесты прогоняются 256 раз по умолчанию. Другими словами, программа попробует подставить 256 различных значений и проверить их.
Мы можем изменить этот параметр в файле конфигурации, добавив строку:
fuzz_runs = 10000 (количество тестов)
Подобные тесты очень помогают для проверки расчетов и транзакций в наших функциях, так как мы никогда не сможем предугадать, кто и как будет использовать наш контракт.
В общем, Foundry сильно облегчает нам работу!
#foundry
👍3
Тесты с Foundry. Часть 6
В видео у Ильи мы делали тесты конечных результатов выполнения функции с помощью команды assertEq(), которая проверяет равны ли введённые значения.
В Foundry есть и другие команды для проверки условий:
assertGt() - проверка, если "а" больше "б";
assertGe() - проверка, если "а" больше или равно "б";
assertLt() - проверка, если "а" меньше "б";
assertLe() - проверка, если "а" меньше или равно "б";
assertTrue() - проверка, если значение возвращает true;
Также возможно и такие проверки:
assertEqDecimal() - проверка равности значений decimals, например:
uint256 a = 1 ether;
uint256 b = 1e18 wei;
assertEqDecimal(a, b, 18);
assertEq32() - равны ли значения bytes32;
assertEq0() - равны ли значения bytes;
Еще мне очень понравилось, что достаточно много команд и проверок можно выполнять в самой консоли. Об этом можно почитать тут.
В общем, с помощью cast команд в локальной сети можно просматривать транзакции, подписывать ее, рассчитывать газ, получить код деплоя или информацию о блоке, работать с адресом и abi контракта, а также получать данные из etherscan (при наличии API ключа) и много чего еще.
Вот, чем больше я изучаю Foundry, тем больше он мне нравится. И что самое интересное, это довольно таки новый проект. Есть большая вероятность, что с дальнейшим развитием, он станет еще круче!
#foundry
В видео у Ильи мы делали тесты конечных результатов выполнения функции с помощью команды assertEq(), которая проверяет равны ли введённые значения.
В Foundry есть и другие команды для проверки условий:
assertGt() - проверка, если "а" больше "б";
assertGe() - проверка, если "а" больше или равно "б";
assertLt() - проверка, если "а" меньше "б";
assertLe() - проверка, если "а" меньше или равно "б";
assertTrue() - проверка, если значение возвращает true;
Также возможно и такие проверки:
assertEqDecimal() - проверка равности значений decimals, например:
uint256 a = 1 ether;
uint256 b = 1e18 wei;
assertEqDecimal(a, b, 18);
assertEq32() - равны ли значения bytes32;
assertEq0() - равны ли значения bytes;
Еще мне очень понравилось, что достаточно много команд и проверок можно выполнять в самой консоли. Об этом можно почитать тут.
В общем, с помощью cast команд в локальной сети можно просматривать транзакции, подписывать ее, рассчитывать газ, получить код деплоя или информацию о блоке, работать с адресом и abi контракта, а также получать данные из etherscan (при наличии API ключа) и много чего еще.
Вот, чем больше я изучаю Foundry, тем больше он мне нравится. И что самое интересное, это довольно таки новый проект. Есть большая вероятность, что с дальнейшим развитием, он станет еще круче!
#foundry
👍3
Защита от атак Signature Replay
Несколько раз в задачах встречал уязвимости с подписями пользователей транзакций, что приводило к Front run и Signature Replay атакам. Мне захотелось чуть больше узнать о них. И для начала небольшой пример кода:
function unlock(
address _to,
uint256 _amount,
uint8[] _v,
bytes32[] _r,
bytes32[] _s
)
external
{
require(_v.length >= 5);
bytes32 hashData = keccak256(_to, _amount);
for (uint i = 0; i < _v.length; i++) {
address recAddr = ecrecover(hashData, _v[i], _r[i], _s[i]);
require(_isValidator(recAddr));
}
to.transfer(_amount);
}
Это сильно упрощенный код из аудиторского отчета одного из мостов. По своей сути, функция запрашивает как минимум 5 подписей, чтобы разблокировать сумму и отправить ее получателю.
Другими словами, поставщик должен собрать пять подписей на проведение транзакции, после чего он может отправить ее на исполнение. Поняли в чем подвох?
В тот момент, когда поставщик отправит транзакцию в мемпул, злоумышленник может скопировать данные подписи и сам вызвать unlock() уже со своим адресом для получения активов. И делать это можно до тех пор, пока пул не будет опустошен!
Самой простой защитой было бы добавить nonce в аргументы функции (индивидуальный номер) и проверку типа require(_nonce == nonce++).
Как же получше защититься от них?
Вот три самых популярных решения:
1. Сохранять message hash в контракте, и позже проверять его на предмет повтора;
2. Включать в message hash адрес контракта, чтобы удостовериться, что сообщение используется только в данном контрактом;
3. Никогда не генерировать message hash вместе с подписью пользователя.
Будьте очень осторожны в работе с подписями и в обязательном порядке проверяйте их уникальность.
#signaturereplay #signature #replay #security
Несколько раз в задачах встречал уязвимости с подписями пользователей транзакций, что приводило к Front run и Signature Replay атакам. Мне захотелось чуть больше узнать о них. И для начала небольшой пример кода:
function unlock(
address _to,
uint256 _amount,
uint8[] _v,
bytes32[] _r,
bytes32[] _s
)
external
{
require(_v.length >= 5);
bytes32 hashData = keccak256(_to, _amount);
for (uint i = 0; i < _v.length; i++) {
address recAddr = ecrecover(hashData, _v[i], _r[i], _s[i]);
require(_isValidator(recAddr));
}
to.transfer(_amount);
}
Это сильно упрощенный код из аудиторского отчета одного из мостов. По своей сути, функция запрашивает как минимум 5 подписей, чтобы разблокировать сумму и отправить ее получателю.
Другими словами, поставщик должен собрать пять подписей на проведение транзакции, после чего он может отправить ее на исполнение. Поняли в чем подвох?
В тот момент, когда поставщик отправит транзакцию в мемпул, злоумышленник может скопировать данные подписи и сам вызвать unlock() уже со своим адресом для получения активов. И делать это можно до тех пор, пока пул не будет опустошен!
Самой простой защитой было бы добавить nonce в аргументы функции (индивидуальный номер) и проверку типа require(_nonce == nonce++).
Как же получше защититься от них?
Вот три самых популярных решения:
1. Сохранять message hash в контракте, и позже проверять его на предмет повтора;
2. Включать в message hash адрес контракта, чтобы удостовериться, что сообщение используется только в данном контрактом;
3. Никогда не генерировать message hash вместе с подписью пользователя.
Будьте очень осторожны в работе с подписями и в обязательном порядке проверяйте их уникальность.
#signaturereplay #signature #replay #security
👍2
Новые уязвимости? Часть 1. Фантомные функции
Нашел интересную статью на английском языке, где приводятся возможные новые уязвимости, на которые стоит обращать внимание. Предлагаю перевод в нескольких постах.
Фантомные функции
Представьте, что разработчик делает вызов случайной функции в НЕзадеплоеный контракт. Интуитивно, он ожидает, что транзакция будет откатана (revert), но это не так.
Объяснить это можно особенностью работы EVM: вся работа байткода контракта заканчивается специальным опкодом Stop. Именно он говорит EVM вернуть результат (return) без каких-либо ошибок.
Ситуация меняется с задеплоенными контрактами, когда разработчик вызывает несуществующую функцию и EVM делает revert.
Но и тут есть нюанс, а именно наличие fallback функции, которая выполняет определенные действия в этом случае.
Вот тут и может таиться уязвимость. Разработчик ожидает, что:
1) Транзакция откатится, если такой функции в контракте не существует;
2) А если такая функция существует, то транзакция может откатиться, если что-то пойдет не так;
Но, что если вызываемой функции в контракте нет, но есть fallback функция, которая принимает любые параметры и никогда не откатывается? Посмотрите на код ниже:
function depositWithPermit(...) {
IERC20(token).permit(receiver, address(this), value, deadline, v, r, s);
IERC20(token).transferFrom(receiver, address(this), value);
}
Это реальный код одного из проектов. Разработчики ожидали, что transferFrom() может быть вызван только после того как пользователь пройдет permit(), в другом случае должен был произойти откат. Однако некоторые токены, типа WETH, не имеют функции permit(), но есть fallback(), которая никогда не делает revert.
В этом случае хакер может пройти permit() и опустошить контракт, заранее сделав approve() на себя.
При аудите контракта всегда нужно предполагать, что разработчики могли предусмотреть не все случаи откатов транзакций, или не знать о подобных вариантах работы EVM.
#security #phantom
Нашел интересную статью на английском языке, где приводятся возможные новые уязвимости, на которые стоит обращать внимание. Предлагаю перевод в нескольких постах.
Фантомные функции
Представьте, что разработчик делает вызов случайной функции в НЕзадеплоеный контракт. Интуитивно, он ожидает, что транзакция будет откатана (revert), но это не так.
Объяснить это можно особенностью работы EVM: вся работа байткода контракта заканчивается специальным опкодом Stop. Именно он говорит EVM вернуть результат (return) без каких-либо ошибок.
Ситуация меняется с задеплоенными контрактами, когда разработчик вызывает несуществующую функцию и EVM делает revert.
Но и тут есть нюанс, а именно наличие fallback функции, которая выполняет определенные действия в этом случае.
Вот тут и может таиться уязвимость. Разработчик ожидает, что:
1) Транзакция откатится, если такой функции в контракте не существует;
2) А если такая функция существует, то транзакция может откатиться, если что-то пойдет не так;
Но, что если вызываемой функции в контракте нет, но есть fallback функция, которая принимает любые параметры и никогда не откатывается? Посмотрите на код ниже:
function depositWithPermit(...) {
IERC20(token).permit(receiver, address(this), value, deadline, v, r, s);
IERC20(token).transferFrom(receiver, address(this), value);
}
Это реальный код одного из проектов. Разработчики ожидали, что transferFrom() может быть вызван только после того как пользователь пройдет permit(), в другом случае должен был произойти откат. Однако некоторые токены, типа WETH, не имеют функции permit(), но есть fallback(), которая никогда не делает revert.
В этом случае хакер может пройти permit() и опустошить контракт, заранее сделав approve() на себя.
При аудите контракта всегда нужно предполагать, что разработчики могли предусмотреть не все случаи откатов транзакций, или не знать о подобных вариантах работы EVM.
#security #phantom
❤2