

Echidna — странное существо, которое ест баги и обладает высокой электровосприимчивостью (с извинениями перед Джейкобом Стэнли)
Если серьёзно, Echidna — это программа на Haskell, предназначенная для фаззинга/тестирования на основе свойств смарт-контрактов Ethereum. Она использует сложные кампании фаззинга на основе грамматики, основанные на ABI контракта, для опровержения пользовательских предикатов или утверждений Solidity. Мы разработали Echidna с учётом модульности, поэтому её можно легко расширять, добавляя новые мутации или тестируя определённые контракты в конкретных случаях.
.. и красивый высококачественный логотип ручной работы.
Основная функциональность Echidna — это исполняемый файл с именем echidna, который принимает на вход контракт и список инвариантов (свойств, которые всегда должны оставаться истинными). Для каждого инварианта он генерирует случайные последовательности вызовов контракта и проверяет, выполняется ли инвариант. Если ему удаётся найти способ опровергнуть инвариант, он выводит последовательность вызовов, которая это делает. Если нет, вы получаете некоторую уверенность в безопасности контракта.
Инварианты выражаются как функции Solidity с именами, начинающимися с echidna_, без аргументов и возвращающие логическое значение. Например, если у вас есть переменная balance, которая никогда не должна опускаться ниже 20, вы можете написать дополнительную функцию в вашем контракте, например такую:```solidity
function echidna_check_balance() public returns (bool) {
return(balance >= 20);
}
Чтобы проверить эти инварианты, выполните:```sh
$ echidna myContract.sol
Пример контракта с тестами можно найти в tests/solidity/basic/flags.sol. Чтобы запустить его, выполните:```sh $ echidna tests/solidity/basic/flags.sol
Echidna должна найти последовательность вызовов, которая опровергает `echidna_sometimesfalse`, и не должна находить опровергающее значение для `echidna_alwaystrue`.
### Режимы тестирования
В приведённом выше примере используется режим **property** по умолчанию, но Echidna поддерживает несколько режимов тестирования, настраиваемых через `testMode` в файле конфигурации или `--test-mode` в командной строке:
* **`property`** (по умолчанию): Тестирование функций с префиксом `echidna_`, возвращающих `bool`.
* **`assertion`**: Обнаружение ошибок утверждений из `assert()` и хелперов Foundry `assertX` (`assertTrue`, `assertEq` и т.д.).
* **`foundry`**: Запуск юнит-тестов с префиксом `test` и инвариантов с префиксом `invariant_` в стиле Foundry.
* **`overflow`**: Обнаружение целочисленных переполнений/потерь (Solidity >= 0.8.0).
* **`optimization`**: Максимизация возвращаемого значения функций с префиксом `echidna_`, возвращающих `int256` (использует тот же настраиваемый префикс, что и режим property).
* **`exploration`**: Сбор покрытия без проверки свойств.
### Сбор и визуализация покрытия
После завершения кампании Echidna может сохранить максимизирующий покрытие **корпус** в специальной директории, указанной в опции конфигурации `corpusDir`. Эта директория будет содержать две записи: (1) директорию с именем `coverage` с JSON-файлами, которые можно воспроизвести в Echidna, и (2) текстовый файл с именем `covered.txt` — копию исходного кода с аннотациями покрытия.
Если запустить пример `tests/solidity/basic/flags.sol`, Echidna сохранит несколько файлов сериализованных транзакций в директории `coverage` и файл `covered.$(date +%s).txt` со следующими строками:```text
*r | function set0(int val) public returns (bool){
* | if (val % 100 == 0)
* | flag0 = false;
}
*r | function set1(int val) public returns (bool){
* | if (val % 10 == 0 && !flag0)
* | flag1 = false;
}
Наш инструмент помечает каждую трассу выполнения в корпусе следующим «маркером строки»:
*, если выполнение завершилось STOPr, если выполнение завершилось REVERTo, если выполнение завершилось ошибкой out-of-gase, если выполнение завершилось любой другой ошибкой (деление на ноль, ошибка утверждения и т. д.)Echidna может тестировать контракты, скомпилированные с помощью различных систем сборки смарт-контрактов, включая Foundry, Hardhat и Truffle, используя crytic-compile. Чтобы запустить Echidna с текущим фреймворком компиляции, используйте echidna ..
Кроме того, Echidna поддерживает два режима тестирования сложных контрактов. Во-первых, можно воспользоваться существующим состоянием сети и использовать его в качестве базового состояния для Echidna. Во-вторых, Echidna может вызывать любой контракт с известным ABI, передав соответствующий исходный код Solidity в CLI. Для включения этой функции используйте allContracts: true в вашей конфигурации.
Наш репозиторий Building Secure Smart Contracts содержит краткий курс по Echidna, включая примеры, уроки и упражнения.
Существует действие Echidna, которое можно использовать для запуска echidna в рамках рабочего процесса GitHub Actions. Обратитесь к репозиторию crytic/echidna-action за инструкциями по использованию и примерами.
CLI Echidna позволяет выбрать контракт для тестирования и загрузить файл конфигурации.```sh $ echidna contract.sol --contract TEST --config config.yaml
Конфигурационный файл позволяет пользователям выбирать параметры EVM и генерации тестов. Пример полного аннотированного конфигурационного файла с настройками по умолчанию можно найти по адресу [tests/solidity/basic/default.yaml](https://github.com/crytic/echidna/blob/HEAD/tests/solidity/basic/default.yaml). Более подробную информацию о доступных параметрах конфигурации см. в [документации](https://secure-contracts.com/program-analysis/echidna/configuration.html).
Echidna поддерживает три различных драйвера вывода. Это драйвер `text` по умолчанию, драйвер `json` и драйвер `none`, который должен подавлять весь вывод `stdout`. Драйвер JSON сообщает об общей кампании следующим образом.```
Campaign = {
"success" : bool,
"error" : string?,
"tests" : [Test],
"seed" : number,
"coverage" : Coverage
}
Test = {
"contract" : string,
"name" : string,
"status" : string,
"error" : string?,
"testType" : string,
"transactions" : [Transaction]?
}
Transaction = {
"contract" : string,
"function" : string,
"arguments" : [string]?,
"gas" : number,
"gasprice" : number
}
Coverage — это словарь, описывающий определенные вызовы, увеличивающие покрытие. В будущем эти интерфейсы могут быть изменены, чтобы стать немного более удобными для пользователя. testType может быть одним из property, assertion, optimization, exploration или call, а status всегда принимает значение fuzzing, shrinking, solved, passed или error.
Один из способов диагностировать проблемы с производительностью Echidna — запустить echidna с профилированием. Чтобы запустить Echidna с базовым профилированием, добавьте +RTS -p -s в вашу исходную команду echidna:```sh
$ nix develop # alternatively nix-shell
$ cabal --enable-profiling run echidna -- ... +RTS -p -s
$ less echidna.prof
Это создаёт файл отчёта (`echidna.prof`), который показывает, какие функции потребляют больше всего ресурсов ЦП и памяти.
Если базового профилирования недостаточно, вы можете использовать более [продвинутые техники профилирования](https://haskell.foundation/hs-opt-handbook.github.io/src/Measurement_Observation/Haskell_Profiling/eventlog.html).
Распространённые причины проблем с производительностью, которые мы наблюдали:
- Дорогостоящие функции, вызываемые на горячих путях
- Ленивые конструкторы данных, накапливающие тунки
- Неэффективные структуры данных, используемые на горячих путях
Проверка этих аспектов — хорошая отправная точка. Если вы подозреваете, что некоторое вычисление слишком лениво и
утекает память, вы можете использовать `force` из `Control.DeepSeq`, чтобы убедиться, что оно вычисляется.
## Ограничения и известные проблемы
Эмуляция EVM и тестирование — сложная задача. Echidna имеет некоторые ограничения в последнем релизе. Некоторые из
них унаследованы от [hevm](https://github.com/argotorg/hevm), в то время как другие являются результатом
решений по проектированию/производительности или просто ошибок в нашем коде. Мы перечисляем их здесь, включая их
соответствующий issue и статус ("wont fix", "on hold", "in review", "fixed"). Проблемы, которые
помечены как "fixed", ожидается, что они будут включены в следующий релиз Echidna.
| Описание | Issue | Статус |
| :--- | :---: | :---: |
| Поддержка Vyper ограничена | [#652](https://github.com/crytic/echidna/issues/652) | *не будет исправлено* |
| Ограниченная поддержка библиотек для тестирования | [#651](https://github.com/crytic/echidna/issues/651) | *не будет исправлено* |
## Установка
### Предкомпилированные бинарные файлы
Перед началом убедитесь, что Slither [установлен](https://github.com/crytic/slither) (`pip3 install slither-analyzer --user`).
Если вы хотите быстро протестировать Echidna в Linux или MacOS, мы предоставляем статически слинкованные бинарные файлы для Linux, собранные на Ubuntu, и в основном статически слинкованные бинарные файлы для MacOS на нашей [странице релизов](https://github.com/crytic/echidna/releases). Вы также можете получить такие же бинарные файлы из нашего [CI конвейера](https://github.com/crytic/echidna/actions?query=workflow%3ACI+branch%3Amaster+event%3Apush), просто нажмите на коммит, чтобы найти бинарные файлы для Linux или MacOS.
### Homebrew (macOS / Linux)
Если у вас установлен Homebrew на вашем Mac или Linux-машине, вы можете установить Echidna и все его зависимости (Slither, crytic-compile) командой `brew install echidna`.
Вы также можете скомпилировать и установить последнюю версию кода из ветки `master` командой `brew install --HEAD echidna`
Вы можете получить дополнительную информацию на странице [`echidna` Homebrew Formula](https://formulae.brew.sh/formula/echidna). Сама формула поддерживается как часть [репозитория homebrew-core](https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/e/echidna.rb)
### Docker-контейнер
Если вы предпочитаете использовать предварительно собранный Docker-контейнер, ознакомьтесь с нашим [docker
пакетом](https://github.com/orgs/crytic/packages?repo_name=echidna), который
автоматически собирается с помощью GitHub Actions. Контейнер `echidna` основан на
`ubuntu:noble` и предназначен для создания небольшого, но достаточно гибкого образа для использования
Echidna. Он предоставляет предварительно собранную версию `echidna`, а также
`slither`, `crytic-compile`, `solc-select`, `nvm` и `foundry` (включая
`forge`, `cast`, `anvil` и `chisel`) объёмом менее 200 МБ.
Обратите внимание, что образы контейнеров в настоящее время собираются только для систем x86. Запуск их
на устройствах ARM, таких как Mac M1, не рекомендуется из-за потери производительности,
вызванной эмуляцией ЦП.
Для образа Docker-контейнера доступны различные теги:
| Тег | Сборка по тегу
|---------------|-------------
| `vx.y.z` | Сборка, соответствующая релизу `vx.y.z`
| `latest` | Последний помеченный релиз Echidna.
| `edge` | Самый последний коммит в ветке по умолчанию.
| `testing-foo` | Тестовая сборка на основе ветки `foo`.
Чтобы запустить контейнер с последней версией Echidna в интерактивном режиме, вы можете использовать
что-то вроде следующей команды. Она смонтирует текущую директорию как
`/src` внутри контейнера и даст вам командную оболочку, где вы сможете использовать
`echidna`:```sh
$ docker run --rm -it -v "$(pwd)":/src ghcr.io/crytic/echidna/echidna
В противном случае, если вы хотите локально собрать последнюю версию Echidna, мы рекомендуем использовать Docker. Из клона этого репозитория выполните следующую команду для сборки образа контейнера Docker:```sh $ docker build -t echidna -f docker/Dockerfile --target final-ubuntu .
Затем вы можете запустить образ `echidna` локально. Например, чтобы установить solc 0.5.7 и проверить `tests/solidity/basic/flags.sol`, выполните:```sh
$ docker run -it -v "$(pwd)":/src echidna bash -c "solc-select install 0.5.7 && solc-select use 0.5.7 && echidna /src/tests/solidity/basic/flags.sol"
Образ Docker также включает инструменты Foundry для всесторонней разработки и тестирования смарт-контрактов. Вы можете использовать forge, cast, anvil и chisel непосредственно в контейнере:```sh
$ docker run -it -v "$(pwd)":/src echidna bash
$ forge --version $ cast --version $ anvil --version $ chisel --version
$ forge init my-project $ cd my-project $ forge build $ forge test
### Сборка с помощью Stack
Если вы предпочитаете собирать из исходников, используйте [Stack](https://docs.haskellstack.org/en/stable/). `stack install` должен собрать и скомпилировать `echidna` в `~/.local/bin`. Вам потребуется слинковать с libreadline и libsecp256k1 (собранными с поддержкой восстановления), которые следует установить с помощью выбранного вами менеджера пакетов. Также нужно установить последний релиз [libff](https://github.com/scipr-lab/libff). Обратитесь к нашим [CI-тестам](https://github.com/crytic/echidna/blob/HEAD/.github/scripts/install-libff.sh) для получения инструкций.
Некоторые дистрибутивы Linux не поставляют статические библиотеки для некоторых вещей, необходимых Haskell, например, Arch Linux, что приводит к ошибкам линковки при выполнении `stack build`, так как мы используем флаг `-static`. В этом случае используйте `--flag echidna:-static` для создания динамически слинкованного бинарника.
Если возникают ошибки сборки, связанные с линковкой, попробуйте поиграть с параметрами `--extra-include-dirs` и `--extra-lib-dirs`.
### Сборка с помощью Nix (работает нативно на системах Apple M1)
[Пользователи Nix](https://nixos.org/download/) могут установить последнюю версию Echidna с помощью:
```bash
nix profile install github:crytic/echidna
``````sh
$ nix-env -i -f https://github.com/crytic/echidna/tarball/master
С включенными flakes вы можете запустить Echidna прямо из этого репозитория:```sh $ nix run github:crytic/echidna # master $ nix run github:crytic/echidna/v2.1.1 # specific ref (tag/branch/commit)
Для создания автономного релиза для систем macOS без Nix, следующая команда соберет Echidna в основном в статический бинарник. Это также можно использовать на системах Linux для получения полностью статического бинарника.```sh
$ nix build .#echidna-redistributable
Nix автоматически установит все зависимости, необходимые для разработки, включая crytic-compile и solc. Быстрый способ начать разработку с Echidna:```sh
$ git clone https://github.com/crytic/echidna
$ cd echidna
$ nix develop # alternatively nix-shell
[nix-shell]$ cabal run echidna
[nix-shell]$ cabal run tests
[nix-shell]$ cabal new-repl
## Публичное использование Echidna
### Наборы для тестирования свойств
Это частичный список проектов смарт-контрактов, использующих Echidna для тестирования:
* [Curvance](https://github.com/curvance/Curvance-CantinaCompetition/tree/CodeFAQAndAdjustments/tests/fuzzing)
* [Primitive](https://github.com/primitivefinance/rmm-core/tree/main/contracts/crytic)
* [Uniswap-v3](https://github.com/search?q=org%3AUniswap+echidna&type=commits)
* [Balancer](https://github.com/balancer/balancer-core/tree/master/echidna)
* [MakerDAO vest](https://github.com/makerdao/dss-vest/pull/16)
* [Optimism DAI Bridge](https://github.com/makerdao/optimism-dai-bridge/blob/master/contracts/test/DaiEchidnaTest.sol)
* [WETH10](https://github.com/WETH10/WETH10/tree/main/contracts/fuzzing)
* [Yield](https://github.com/yieldprotocol/fyDai/pull/312)
* [Convexity Protocol](https://github.com/opynfinance/ConvexityProtocol/tree/dev/contracts/echidna)
* [Aragon Staking](https://github.com/aragon/staking/blob/82bf54a3e11ec4e50d470d66048a2dd3154f940b/packages/protocol/contracts/test/lib/EchidnaStaking.sol)
* [Centre Token](https://github.com/circlefin/stablecoin-evm/tree/release-2024-03-15T223309/echidna_tests)
* [Tokencard](https://github.com/tokencard/contracts/tree/master/tools/echidna)
* [Minimalist USD Stablecoin](https://github.com/usmfum/USM/pull/41)
### Обзоры безопасности
Ниже приведены публичные обзоры безопасности, в которых использовалась Echidna для выявления уязвимостей.
- [Advanced Blockchain](https://github.com/trailofbits/publications/blob/master/reviews/AdvancedBlockchain.pdf)
- [Amp](https://github.com/trailofbits/publications/blob/master/reviews/amp.pdf)
- [Ampleforth](https://github.com/trailofbits/publications/blob/master/reviews/ampleforth.pdf)
- [Atlendis](https://github.com/trailofbits/publications/blob/master/reviews/2023-03-atlendis-atlendissmartcontracts-securityreview.pdf)
- [Balancer](https://github.com/trailofbits/publications/blob/master/reviews/2021-04-balancer-balancerv2-securityreview.pdf)
- [Basis](https://github.com/trailofbits/publications/blob/master/reviews/basis.pdf)
- [Dai](https://github.com/trailofbits/publications/blob/master/reviews/mc-dai.pdf)
- [Frax](https://github.com/trailofbits/publications/blob/master/reviews/FraxQ22022.pdf)
- [Liquity](https://github.com/trailofbits/publications/blob/master/reviews/LiquityProtocolandStabilityPoolFinalReport.pdf)
- [LooksRare](https://github.com/trailofbits/publications/blob/master/reviews/LooksRare.pdf)
- [Maple](https://github.com/trailofbits/publications/blob/master/reviews/2022-03-maplefinance-securityreview.pdf)
- [Optimism](https://github.com/trailofbits/publications/blob/master/reviews/2022-11-optimism-securityreview.pdf)
- [Opyn](https://github.com/trailofbits/publications/blob/master/reviews/Opyn.pdf)
- [Origin Dollar](https://github.com/trailofbits/publications/blob/master/reviews/OriginDollar.pdf)
- [Origin](https://github.com/trailofbits/publications/blob/master/reviews/origin.pdf)
- [Paxos](https://github.com/trailofbits/publications/blob/master/reviews/paxos.pdf)
- [Primitive](https://github.com/trailofbits/publications/blob/master/reviews/Primitive.pdf)
- [RocketPool](https://github.com/trailofbits/publications/blob/master/reviews/RocketPool.pdf)
- [Seaport](https://github.com/trailofbits/publications/blob/master/reviews/SeaportProtocol.pdf)
- [Set Protocol](https://github.com/trailofbits/publications/blob/master/reviews/setprotocol.pdf)
- [Shell protocol](https://github.com/trailofbits/publications/blob/master/reviews/ShellProtocolv2.pdf)
- [Sherlock](https://github.com/trailofbits/publications/blob/master/reviews/Sherlockv2.pdf)
- [Pegasys Pantheon](https://github.com/trailofbits/publications/blob/master/reviews/pantheon.pdf)
- [TokenCard](https://github.com/trailofbits/publications/blob/master/reviews/TokenCard.pdf)
- [Uniswap](https://github.com/trailofbits/publications/blob/master/reviews/UniswapV3Core.pdf)
- [Yearn](https://github.com/trailofbits/publications/blob/master/reviews/YearnV2Vaults.pdf)
- [Yield](https://github.com/trailofbits/publications/blob/master/reviews/YieldProtocol.pdf)
- [88mph](https://github.com/trailofbits/publications/blob/master/reviews/88mph.pdf)
- [0x](https://github.com/trailofbits/publications/blob/master/reviews/0x-protocol.pdf)
### Трофеи
Следующие уязвимости безопасности были обнаружены с помощью Echidna. Если вы нашли уязвимость, используя наш инструмент, пожалуйста, отправьте PR с соответствующей информацией.
| Проект | Уязвимость | Дата |
|--|--|--|
[0x Protocol](https://github.com/trailofbits/publications/blob/master/reviews/0x-protocol.pdf) | Если заказ не может быть выполнен, то его нельзя отменить | Октябрь 2019
[0x Protocol](https://github.com/trailofbits/publications/blob/master/reviews/0x-protocol.pdf) | Если заказ может быть частично выполнен с нулём, то его можно частично выполнить с одним токеном | Октябрь 2019
[0x Protocol](https://github.com/trailofbits/publications/blob/master/reviews/0x-protocol.pdf) | Функция cobbdouglas не возвращает ошибку при использовании корректных входных параметров | Октябрь 2019
[Balancer Core](https://github.com/trailofbits/publications/blob/master/reviews/BalancerCore.pdf) | Злоумышленник не может украсть активы из публичного пула | Январь 2020
[Balancer Core](https://github.com/trailofbits/publications/blob/master/reviews/BalancerCore.pdf) | Злоумышленник не может создать бесплатные токены пула с помощью joinPool | Январь 2020
[Balancer Core](https://github.com/trailofbits/publications/blob/master/reviews/BalancerCore.pdf) | Вызов joinPool-exitPool не приводит к получению бесплатных токенов пула | Январь 2020
[Balancer Core](https://github.com/trailofbits/publications/blob/master/reviews/BalancerCore.pdf) | Вызов exitswapExternAmountOut не приводит к получению бесплатных активов | Январь 2020
[Liquity Dollar](https://github.com/trailofbits/publications/blob/master/reviews/Liquity.pdf) | [Для закрытия trove требуется полное количество выпущенных LUSD](https://github.com/liquity/dev/blob/echidna_ToB_final/packages/contracts/contracts/TestContracts/E2E.sol#L242-L298) | Декабрь 2020
[Liquity Dollar](https://github.com/trailofbits/publications/blob/master/reviews/Liquity.pdf) | [Troves могут быть некорректно удалены](https://github.com/liquity/dev/blob/echidna_ToB_final/packages/contracts/contracts/TestContracts/E2E.sol#L242-L298) | Декабрь 2020
[Liquity Dollar](https://github.com/trailofbits/publications/blob/master/reviews/Liquity.pdf) | Изначальный выкуп может неожиданно откатиться | Декабрь 2020
[Liquity Dollar](https://github.com/trailofbits/publications/blob/master/reviews/Liquity.pdf) | Выкуп без погашений может всё равно вернуть успех | Декабрь 2020
[Origin Dollar](https://github.com/trailofbits/publications/blob/master/reviews/OriginDollar.pdf) | Пользователям разрешено передавать больше токенов, чем у них есть | Ноябрь 2020
[Origin Dollar](https://github.com/trailofbits/publications/blob/master/reviews/OriginDollar.pdf) | Балансы пользователей могут превышать общее предложение | Ноябрь 2020
[Yield Protocol](https://github.com/trailofbits/publications/blob/master/reviews/YieldProtocol.pdf) | Арифметические вычисления для покупки и продажи токенов неточны | Август 2020
### Исследования
Мы также можем использовать Echidna для воспроизведения исследовательских примеров из статей по фаззингу смарт-контрактов, чтобы показать, как быстро он может найти решение. Все эти примеры решаются за несколько секунд или одну-две минуты на ноутбуке.
| Источник | Код
|--|--
[Using automatic analysis tools with MakerDAO contracts](https://forum.openzeppelin.com/t/using-automatic-analysis-tools-with-makerdao-contracts/1021) | [SimpleDSChief](https://github.com/crytic/echidna/blob/master/tests/solidity/research/vera_dschief.sol)
[Integer precision bug in Sigma Prime](https://github.com/muellerberndt/sabre#example-2-integer-precision-bug) | [VerifyFunWithNumbers](https://github.com/crytic/echidna/blob/master/tests/solidity/research/solcfuzz_funwithnumbers.sol)
[Learning to Fuzz from Symbolic Execution with Application to Smart Contracts](https://files.sri.inf.ethz.ch/website/papers/ccs19-ilf.pdf) | [Crowdsale](https://github.com/crytic/echidna/blob/master/tests/solidity/research/ilf_crowdsale.sol)
[Harvey: A Greybox Fuzzer for Smart Contracts](https://arxiv.org/abs/1905.06944) | [Foo](https://github.com/crytic/echidna/blob/master/tests/solidity/research/harvey_foo.sol), [Baz](https://github.com/crytic/echidna/blob/master/tests/solidity/research/harvey_baz.sol)
### Академические публикации
| Название статьи | Место проведения | Дата публикации |
| --- | --- | --- |
| [echidna-parade: Diverse multicore smart contract fuzzing](https://agroce.github.io/issta21.pdf) | [ISSTA 2021](https://conf.researchr.org/home/issta-2021) | Июль 2021 |
| [Echidna: Effective, usable, and fast fuzzing for smart contracts](https://agroce.github.io/issta20.pdf) | [ISSTA 2020](https://conf.researchr.org/home/issta-2020) | Июль 2020 |
| [Echidna: A Practical Smart Contract Fuzzer](https://github.com/trailofbits/publications/blob/master/papers/echidna_fc_poster.pdf) | [FC 2020](https://fc20.ifca.ai/program.html) | Февраль 2020 |
Если вы используете Echidna в академических целях, рассмотрите возможность участия в [Crytic $10k Research Prize](https://blog.trailofbits.com/2019/11/13/announcing-the-crytic-10k-research-prize/).
## Получение помощи
Не стесняйтесь заходить в наш канал #ethereum slack в [Empire Hacking](https://slack.empirehacking.nyc/) для получения помощи по использованию или расширению Echidna.
* Начните с изучения этих простых [инвариантов Echidna](https://github.com/crytic/echidna/blob/HEAD/tests/solidity/basic/flags.sol)
* Для более детальных вопросов можно напрямую [написать](mailto:[email protected]) команде разработчиков Echidna.
## Лицензия
Echidna лицензирован и распространяется в соответствии с [лицензией AGPLv3](https://github.com/crytic/echidna/blob/master/LICENSE).