Unlimited approve: реальная угроза для DeFi
Unlimited approve — стандартная практика в DeFi для экономии газа, но и вектор атаки при компрометации протокола. Пользователь даёт approve(spender, type(uint256).max) один раз и забывает. При взломе протокола злоумышленник может вывести все средства через старые апрувы. После взлома Curve несколько лет назад злоумышленники вывели более $6 млн через старые апрувы. Revoke.cash — open-source инструмент для просмотра и отзыва таких разрешений. Мы интегрируем его в ваш dApp: от быстрой deeplink-кнопки до полноценного embedded списка allowances. Закажите интеграцию — повысите доверие пользователей.
Почему интеграция Revoke.cash критична для DeFi-продукта?
Без инструмента отзыва апрувалов пользователи рискуют потерять средства при взломе любого протокола, которому когда-либо дали approve. Интеграция Revoke.cash снижает этот риск и укрепляет доверие к вашему продукту. Deeplink-интеграция занимает 30 минут и подходит для быстрого запуска. Embedded версия через SDK занимает 1–5 дней, но даёт полный контроль над UI и не уводит пользователя из dApp. Мы реализовали внедрение в 25+ DeFi-проектов, гарантируем сроки и безопасность.
Deeplink vs Embedded: какой подход выбрать?
| Параметр | Deeplink | Embedded (через SDK) |
|---|---|---|
| Время интеграции | 30 минут – 1 день | 1–5 дней |
| UX | Редирект на revoke.cash | Без покидания dApp |
| Кастомизация | Минимальная | Полный контроль интерфейса |
| Газовые затраты | Пользователь платит сам | Пользователь платит сам |
| Безопасность | Высокая (аудированный проект) | Высокая (аудированный проект) |
| Подходит для | Быстрого запуска, MVP | Продуктов с фокусом на безопасность |
Как реализовать интеграцию через deeplink и embedded?
Для deeplink достаточно кнопки с ссылкой на revoke.cash с параметрами адреса и chainId. Пример компонента на React:
import { useAccount } from 'wagmi' function ManageApprovalsButton() { const { address, chainId } = useAccount() const revokeUrl = address ? `https://revoke.cash/${address}?chainId=${chainId ?? 1}` : 'https://revoke.cash' return ( <a href={revokeUrl} target="_blank" rel="noopener noreferrer" className="flex items-center gap-2 text-sm text-yellow-400 hover:text-yellow-300" > <ShieldAlert className="h-4 w-4" /> Управление разрешениями </a> ) } Revoke.cash поддерживает параметр chainId — пользователь сразу попадает на нужную сеть.
Если нужно показывать allowances внутри dApp без редиректа — читаем напрямую через ERC-20 allowance():
import { createPublicClient, http, erc20Abi } from 'viem' async function getAllowance( tokenAddress: `0x${string}`, owner: `0x${string}`, spender: `0x${string}`, chainId: number ): Promise<bigint> { const client = createPublicClient({ chain: getChain(chainId), transport: http() }) return client.readContract({ address: tokenAddress, abi: erc20Abi, functionName: 'allowance', args: [owner, spender], }) } Для revoke — approve(spender, 0):
import { useWriteContract } from 'wagmi' import { erc20Abi } from 'viem' function RevokeButton({ tokenAddress, spender }: { tokenAddress: `0x${string}`, spender: `0x${string}` }) { const { writeContract, isPending } = useWriteContract() return ( <button onClick={() => writeContract({ address: tokenAddress, abi: erc20Abi, functionName: 'approve', args: [spender, 0n], })} disabled={isPending} > {isPending ? 'Отзыв...' : 'Отозвать разрешение'} </button> ) } Обратите внимание: 0n (BigInt ноль), не 0. viem строго типизирован и ожидает bigint для uint256.
Сравнение затрат газа
| Операция | Gas used (примерно) | Комментарий |
|---|---|---|
| approve (unlimited) | 45k gas | Стандартный расход |
| revoke (approve 0) | 45k gas | Аналогичный расход |
| batch revoke (через Revoke.cash SDK) | от 60k gas | Экономия при массовом отзыве |
Как мы внедряем Revoke.cash: процесс и гарантии
| Этап | Длительность | Что делаем |
|---|---|---|
| Аналитика | 0.5 дня | Изучаем текущие allowances, стек dApp, выбираем подход |
| Проектирование | 0.5–1 день | Разрабатываем архитектуру, UI/UX |
| Реализация | 1–3 дня | Пишем компоненты, интеграция с Revoke.cash SDK или deeplink |
| Тестирование | 0.5–1 день | Тестируем на testnet и mainnet, проверяем gas cost |
| Деплой | 0.5 дня | Развёртывание, финальная проверка, документация |
В рамках интеграции мы анализируем текущие allowances и стек dApp, проектируем оптимальное решение, реализуем компоненты и тестируем их на testnet и mainnet. После деплоя предоставляем документацию и поддержку. За 5 лет работы мы реализовали 25+ Web3-проектов. Гарантируем интеграцию в срок и соответствие лучшим практикам безопасности.
Что входит в работу: наши обязательства
| Deliverable | Описание |
|---|---|
| Документация | Инструкция по использованию компонентов, описание API |
| Доступы | GitHub-репозиторий с кодом, доступ к тестовым сетям |
| Обучение команды | Онлайн-сессия по настройке и кастомизации |
| Поддержка | 7 дней после деплоя — отвечаем на вопросы |
Как проходит интеграция: пошаговый чеклист
- Оценка текущих апрувов: анализируем существующие allowances вашего dApp и определяем, какие из них требуют отзыва.
- Выбор подхода: deeplink или embedded — исходя из требований к UX и безопасности.
- Разработка компонентов: реализуем кнопку управления allowances и, при необходимости, UI для отображения списка.
- Тестирование: проверяем на тестовой сети, эмулируем сценарии отзыва.
- Развёртывание: деплоим в mainnet, документируем изменения.
Где разместить кнопку управления allowances
Логичные места для кнопки управления allowances:
- В разделе Settings / Security dApp
- После approve транзакции — всплывающая подсказка «Хотите ограничить разрешение?»
- В Wallet dropdown — рядом с балансом и disconnect
- В Transaction history — рядом с историческими approve операциями
Показывать кнопку на главной странице не стоит — это создаёт лишнюю тревогу. Возможность должна быть легко находимой, но не навязчивой. Оценим ваш проект за 1 день — свяжитесь с нами. Закажите интеграцию через форму на сайте.
Ссылка на Revoke.cash — open-source проект, на котором основана интеграция.







