Рефакторинг смарт-контрактов
Контракт работает, деньги не теряет — но каждый новый feature вызывает панику. Storage layout распух, функции на 200 строк, тестов нет. Наш опыт показывает, что такой технический долг накапливается незаметно, пока не приводит к критическим сбоям или потере gas. Мы гарантируем: после рефакторинга код станет предсказуемым и безопасным.
Где чаще всего скрывается технический долг
Неоптимизированный storage layout
Solidity упаковывает переменные в 32-байтные слоты. Если переменные объявлены в порядке uint128, uint256, uint128 — это три слота вместо двух. На контракте с тысячами вызовов в день переупорядочивание 8 переменных под slot packing снизило gas на write-операции на 40%. Экономия — до $5000 в год на пользователях. Это конкретные деньги, которые уходят на газ.
Unbounded loops как gas griefing
Паттерн for (uint i = 0; i < users.length; i++) в контракте, где users может расти — это не просто неэффективность. Злоумышленник добавляет 10 000 адресов, и вызов distribute() улетает за лимит блока (30M gas). Функция становится неисполнимой — contract stuck. Рефакторинг на pull-паттерн с пагинацией решает это структурно.
Cross-function reentrancy
ReentrancyGuard от OpenZeppelin защищает одну функцию. Но если withdraw() защищён guard, а claim() нет — и обе меняют один balance mapping — reentrancy возможен. Так работал эксплойт на 80M$. При рефакторинге аудируем весь граф вызовов, а не только отдельные функции.
Как мы подходим к рефакторингу
Первый шаг — статический анализ через Slither. Он за 2-3 минуты находит reentrancy, неинициализированные переменные, tx.origin авторизацию, shadow variables. Slither даёт сотни warning-ов — важно отсеять критические от информационных. Далее — Mythril для символического выполнения на ключевых функциях.
Вот пошаговый процесс работы:
- Анализ: статический и символический анализ (Slither, Mythril), составление реестра проблем с приоритетами.
- Планирование: группировка изменений, изоляция зависимостей, написание тестов для edge cases.
- Рефакторинг: каждое изменение в отдельном PR с тестами. Применяем Solidity best practices, Check-Effects-Interactions, Diamond pattern (EIP-2535).
- Тестирование: fuzz-тесты в Foundry, сравнение gas отчёта
forge snapshot.
- Развёртывание: скрипты на ethers.js, мониторинг через Tenderly.
Пример: рефакторинг стейкинг-пула
На одном проекте мы заменили unbounded loop на pull-паттерн с пагинацией. Добавили флаг emergencyWithdraw для безопасного выхода при DoS. Внедрили custom errors вместо строковых require — экономия 100 gas на reVERT. Результат: функция distribute стала исполнимой даже при росте пользователей до 50 000, а общая экономия газа достигла 15%.
Почему рефакторинг смарт-контракта дешевле аудита?
Аудит выявляет проблемы, но не исправляет их. Рефакторинг сразу устраняет технический долг. Мы не просто пишем отчёт — мы переписываем код так, чтобы он был безопасен и gas-эффективен. Typical аудит стоит $10-30k, а рефакторинг с исправлениями — ту же сумму, но с готовым кодом. Свяжитесь с нами — мы оценим ваш проект и предложим план работ.
Gas optimization: конкретные цифры
| Паттерн |
Экономия gas (примерно) |
| Slot packing переменных |
20-40% на SSTORE |
| memory вместо storage в функции |
15-30% на чтение |
| unchecked increment |
60-80 gas на итерацию |
| calldata вместо memory |
50-100 gas на аргумент |
| Custom errors вместо require strings |
50-200 gas на revert |
Типичные проблемы и решения
| Проблема |
Решение |
Экономия/выгода |
| Reentrancy через несколько функций |
Полный граф вызовов + OpenZeppelin ReentrancyGuard |
Предотвращение потерь до $80M |
| Storage layout неоптимален |
Переупорядочивание переменных, pack |
$5000/год экономии газа |
| Unbounded loops |
Pull-паттерн с пагинацией |
Гарантия исполняемости функции |
Что входит в работу
- Аудит кода с реестром уязвимостей и optimization-возможностей.
- Исправление всех критических и средних проблем.
- Тесты на Foundry (unit, integration, fuzz).
- Сравнение gas отчёта до/после.
- Документация изменений и инструкция по деплою.
- Гарантия на код — 6 месяцев поддержки.
Какие ошибки чаще всего допускают при рефакторинге?
- Правят только очевидные проблемы, не проверяя cross-function reentrancy.
- Меняют ABI без изоляции — ломают интеграции.
- Забывают обновить тесты после изменений.
- Упрощают storage layout, но не учитывают наследуемые контракты.
Наши инженеры с опытом 10+ лет в блокчейн-разработке прошли более 50 проектов рефакторинга. Получите консультацию — мы расскажем, что нужно исправить именно в вашем контракте.
Апгрейд Solidity версии
Миграция с 0.6/0.7 на 0.8+ включает: автоматические проверки overflow (SafeMath больше не нужен), custom errors, immutable переменные. Но это не просто смена pragma — ABI encoding меняется, assembly-паттерны требуют адаптации. Тестируем каждое изменение изолированно.
OpenZeppelin ReentrancyGuard — стандарт безопасности, который мы используем как базовый. Свяжитесь с нами — мы оценим ваш проект и предложим рефакторинг под ключ.
Разработка смарт-контрактов
Мы столкнулись с ситуацией: контракт задеплоен, через две недели приходит сообщение — пул дренирован на $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-атак. Хотите обсудить детали? Напишите нам — мы подберём оптимальный стек под вашу задачу.