Настройка Foundry для разработки смарт-контрактов
Мы интегрируем Foundry в ваш пайплайн разработки смарт-контрактов. В отличие от Hardhat, Rust-based Foundry даёт выигрыш в скорости до 50× на тестах, но требует грамотной настройки профилей и зависимостей. Без этого вы рискуете получить нестабильные билды или пропустить реентерабельность на этапе тестирования.
Жизнь блокчейн-разработчика — это бесконечные итерации: скомпилировали, запустили тесты, нашли баг, исправили, снова запустили. Foundry делает этот цикл в десятки раз быстрее, но чтобы раскрыть его потенциал, нужно правильно настроить конфигурацию. Мы поможем вам сделать это под ключ. За 5 лет работы мы настроили Foundry для 50+ проектов — от простых ERC-20 до сложных DeFi-протоколов на L2.
Почему Foundry быстрее Hardhat?
Foundry написан на Rust и компилирует Solidity через solc напрямую, без лишних промежуточных слоёв. Тесты выполняются в нативной среде, fuzzing работает из коробки. Результат — скорость компиляции и тестов в 10–50 раз выше на типичных DeFi-проектах. Как отмечено в документации Foundry, benchmark на проекте с 200 тестами показывает 3 секунды против 45 секунд у Hardhat.
Установка и базовая конфигурация
Команда foundryup устанавливает последнюю версию toolchain. Проект инициализируется через forge init my-project. Базовая структура:
my-project/
├── foundry.toml
├── src/
├── test/
├── script/
└── lib/
Файл foundry.toml — сердце конфигурации. Мы настраиваем два профиля: быстрый для локальной разработки и более глубокий для CI.
| Параметр |
[profile.default] |
[profile.ci] |
| fuzz.runs |
1000 |
10000 |
| invariant.runs |
256 |
1000 |
| invariant.depth |
500 |
1000 |
Такой подход позволяет за минуты тестировать базовую логику локально и получать надёжные результаты на CI.
[profile.default]
src = "src"
out = "out"
libs = ["lib"]
solc = "0.8.24"
optimizer = true
optimizer_runs = 200
fuzz = { runs = 1000 }
invariant = { runs = 256, depth = 500 }
[profile.ci]
fuzz = { runs = 10000 }
invariant = { runs = 1000, depth = 1000 }
Как настроить профиль CI в Foundry?
Профиль CI требует более агрессивного fuzzing и depth для invariant тестов. Настройте его отдельно в foundry.toml и запускайте через forge test --profile ci -vvv. В CI-пайплайне мы также включаем --gas-report и дополнительные проверки Slither.
Зависимости через forge install
Подключаем OpenZeppelin, forge-std и другие библиотеки.
forge install OpenZeppelin/openzeppelin-contracts
forge install foundry-rs/forge-std
После установки добавляем remappings:
remappings = [
"@openzeppelin/=lib/openzeppelin-contracts/",
"forge-std/=lib/forge-std/src/",
]
Зависимости хранятся как git submodules — это стандарт для Foundry, обеспечивающий воспроизводимость.
Совет: как избежать конфликтов remappings
Если несколько библиотек экспортируют одинаковые пути, используйте приоритет в foundry.toml: remappings обрабатываются в порядке объявления. Всегда проверяйте компиляцию после установки новой зависимости.
Как настроить форк-тестирование с Anvil?
Anvil — локальная нода с возможностью форка mainnet. Это ключевая фича для интеграционных тестов.
anvil --fork-url $MAINNET_RPC --fork-block-number 19000000 --chain-id 1
Вы получаете копию состояния mainnet на конкретном блоке без моков. Наш опыт показывает, что именно форк-тесты выявляют неочевидные ошибки, которые не ловятся юнит-тестами. В одном проекте invariant тест за 20 минут нашёл три логические ошибки, которые ускользали от ручных тестов: при цепочке deposit → withdraw → deposit totalSupply расходился на 1 wei из-за округления.
Fuzz и invariant тесты
Fuzzing работает автоматически — достаточно передать случайный параметр в тест.
function testFuzz_Deposit(uint256 amount) public {
amount = bound(amount, 1, 1e27);
token.mint(alice, amount);
vm.prank(alice);
vault.deposit(amount);
assertEq(vault.balanceOf(alice), amount);
}
Invariant тесты проверяют, что системные инварианты сохраняются после любых последовательностей вызовов.
function invariant_TotalSupplyEqualsDeposits() public {
assertEq(vault.totalSupply(), vault.totalDeposits());
}
Интеграция с CI (GitHub Actions)
Мы настраиваем пайплайн, который запускает тесты с профилем CI на каждом коммите.
- name: Install Foundry
uses: foundry-rs/foundry-toolchain@v1
- name: Run tests
run: forge test --profile ci -v
env:
FOUNDRY_ETH_RPC_URL: ${{ secrets.MAINNET_RPC }}
Что входит в настройку
- Конфигурация foundry.toml с профилями default/ci
- Установка и ремаппинг зависимостей (OpenZeppelin, forge-std)
- Настройка Anvil с форком mainnet для интеграционных тестов
- Написание базовых fuzz и invariant тестов
- CI пайплайн с GitHub Actions (GitLab, CircleCI по запросу)
- Документация по используемым флагам и командам
Сроки
Настройка Foundry с зависимостями, профилями и CI — от 2 до 6 часов в зависимости от сложности проекта. Время включает написание шаблонных тестов и отладку форка. Стоимость рассчитывается индивидуально.
Почему выбирают нашу настройку?
Мы не просто копируем шаблонные конфиги — мы анализируем структуру вашего проекта, подбираем оптимальные параметры fuzzing и invariant, настраиваем gas-репортинг. Более 5 лет опыта в блокчейн-разработке и 50+ успешных проектов — это гарантия, что ваша конфигурация будет работать стабильно.
Получите консультацию по настройке Foundry для вашего проекта. Свяжитесь с нами — мы оценим задачи и предложим оптимальное решение.
Примечание: цены на настройку зависят от объёма работ и обсуждаются индивидуально.
Разработка смарт-контрактов
Мы столкнулись с ситуацией: контракт задеплоен, через две недели приходит сообщение — пул дренирован на $800k. Смотрим транзакцию в Tenderly: атакующий вызвал deposit(), внутри callback на ERC-777 повторно вызвал withdraw() — баланс обновился только после второго выхода. Классическая reentrancy, но не через ETH transfer, а через хук ERC-777. ReentrancyGuard стоял только на withdraw().
Такие случаи — не редкость. Смарт-контракт — это финансовая логика без возможности пропатчить её ночью. Наша команда разрабатывает контракты под ключ, встраивая защиту от reentrancy, MEV и gas-атак на ранних этапах.
Как мы разрабатываем смарт-контракты под ключ
Начинаем с аудита бизнес-логики и выбора стека. Solidity 0.8.x — стандарт для EVM-совместимых чейнов: Ethereum, Arbitrum, Optimism, Polygon, BSC, Avalanche C-Chain. Для Solana используем Rust и Anchor: модель аккаунтов и программ требует явного объявления всех ресурсов. Для проектов с формальной верификацией подходит Move (Aptos, Sui) — линейные типы языка исключают копирование ресурсов на уровне компилятора. Vyper выбираем для контрактов, где критична простота аудита (Curve Finance).
| Язык |
Модель исполнения |
Типичная область |
Риски |
| Solidity 0.8.x |
EVM, последовательное исполнение |
DeFi, NFT, токены |
Reentrancy, переполнение (unchecked) |
| Rust (Anchor) |
Solana, параллельное |
Высоконагруженные DEX, игры |
Неправильное объявление аккаунтов |
| Move |
Aptos/Sui, ресурсная |
Крупные протоколы |
Сложность экосистемы |
| Vyper |
EVM, ограниченный синтаксис |
Критические контракты (Curve) |
Зависимость от стабильности компилятора |
Gas optimization — не преждевременная оптимизация, а архитектурное решение. На Ethereum mainnet деплой плохо спроектированного контракта может стоить 2–5 ETH только из-за неоптимального storage layout. Переупаковка структуры Proposal с 7 слотов до 4 сэкономила 18k gas на каждом голосовании — около $1.5 при gas price 30 gwei. Экономия на масштабе протокола с тысячами голосований в день даёт ощутимую годовую выгоду.
Типичные ошибки в gas: передача массивов через memory вместо calldata в external функциях (дороже в 2–3 раза); использование require с длинными строками вместо custom error error InsufficientBalance(...). Кастомные ошибки дешевле на 50–200 gas на revert и передают структурированные данные фронтенду.
Почему аудит смарт-контрактов критичен для безопасности
Аудит — не разовая проверка, а встроенный этап разработки. Используем три уровня:
-
Статический анализ —
Slither (30 секунд в CI) выявляет reentrancy, неинициализированные переменные, опасный delegatecall.
-
Фаззинг и invariant тесты —
Foundry с --fuzz-runs 50000 находит edge cases, которые пропускают сотни unit-тестов. Реальный кейс: AMM контракт с кастомной математикой после 150 тестов в Hardhat — Foundry нашёл integer division truncation, позволявший пылевой атаке копить dust на контракте. Echidna проверяет инварианты («сумма всех балансов ≤ totalSupply»).
-
Ручной code review — наши инженеры с опытом 10+ лет в блокчейне выявляют логические ошибки, которые не ловят инструменты. Для протоколов с TVL > $1M обязателен внешний аудит со стороны Trail of Bits, Consensys Diligence или OpenZeppelin. Срок — 2–4 недели.
Любой апгрейдируемый протокол должен иметь timelock. TimelockController из OpenZeppelin: операция предлагается → ждёт минимальный delay (48–72 часа) → выполняется. Без timelock один скомпрометированный deployer wallet = потеря всего пула.
Какие паттерны апгрейда выбираем
| Паттерн |
Механизм |
Риск |
Когда использовать |
Наш опыт |
| Transparent Proxy (OZ) |
admin vs user разделение |
Storage collision, centralization |
Стандартные проекты |
15+ реализаций |
| UUPS |
Логика апгрейда в implementation |
Забыть _authorizeUpgrade → контракт навсегда сломан |
Газ-оптимизированные проекты |
7 проектов |
| Diamond (EIP-2535) |
Множество facets |
Сложность аудита |
Крупные протоколы с 10+ контрактами |
3 внедрения |
| Beacon Proxy |
Один beacon для множества proxies |
Beacon = single point of failure |
Фабрики однотипных контрактов |
5 фабрик |
Storage collision — главная опасность прокси. Implementation v2 не должен добавлять переменные перед существующими. OpenZeppelin Upgrades plugin для Hardhat и Foundry проверяет это автоматически, но только при использовании его API.
Как защитить контракт от MEV и front-running
На Ethereum mainnet транзакции в mempool видны всем. MEV-боты проводят sandwich-атаки на DEX, фронтраннинги минтинга и governance. Решение: commit-reveal scheme для аукционов, приватная отправка через Flashbots PROTECT RPC. EIP-7702 и PBS (proposer-builder separation) меняют картину, но пока не массово.
Процесс разработки
-
Аналитика — спецификация функций, диаграмма вызовов, анализ edge cases. Без этого кодинг начинается впустую.
-
Разработка — Solidity/Rust с тестами параллельно. Тест → код → рефакторинг. Используем Foundry для fuzz и invariant тестов.
-
Внутренний аудит — Slither + Echidna + ручной code review. Foundry invariant tests для протокольных инвариантов.
-
Внешний аудит — для проектов с реальными деньгами. Срок: 2–4 недели.
-
Деплой — Foundry scripts или Hardhat Ignition с verify на Etherscan. Gnosis Safe для ownership transfer сразу после деплоя.
-
Мониторинг — Tenderly alerts, OpenZeppelin Defender, Forta Network.
Что входит в работу
- Документация на архитектуру и спецификацию контракта (NatSpec).
- Исходный код с репозиторием и CI (Slither, Foundry, coverage).
- Развёрнутая версия контракта с verify на блокчейн-эксплорере.
- Результаты аудита (внутреннего и внешнего по запросу).
- Доступы к мониторингу и управлению (Gnosis Safe).
- Гарантия на код: фиксы критических багов в течение месяца после деплоя.
- Консультация по интеграции с веб-интерфейсом (wagmi, RainbowKit).
Сроки ориентировочно
- ERC-20 token с базовыми функциями: 1–2 недели
- Vesting контракт с cliff/linear schedule: 2–3 недели
- NFT ERC-721/1155 с маркетплейсом: 4–6 недель
- AMM или lending протокол: 2–4 месяца
- Мультичейн протокол с bridge: 4–7 месяцев
Аудит добавляет 3–6 недель и идёт параллельно с финальным тестированием где возможно. Стоимость рассчитывается индивидуально — свяжитесь с нами, и мы оценим ваш проект бесплатно.
Закажите разработку смарт-контракта — получите консультацию по архитектуре и защите от reentrancy, MEV и gas-атак. Хотите обсудить детали? Напишите нам — мы подберём оптимальный стек под вашу задачу.