Skip to content
KitploitKITPLOIT
ИнструментыЭксплойтыБлог
Log in
Отправить
ИнструментыЭксплойтыБлог
Отправить

Инструменты для хакинга, пентеста и кибербезопасности — ваш арсенал защиты!

Kitploit — это каталог инструментов для хакинга, кибербезопасности и пентестинга. Находите последние обновления проектов для поиска уязвимостей, анализа систем, автоматизации тестирования и усиления вашей безопасности.

ЛентыКонтактыКонфиденциальность© 2026 Kitploit

Каталог инструментов

Категории

Все категории
Loading categories
echidna — Фаззер смарт-контрактов Ethereum | Kitploit
Инструменты/GitHubGitHub/crytic/echidna
Анализ уязвимостейФаззинг
GitHubcrytic/echidna

echidna

Фаззер смарт-контрактов Ethereum

РепозиторийСайт
3.2k4321322 дней назадПроверено Kitploit

Популярное

Смотреть все →

Откройте для себя самые используемые инструменты нашего сообщества.

Изучить все инструменты

Просмотрите нашу коллекцию инструментов

Смотреть все инструменты →
Поделиться
# Echidna: Быстрый фаззер для смарт-контрактов <a href="https://raw.githubusercontent.com/crytic/echidna/master/echidna.png"><img src="https://assets.kitploit.com/production/public/readmes/2659/763a0b6f546e53fe33e871cd7359ba47272d81be37527f1cceaa827256af0337.png" width="75"/></a>

![Build Status](https://github.com/crytic/echidna/workflows/CI/badge.svg)

Echidna — это странное существо, которое питается багами и обладает высокой электрочувствительностью (с извинениями перед Джейкобом Стэнли)

Если говорить серьёзно, Echidna — это программа на Haskell, предназначенная для фаззинга и тестирования на основе свойств смарт-контрактов Ethereum. Она использует сложные кампании грамматического фаззинга на основе [ABI контракта](https://docs.soliditylang.org/en/develop/abi-spec.html) для опровержения определяемых пользователем предикатов или [утверждений Solidity](https://docs.soliditylang.org/en/develop/control-structures.html#error-handling-assert-require-revert-and-exceptions). Мы разработали Echidna с учётом модульности, поэтому её легко расширять, добавляя новые мутации или тестируя конкретные контракты в особых случаях.

## Возможности

* Генерирует входные данные, адаптированные к вашему реальному коду
* Опциональный сбор корпуса, мутации и наведение по покрытию для поиска более глубоких багов
* Работает на основе [Slither](https://github.com/crytic/slither) для извлечения полезной информации перед кампанией фаззинга
* Интеграция с исходным кодом для определения того, какие строки покрыты после кампании фаззинга
* Интерактивный терминальный интерфейс, вывод в текстовом формате или JSON
* Автоматическая минимизация тестовых случаев для быстрой триажной сортировки
* Бесшовная интеграция в процесс разработки

.. и [прекрасный логотип ручной работы в высоком разрешении](https://raw.githubusercontent.com/crytic/echidna/master/echidna.png).

<a href="https://i.imgur.com/saFWti4.png"><img src="https://assets.kitploit.com/production/public/readmes/2659/ec117cf17d5b4eeb75f52a3654df19ba615818f232d5e9238093cf010431fedc.png" width="650"/></a>

## Использование

### Запуск средства выполнения тестов

Основная функциональность 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](https://github.com/crytic/echidna/blob/master/tests/solidity/basic/flags.sol). Чтобы запустить его, выполните:```sh
$ echidna tests/solidity/basic/flags.sol
```
Echidna должна найти последовательность вызовов, которая опровергает `echidna_sometimesfalse`, и не должна найти опровергающий вход для `echidna_alwaystrue`.

### Режимы тестирования

В приведённом выше примере используется режим **property** по умолчанию, но Echidna поддерживает несколько режимов тестирования, настраиваемых через `testMode` в файле конфигурации или `--test-mode` в CLI:

* **`property`** (по умолчанию): Тестирование функций с префиксом `echidna_`, возвращающих `bool`.
* **`assertion`**: Обнаружение сбоев утверждений из `assert()` и хелперов Foundry `assertX` (`assertTrue`, `assertEq` и т. д.).
* **`foundry`**: Запуск тестов в стиле Foundry, следуя его соглашениям об именовании: юнит- и фаззинг-тесты с префиксом `test` (те, что с префиксом `testFail`, должны ревертиться) и stateful-инварианты с префиксом `invariant` или `statefulFuzz`. Функции с префиксами `check` и `prove` являются символическими точками входа, но поскольку этот режим представляет собой кампанию фаззинга, они фаззятся как любая другая тестовая функция.
* **`verification`**: Символическая верификация каждой функции контракта с использованием одной транзакции. Функции с префиксами `check` и `prove` всегда используются как точки входа.
* **`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;
  }
```
Наш инструмент помечает каждый трейс выполнения в корпусе следующим "маркером строки":

* `*` если выполнение завершилось STOP
* `r` если выполнение завершилось REVERT
* `o` если выполнение завершилось ошибкой out-of-gas
* `e` если выполнение завершилось любой другой ошибкой (деление на ноль, ошибка утверждения и т.д.)

### Поддержка систем сборки смарт-контрактов

Echidna может тестировать контракты, скомпилированные с помощью различных систем сборки смарт-контрактов, включая [Foundry](https://book.getfoundry.sh/), [Hardhat](https://hardhat.org/) и [Truffle](https://archive.trufflesuite.com/), используя [crytic-compile](https://github.com/crytic/crytic-compile). Чтобы запустить Echidna с текущей платформой компиляции, используйте `echidna .`.

Кроме того, Echidna поддерживает два режима тестирования сложных контрактов. Во-первых, можно [воспользоваться существующим состоянием сети](https://secure-contracts.com/program-analysis/echidna/advanced/state-network-forking.html) и использовать его в качестве базового состояния для Echidna. Во-вторых, Echidna может вызывать любой контракт с известным ABI, передав соответствующий исходный код Solidity в CLI. Используйте `allContracts: true` в вашей конфигурации, чтобы включить это.

### Краткий курс по Echidna

Наш репозиторий [Building Secure Smart Contracts](https://github.com/crytic/building-secure-contracts/tree/master/program-analysis/echidna#echidna-tutorial) содержит краткий курс по Echidna, включая примеры, уроки и упражнения.

### Использование Echidna в рабочем процессе GitHub Actions

Существует действие Echidna, которое можно использовать для запуска `echidna` в рамках
рабочего процесса GitHub Actions. Пожалуйста, обратитесь к репозиторию
[crytic/echidna-action](https://github.com/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/master/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` — это dict, описывающий определённые вызовы, увеличивающие покрытие. Эти интерфейсы
впоследствии могут быть изменены, чтобы стать немного более удобными для пользователя. `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`), который показывает, какие функции потребляют больше всего CPU и памяти.

Если базовое профилирование не помогает, можно использовать более [продвинутые методы профилирования](https://haskell.foundation/hs-opt-handbook.github.io/src/Measurement_Observation/Haskell_Profiling/eventlog.html).

Распространённые причины проблем с производительностью, которые мы наблюдали:

- Дорогостоящие функции, вызываемые в горячих путях
- Ленивые конструкторы данных, накапливающие thunks
- Неэффективные структуры данных, используемые в горячих путях

Проверка этих пунктов — хорошее начало. Если вы подозреваете, что какое-то вычисление слишком лениво и
утекает память, можно использовать `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) | *wont fix* |
| Ограниченная поддержка библиотек для тестирования | [#651](https://github.com/crytic/echidna/issues/651) | *wont fix* |

## Установка

### Предкомпилированные бинарные файлы

Перед началом убедитесь, что Slither [установлен](https://github.com/crytic/slither) (`pip3 install slither-analyzer --user`).
Если вы хотите быстро протестировать Echidna в Linux или MacOS, мы предоставляем статически слинкованные бинарные файлы для Linux, собранные на Ubuntu, и в основном статические бинарные файлы для MacOS на нашей [странице релизов](https://github.com/crytic/echidna/releases). Вы также можете получить такие же бинарные файлы из нашего [CI pipeline](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 repository](https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/e/echidna.rb)

### Docker-контейнер

Если вы предпочитаете использовать готовый Docker-контейнер, ознакомьтесь с нашим [docker
package](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, не рекомендуется из-за потери производительности,
возникающей при эмуляции CPU.

Для образа 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
# Run an interactive shell with Foundry tools available
$ docker run -it -v "$(pwd)":/src echidna bash

# Inside the container, you can use Foundry commands:
$ forge --version
$ cast --version
$ anvil --version
$ chisel --version

# Example: Initialize a new Foundry project
$ 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 (собранной с включённым recovery), которые должны быть установлены менеджером пакетов на ваш выбор. Также необходимо установить последний релиз [libff](https://github.com/scipr-lab/libff). Обратитесь к нашим [CI-тестам](https://github.com/crytic/echidna/blob/master/.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 с помощью:```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
```
### Запуск наборов тестов

`cabal run tests` — это набор тестов на Haskell, который покрывает всё, что Echidna делает в
процессе.

Сервер MCP тестируется вне процесса: запускается реальная кампания и
управляется так, как это делал бы клиент-агент. Этот набор написан на Python и требует
`echidna` в `$PATH`:```sh
$ pip install -r tests/mcp/requirements-test.txt
$ pytest tests/mcp -v
```
Укажите на кампанию, которую вы запустили самостоятельно, с помощью `ECHIDNA_MCP_URL`, на другой порт с помощью `ECHIDNA_MCP_PORT` или на конкретный бинарный файл с помощью `ECHIDNA_BIN`. Пример агента, управляющего кампанией через тот же интерфейс, находится в [examples/](https://github.com/crytic/echidna/blob/master/examples/README.md).

## Публичное использование 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

---

[Read more](https://github.com/crytic/echidna)
Скачать инструмент