ch
Feedback
Solidity. Смарт контракты и аудит

Solidity. Смарт контракты и аудит

前往频道在 Telegram

Обучение Solidity. Уроки, аудит, разбор кода и популярных сервисов

显示更多
2 597
订阅者
无数据24 小时
+57
+930
帖子存档
Как стать web3 разработчиком? Часть 1 За последнее время на канал пришло много новеньких, поэтому, думаю, стоит сделать пару постов на тему старта своей карьеры в web3 и ответить на некоторые популярные вопросы. Участников с опытом попрошу оставлять свои комментарии к постам, если вдруг будет, что добавить. Итак, поехали. 1. Какие профессии есть в web3? Из вакансий, что я просматривал на зарубежных площадках, могу выделить следующие направления: - Разработчик смарт контрактов; - Разработчик смарт контрактов + фронтэнд; - Аудитор смарт контрактов; - Блокчейн разработчик; - Архитектор систем (для DAO, gameFi, DeFi); - Экономист (токеномика); - Комьюнити менеджер; - Маркетолог; На данном канале можно найти кучу полезной информации по первым трем темам. 4-6 темы узкоспециализированные, там нужно изначально понимать требования под вакансии и изучать материал прицельно. Последние две темы для людей, которые не хотят изучать разработку, но планируют перейти в web3. Варианты всегда есть. Далее ответы на вопросы будут касаться первых трех тем, так как у меня есть практический опыт только в них. 2. Сколько платят разработчику? Средняя з/п около 3к-4к долларов в месяц. Более опытные программисты могут получать и 8-10, а сеньоры и того больше. 3. Сложно ли найти работу? Довольно сложно. В большинстве вакансий требуются разработчики с опытом работы от 2-3 лет, имеющие портфолио. Для начинающего в web3, который только закончил обучение или прошел курсы потребуется некоторое время, чтобы найти подходящую должность. Более того, практически все вакансии приходятся на зарубежные компании. В русскоговорящих странах ощущается явный провал в этом. 4. Что нужно для поиска работы? В идеале - портфолио на GitHub. Это могут быть как мелкие одностраничные проекты в web3, так и более крупные - своя игра, приложение обменник, dao и т.д. Главное показать, что вы можете писать сложные смарт контракты. Также будут огромным плюсом ваши статьи или посты по теме разработки. Страничка на LinkedIn, активный профиль в Твиттере или ваш персональный сайт тоже будут кстати. Далее поговорим о навыках. #start #web3 #newby

Читаем отчеты вместе. 3 На сегодня у нас отчет с code4reana, которые делали аудит для Olympus DAO. Он слегка сложноват, но можно читать и пытаться понять общий смысл того, что хотели донести аудиторы. Были найдены 3 крупные уязвимости, 32 средних, а также некоторое количество мелких. Что мне нравится в отчетах code3rena, что там всегда есть упоминания по экономии газа и те мелкие ошибки, на которые в других конкурсах не обращают внимания. А ведь за них тоже платят! Читаем новый аудит и делаем заметки! #report #audit

Про внешние контракты в 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 Хороший разработчик, как и хороший аудитор, на папку тестов уделят столько же времени, сколько и на сам проект. Хотя бы для того, чтобы понять, какие тесты проводились и что в голове у других разработчиков. Итак, для каждого контракта в проекте чаще всего создается свой файл теста. Нельзя нагружать все в одно место, так будет проблематичнее потом. Если есть какие либо библиотеки или сторонние файлы, которые требуют тестов, то также создаем отдельную папку для них (например, utils) и проверяем. Далее идут файлы хелперы. Так сложно объяснить, что это такое, но в общем, это такие sol файлы в которых прописаны некоторые функции, с помощью которых будет легче проводить сами тесты. Чаще всего они так и называются Helpers.sol или с добавление имени контракта в начале. Тут прописываются переменные, импорты, структуры и функции. При встрече с ними, крайне рекомендую начинать изучение именно с них. Сложнее всего иногда бывает определить контракт входа, т.е. с какого контракта начинается взаимодействие с остальными. И от какого лица. Ведь некоторые контракты могут разворачивать только другие контракты (фабрики), или частные лица, или только Сейф и т.д. При написание своих тестов, мы определяем изначальные условия: контракт входа, его настройки (нужно ли сминтить токены и забросить туда), его пользователей и т.д. В этом очень сильно помогают как раз те хелперы. И только потом начинаем писать свои тесты. Если вы хотите действительно научиться писать тесты, то возьмите конкурсный проект и просто сначала изучайте, а потом пробуйте писать свои. Очень жаль, что нет полноценного курса по проведению тестов. #tests

Тесты в обучении и аудите. Часть 1 Сегодня хочу поднять тему проведения тестов. В частности на Foundry, но подойдет и для HardHat. В сети можно встретить достаточно большое количество уроков по темам проведения тестов. Даже ролики на Ютуб на русском языке есть, и по ним действительно можно научиться основам. Точнее установке пакетов, созданию файла и написанию простых тестов. Немного попрактиковавшись, вы вполне себе сможете написать тест на функцию в своем контракте. Однако сложности начинаются, когда вы берете проект, где уже были проведены тесты и вам нужно либо дополнить их, либо написать свои, например, когда при аудите вы нашли потенциальную проблему и хотите проверить ее. Что можно найти в серьезных проектах? Во-первых, в папке с тестами чаще всего лежит не один файл, а несколько. Во-вторых, там же еще присутствуют и другие папки. В-третьих, появляются некие контракты хелперы. И вот после простеньких тестов, с которыми мы игрались на своем проекте, в первый раз такое собрание файлов вызывает некоторую панику. #tests

Читаем отчеты вместе. 2 Фух, весь день провел в тестах и постижению новых принципов работы с Foundry. Потрясающая система, особенно, когда научишься с ней обращаться. Вообще, тесты, которые учат писать в роликах на Ютуб, и тесты, которые требуются проводить аудитору - два абсолютно разных по сложности принципа. Завтра сделаю отдельный пост про это. А пока, вечерний отчет для чтения вместе! #report #audit

Прочитать mapping в Foundry Просто оставлю тут небольшую заметку про работу с памятью. Я еще только учусь вместе с вами, и сегодня столкнулся с проблемой прочтения значений из памяти контракта. Допустим есть такой маппинг: mapping (uint256 => structInt) internal BlaBlaSt; Я перерыл весь foundry и гугл, но так и не понял есть ли какие-нибудь команды, чтобы прочитать значения по нужному id. В общем, если однажды столкнётесь с такой же проблемой, то проще всего будет написать функцию для вывода значений, а уже после использовать ее в своих тестах. Получили значения из функции => сохранили в переменные => вывели в консоль. Мне сегодня это стоило пары часов. Если знаете более простой способ или команду, буду рад, если поделитесь в комментариях. #foundry #mapping

Внимание на decimals в аудитах Короткий пост для привлечения внимания разработчиков и аудиторов к проблеме decimals в Solidity и расчетах. Очень и очень часто встречаются ошибки, в которых разработчики учитывали только 18 (WETH) или 6 (USDT) decimals в токенах. При этом их количество в разных токенах варьируется от 1 до 20 (максимальный, который я встречал), но, вполне вероятно, что может быть и больше. Поэтому, если вы не ограничиваете работу своего смарт контракта whitelist токенами с конкретным значением decimals, то следует учитывать и другие варианты. Вот один из примеров такого бага в контракте. #decimals #audit

Новый скам в NFT Около недели назад наткнулся на пост, где рассказывалось о новом скаме с NFT. Более подробно о нем можно прочитать тут, а я расскажу в двух словах. В общем, пользователи Open Sea, да и других бирж, стали замечать, что либо с их аккаунта, либо на их аккаунт идет перевод NFT. Порой даже предлагается подписать транзакцию в кошельке. Делать этого, конечно не стоит. Дело в том, что практически все переводы NFT порождают событие transfer, которое и отлавливается биржами и другими сервисами. Однако, в случае скама, никакой транзакции не происходит. Злоумышленник просто в своем контракте override функцию transferFrom / safeTransferFrom, оставляя только emit event. Для того чтобы не попасть в такую ловушку, нужно просмотреть транзакции (а был ли перевод вообще!), а также заглянуть в контракт, который и порождает это уведомление. Будьте аккуратны, и не подписывайте подозрительные сообщения в кошельках. #nft #scam

Читаем отчеты вместе. 1 Я тут подумал, а давайте читать аудиторские отчеты вместе всем каналом? За месяц у нас получится около 25 прочитанных отчетов (не считая выходные дни), что точно повысит наши знания. Выкладывать буду по вечерам. В комментариях будем делиться, что кому понравилось, кто в чем не разобрался, объяснять друг другу моменты и т.д. Для сегодняшнего вечера я выбрал отчет от Sherlock. Кто что думает? #report #audit

Хэширование в EIP712 Все чаще встречаюсь с этим стандартом на просторах аудиторских отчетов, и стараюсь осмысливать его шаг за шагом. Вообще EIP712 был создан для того, чтобы можно было подписывать сообщения, которые состоят не только из строк, но и более сложных параметров: например, struct. И сегодня разберем, как шифруются структуры. Возьмем такой код: struct Parent {     uint s;     Child[] children; } Child {    uint a;    uint b; } Сначала будет хешироваться каждый пункт в Child по отдельности, затем они соединяются (конкатенация) и еще раз хешируются. Из этого получается хеш структуры. В самом конце, берется S и хеш структуры и высчитывается уже конечный хеш Parent. #erc712 #struct

Нет, не задача Disclaimer. Сегодня я сменил название канала, так как мы уже давно вышли за рамки начального обучения, и матер
Нет, не задача Disclaimer. Сегодня я сменил название канала, так как мы уже давно вышли за рамки начального обучения, и материал теперь уже для более продвинутых пользователей. Сегодня хочу обратить ваше внимание на стандарт ERC4626. По нему ранее была задача у Immunefi, с которой мне пришлось повозиться, чтобы понять в чем там дело. ERC4626, объясняю своими словами, используется тогда, когда вам нужно выдать пользователям вашего проекта некоторое количество shares взамен их токенов, которые они внесли. Он используется и в играх, и в Dao, и на биржах. При аудитах он встречается довольно часто.  В контрактах, которые используют данный стандарт, нужно обращать внимание на формулу расчета количество shares. Чаще всего разработчики упускают из вида проблему минта shares для первого пользователя, а он может оказаться хакером. Хоть я сам и понял суть бага, но объяснить его немного затрудняюсь, поэтому предлагаю вам посмотреть часть видео, где он хорошо разбирается. Видео разбор. #erc4626

И последняя на сегодня Последняя задача была помечена как Critical. Достаточно серьезная проблема многих контактов, которые и
И последняя на сегодня Последняя задача была помечена как Critical. Достаточно серьезная проблема многих контактов, которые используют переводы. Решение Заметили маппинги в начале? Как вы думаете, зачем они были указаны? Да, их значения не обновляются при переводе. А значит, что пользователь может делать перевод несколько раз по одному id и опустошить контракт. Будьте внимательны в своих контрактах! #task

Задача на знание нюансов Задача была помечена как Medium Risk. Ошибка не столько в самом коде, сколько в логике и знании, как
Задача на знание нюансов Задача была помечена как Medium Risk. Ошибка не столько в самом коде, сколько в логике и знании, как работает язык. Поняли, о чем идет речь? Решение Проблема все в том же extcodesize. Нельзя полагаться на него при проверке "Контракт ли это?". В первом случае, хакер может все сделать через конструктор контакта, а в более сложном - поиграться с create2 и selfdestruct(). Т.е. проверку довольно просто обойти. #task

Простая, но серьезная Данная задача одна из самых легких среди тех, что я видел. Тем не менее, она была помечена как High Ris
Простая, но серьезная Данная задача одна из самых легких среди тех, что я видел. Тем не менее, она была помечена как High Risk. Решили? Решение Функция заканчивает свое действие на return и не доходит до проверки require. К чему это может привести, вы и сами знаете. #task

Еще одна с code4rena Данный баг был обозначен как Medium risk. Поняли в чем дело? Решение Функция lendToProject может стать н
Еще одна с code4rena Данный баг был обозначен как Medium risk. Поняли в чем дело? Решение Функция lendToProject может стать не доступной, если количество задач (tasks) будет слишком большим, что приведет к стопорению проекта. Это происходит из-за того, что цикл расходует весь газ из функции. Такая вот DoS атака. #task

Более сложная задача от Immunefi При аудите всегда следует обращать внимание на переменные и "откуда растут ноги" у токена. П
Более сложная задача от Immunefi При аудите всегда следует обращать внимание на переменные и "откуда растут ноги" у токена. Получилось решить? Решение Хоть первая функция и оторвана от контекста, смысл бага все же можно уловить: недостаточная проверка токенов. Другими словами хакер может использовать фейковый токен, чтобы получить реальные токены.  #task #token

День задач на канале Сегодня я подготавливаю отчет для своего конкурсного аудита, поэтому на канале объявляется день задач. И
День задач на канале Сегодня я подготавливаю отчет для своего конкурсного аудита, поэтому на канале объявляется день задач. Итак, первая: была помечена как High Risk на code4rena. Сможете понять в чем тут дело? Решение В этой задаче стоит обратить внимание не только на саму подпись (мы же помним, что с ними существует достаточное количество проблем?), но и на nonce. Вроде бы, все правильно написано в коде. Но нет одной единственной проверки. Уже догадались? Разработчики не проверяют return с call вызова. Это значит, что в случае неудачного вызова, nonce останется прежним, и хакер может использовать подпись с еще действующим nonce в своих целях. Вот описание с code4rena. #task #nonce

+1
Файл-хелпер для работы с Foundry В недавнем аудите я снова столкнулся с некоторыми тестами в Foundry, которые тормозили весь процесс. Сегодня я решил создать для себя небольшой файл подсказку для проведения тестов. Думаю он может быть полезен всем, кто только начинает свою практику. Вы можете скачать его и в любой момент добавлять свои тесты или наработки. Также прикрепляю файл с базовыми контрактами. Обращаю внимание, что это простые тесты с комментариями, для общего понимания принципов работы Foundry. Позже добавлю туда практику с прокси контрактами, а также наработки с эксплойтами. Всем хороших выходных! #foundry

Задачка на день Ну, и небольшая задачка на день. Сможете найти, в чем тут проблема? Решение В аудитах следует всегда обращать
Задачка на день Ну, и небольшая задачка на день. Сможете найти, в чем тут проблема? Решение В аудитах следует всегда обращать внимание на модификаторы функций, какие условия они нам ставят. В текущем же примере, он просто сверяет msg.sender с другим параметров, а значит, что функция _safeMint() не защищена от reentrancy атак. #security #task