На следующей неделе у меня в планах рассмотреть invariant тесты и работу с подписями стандарта EIP-712. Вообще, давайте пройдемся по ближайшим планам с темой Foundry.
На данный момент вышло уже 25 постов, где я постарался объяснить базовые нюансы написания тестов. Осталось несколько более сложных тем:
1. Тесты с использованием контрактов Uniswap и Chainlink;
2. Дебаггинг;
3. Работа с L2, ZKsynk и ZeroLayer;
4. Тестирование мостов;
Информации по этим темам не так много, поэтому времени уйдет на подготовку постов чуть больше. Возможно, дальше они будут выходить не каждый день.
Также хотелось бы разобрать несколько примеров из серии Damn Vulnerable DeFi, Immunefi reports и реальные тесты протоколов из конкурсных аудитов.
В целом, работы нам где-то еще на месяц. Зато после этого мы качественно поднимем свои навыки работы с Foundry и написанием тестов!
А сегодня хочу рассказать вам о некоторых командах Foundry, о которых редко упоминают в обучающих видео.
1. Команда forge fmt
Простая и удобная команда, которая позволяет быстро отформатировать ваш код. Нет, она не исправит ваши ошибки в коде, но сможет убрать не нужные отступы и пробелы, сделает код визуально адекватным.
2. Команда forge doc
Она создает документацию по функциям и контрактам вашего протокола и сохраняет все в отдельные md файлы.
Кстати, для тех, кто не знал, есть прекрасный плаггин Markdown All in One (от Yu Zhang), который может отобразить md файлы в вашем редакторе в удобном читаемом виде.
3. Команда forge config
Она выводит все доступные опции для настройки конфигурационного файла foundry.toml. Можно копировать прямо с терминала, помещать в файл и корректировать необходимые настройки.
4. Кодирование структур
Структуры в Solidity кодируются в виде кортежей данных (tuple), подробнее об этом можно прочитать тут:
https://docs.soliditylang.org/en/latest/abi-spec.html#mapping-solidity-to-abi-types
В тестах Foundry также нужно иметь ввиду, как это все работает "под капотом". Например, возьмем простой тест:
contract Test {
struct MyStruct {
address addr;
uint256 amount;
}
function f(MyStruct memory t) public pure {}
}Вот как эта функция, принимающая структуру, будет выглядеть в раскладке:
{
"inputs": [
{
"components": [
{
"internalType": "address",
"name": "addr",
"type": "address"
},
{
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"internalType": "struct Test.MyStruct",
"name": "t",
"type": "tuple"
}
],
"name": "f",
"outputs": [],
"stateMutability": "pure",
"type": "function"
}т.е. функция f принимает один аргумент из двух компонентов типа адрес и uint256.
4. Вывод отрицательных чисел в тестах
Через команду console.log мы можем выводить какую-либо информацию прямо из наших тестов в терминал. Однако с отрицательными числами так не выйдет.
В этом случае необходимо использовать - console.logInt().
5. Использование стандартных ошибок Foundry
В библиотеке StdErrors, которая по умолчанию наследуется в Test, основную библиотеку для проведения тестов, есть свой набор ошибок. Вы можете использовать их для своих тестов, например:
vm.expectRevert(stdError.arithmeticError);
Полный список ошибок можно посмотреть тут:
https://book.getfoundry.sh/reference/forge-std/std-errors
Надеюсь, сегодня вы также узнали чуточку больше о Foundry.
Приятного обучения и легких выходных!
#foundry #lesson25