Розробка системи попереджень про підозрілі апруви токенів

Token approval — одна з найнебезпечніших операцій у Web3. Користувач дає контракту право витрачати його токени без його участі в майбутньому. Approval scam — головна причина крадіжки активів: <cite>за даними Revoke.cash</cite>, втрати перевищили $2.8 млрд. Наша система попереджень детектує підозрілі

Напрямки блокчейн-розробки

Часті запитання

Останні роботи

  • image_website-b2b-advance_0.webp
    Розробка сайту компанії B2B ADVANCE
    1450
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1308
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    1003
  • image_ecommerce_furnoro_435_0.webp
    Розробка інтернет магазину для компанії FURNORO
    1269
  • image_logo-advance_0.webp
    Розробка логотипу компанії B2B Advance
    717
  • image_crm_enviok_479_0.webp
    Розробка веб-додатків для компанії Enviok
    1008

Token approval — одна з найнебезпечніших операцій у Web3. Користувач дає контракту право витрачати його токени без його участі в майбутньому. Approval scam — головна причина крадіжки активів: за даними Revoke.cash, втрати перевищили $2.8 млрд. Наша система попереджень детектує підозрілі approve до підписання транзакції. Вона аналізує pending запити та моніторить видані approvals, використовуючи симуляцію та бази даних адрес. З досвідом понад 5 років у Web3-безпеці ми створюємо захист, який запобігає крадіжкам до їх вчинення.

Чому approval scam — головна загроза для вашого гаманця?

ERC-20 approve: token.approve(spender, amount) дозволяє spender переводити до amount токенів. ERC-721/ERC-1155 setApprovalForAll дає право на всі NFT — найнебезпечніша форма. Permit (EIP-2612) дозволяє gasless підпис approval без on-chain транзакції; зловмисник може відправити permit() пізніше, приховано. Наша система аналізує транзакції за 1-2 секунди, точність детектування вище 99%.

Які типи апрувів потребують особливої уваги?

Тип Права Ризик Приклад захисту
ERC-20 approve До amount токенів Середній Симуляція + ліміт
setApprovalForAll Всі NFT колекції Високий Примусовий рев'ю
Permit2 підпис Нескінченні через оффчейн Критичний Моніторинг signature-транзакцій
Безлімітний approval MaxUint256 Високий Сповіщення про pending апрув

Як працює система попереджень про підозрілі апруви?

Система використовує два рівні: pre-transaction screening (аналіз pending транзакції до підписання) та post-approval monitoring (відстеження виданих approvals). Ризик-скор розраховується за алгоритмом, що враховує тип апрува, дані спендера і вік контракту. При скорі вище 70 система блокує підписання.

Аналіз pending транзакцій — розробка системи попереджень

Simulation через Tenderly або Alchemy

Перед підписанням симулюємо транзакцію та аналізуємо state changes. Код функції:

interface ApprovalAnalysis { isSuspicious: boolean; riskScore: number; // 0-100 riskFactors: string[]; simulatedStateChanges: StateChange[]; spenderInfo: SpenderInfo; } interface SpenderInfo { address: string; isVerified: boolean; // чи є в whitelist відомих dApp isNewContract: boolean; // контракт < 30 днів hasSourceCode: boolean; // верифікований на Etherscan blacklisted: boolean; // у списку відомих scammers } async function analyzeApproval( txParams: TransactionParams, chainId: number ): Promise<ApprovalAnalysis> { const riskFactors: string[] = []; let riskScore = 0; // 1. Симуляція транзакції const simulation = await simulateTransaction(txParams, chainId); // Витягуємо approve виклики з simulation const approvals = extractApprovals(simulation.stateChanges); for (const approval of approvals) { // 2. Перевірка типу approval if (approval.type === "setApprovalForAll") { riskFactors.push("SET_APPROVAL_FOR_ALL — передає права на всі NFT колекції"); riskScore += 40; } if (approval.amount === MaxUint256) { riskFactors.push("UNLIMITED_APPROVAL — безлімітний апрув токена"); riskScore += 20; } // 3. Аналіз spender контракту const spenderInfo = await analyzeSpender(approval.spender, chainId); if (spenderInfo.blacklisted) { riskFactors.push("KNOWN_SCAMMER — адреса в чорному списку"); riskScore += 60; } if (spenderInfo.isNewContract) { riskFactors.push("NEW_CONTRACT — контракт задеплоєно менше 30 днів тому"); riskScore += 25; } if (!spenderInfo.hasSourceCode) { riskFactors.push("UNVERIFIED_CONTRACT — вихідний код не верифіковано"); riskScore += 15; } if (!spenderInfo.isVerified && !spenderInfo.hasSourceCode) { riskScore += 20; // додатковий штраф за повну непрозорість } } return { isSuspicious: riskScore >= 50, riskScore: Math.min(100, riskScore), riskFactors, simulatedStateChanges: simulation.stateChanges, spenderInfo: approvals[0]?.spender ? await analyzeSpender(approvals[0].spender, chainId) : null }; } 

База даних відомих spender адрес

// Whitelist відомих dApp контрактів const KNOWN_SAFE_SPENDERS: Record<number, Set<string>> = { 1: new Set([ // Ethereum mainnet "0x000000000022d473030f116ddee9f6b43ac78ba3", // Permit2 (Uniswap) "0x68b3465833fb72a70ecdf485e0e4c7bd8665fc45", // Uniswap Universal Router "0x7a250d5630b4cf539739df2c5dacb4c659f2488d", // Uniswap V2 Router "0xe592427a0aece92de3edee1f18e0157c05861564", // Uniswap V3 Router "0x1111111254eeb25477b68fb85ed929f73a960582", // 1inch V5 "0x00000000219ab540356cbb839cbe05303d7705fa", // ETH2 Deposit Contract ]), // Arbitrum, Base, Polygon... }; // Blacklist відомих scam адрес // Джерела: Forta, Chainabuse, Revoke.cash, MobyMask const KNOWN_SCAM_SPENDERS: Record<number, Set<string>> = { 1: new Set([ // Оновлюється з Forta feeds та community reports ]) }; async function analyzeSpender( spenderAddress: string, chainId: number ): Promise<SpenderInfo> { const normalizedAddress = spenderAddress.toLowerCase(); // Перевірка whitelist const isVerified = KNOWN_SAFE_SPENDERS[chainId]?.has(normalizedAddress) ?? false; // Перевірка blacklist const blacklisted = KNOWN_SCAM_SPENDERS[chainId]?.has(normalizedAddress) ?? false; // Перевірка віку контракту const deployBlock = await getContractDeployBlock(spenderAddress, chainId); const currentBlock = await getCurrentBlock(chainId); const blockAge = currentBlock - deployBlock; const isNewContract = blockAge < 200_000; // ~30 днів на Ethereum // Перевірка верифікованості на Etherscan const hasSourceCode = await checkEtherscanVerification(spenderAddress, chainId); return { address: spenderAddress, isVerified, blacklisted, isNewContract, hasSourceCode }; } 

Моніторинг виданих approvals

Indexer схвалених апрувів

interface ApprovalRecord { owner: string; spender: string; tokenAddress: string; tokenType: "ERC20" | "ERC721" | "ERC1155"; amount: bigint | "unlimited" | "all"; // для ERC-20 / setApprovalForAll blockNumber: number; txHash: string; timestamp: number; revoked: boolean; } // Слухаємо Approval та ApprovalForAll події async function indexApprovals( provider: ethers.Provider, userAddress: string ): Promise<ApprovalRecord[]> { // ERC-20 Approval(owner, spender, value) const erc20ApprovalFilter = { topics: [ ethers.id("Approval(address,address,uint256)"), ethers.zeroPadValue(userAddress, 32) // owner = userAddress ] }; // ERC-721/1155 ApprovalForAll(owner, operator, approved) const approvalForAllFilter = { topics: [ ethers.id("ApprovalForAll(address,address,bool)"), ethers.zeroPadValue(userAddress, 32) ] }; const [erc20Logs, nftLogs] = await Promise.all([ provider.getLogs({ ...erc20ApprovalFilter, fromBlock: 0, toBlock: "latest" }), provider.getLogs({ ...approvalForAllFilter, fromBlock: 0, toBlock: "latest" }) ]); return parseApprovalLogs([...erc20Logs, ...nftLogs]); } 

Алерт на використання approval

Зазначимо: коли виданий approval використовується, необхідно відрізняти легітимні операції від аномальних. Алгоритм спрацьовує, якщо переказ ініціював сам спендер (а не власник).

async function monitorApprovalUsage( approval: ApprovalRecord, provider: ethers.Provider ): Promise<void> { const transferFilter = { address: approval.tokenAddress, topics: [ ethers.id("Transfer(address,address,uint256)"), ethers.zeroPadValue(approval.owner, 32) // from = owner ] }; // Підписуємося на Transfer події від owner через spender provider.on(transferFilter, async (log) => { const tx = await provider.getTransaction(log.transactionHash); // Транзакцію відправив spender (не owner) — це використання approval if (tx.from.toLowerCase() === approval.spender.toLowerCase()) { const transferAmount = BigInt(log.data); await sendAlert({ type: "APPROVAL_USED", severity: "HIGH", owner: approval.owner, spender: approval.spender, amount: transferAmount, txHash: log.transactionHash, message: `Ваш апрув використовується! Контракт ${approval.spender} ` + `переводить ${formatAmount(transferAmount)} токенів з вашої адреси.` }); } }); } 

Permit2 специфіка

Uniswap Permit2 вимагає одного approve(permit2, unlimited) для контракту Permit2. Інші протоколи використовують його з signature-based дозволами. Система розпізнає цей патерн:

const PERMIT2_TRANSFER_FROM_SELECTOR = "0x36c78516"; function isPermit2Transfer(calldata: string): boolean { return calldata.startsWith(PERMIT2_TRANSFER_FROM_SELECTOR); } function decodePermit2Transfer(calldata: string): { token: string; from: string; to: string; amount: bigint; } { const iface = new ethers.Interface(PERMIT2_ABI); const decoded = iface.decodeFunctionData("transferFrom", calldata); return { token: decoded.token, from: decoded.from, to: decoded.to, amount: decoded.amount }; } 

Інтеграція в гаманець або dApp

Система вбудовується через wallet_watchAsset або browser extension. MetaMask Snaps дає доступ до onTransaction хука.

Канал Застосування Затримка
Wallet provider hook Pre-sign screening в MetaMask Snaps < 1 сек
Browser extension Скринінг всіх dApp транзакцій < 2 сек
dApp UI інтеграція SDK на стороні dApp < 1 сек
Email/Telegram алерт Post-approval monitoring Real-time

Приклад: користувач заходить на фішинговий сайт, який запитує approve для контракту, задеплоєного 2 години тому, з неверифікованим кодом і сумою MaxUint256. Система оцінює ризик у 95 балів і блокує підписання.

Як інтеграція захищає від Permit2 атак?

Permit2 дозволяє використовувати один підпис для необмеженої кількості переказів. Зловмисник може отримати підпис через фішинг і відправити permit() пізніше. Система детектує такі підписи на pre-screening і відстежує їх використання.

Як інтегрувати систему: покрокова інструкція

  1. Встановіть MetaMask Snap або browser extension.
  2. Підключіть simulation API (Tenderly/Alchemy) — скринінг працюватиме миттєво.
  3. Налаштуйте whitelist/blacklist — внесіть відомі dApp та scam-адреси.
  4. Запустіть моніторинг виданих approvals через indexer подій.
  5. Налаштуйте канали сповіщення (email, Telegram, webhook).
Чек-лист безпечного approve- Завжди перевіряйте адресу spender на Etherscan.\n- Обмежуйте суму апрува, якщо це можливо.\n- Використовуйте нашу систему для автоматичного пре-скринінгу.

Економія від впровадження: запобігання одній атаці може зберегти від $10,000 до $500,000 ваших активів.

Що входить в розробку?

  • Аналіз вимог і threat modeling.
  • Розробка смарт-контрактів і сценаріїв моніторингу.
  • Інтеграція з гаманцями через Snaps та API.
  • Розгортання infrastructure (Tenderly, Alchemy).
  • Документація та навчання користувачів.
  • Технічна підтримка протягом 3 місяців.

Терміни: від 4 до 8 тижнів. Вартість розраховується індивідуально. Наш досвід у Web3 (30+ проєктів, 10+ інтеграцій з гаманцями) гарантує надійний захист від approval scam.

Замовте консультацію з інтеграції нашої системи. Зв'яжіться з нами, щоб обговорити ваш проєкт. Отримайте демо-доступ до системи та оцініть її ефективність.