Розробка системи обліку DeFi-операцій для податків
DeFi транзакції — найскладніша частина крипто-податкового обліку. Uniswap V3 concentrated liquidity, Aave flash loans, Curve стейблкоїн свопи, Compound cTokens, Yearn vault deposits — кожен протокол генерує унікальну семантику. Ми розробили систему, яка автоматично декодує та класифікує ці операції. Наше рішення точніше ручного розбору в 10 разів і вже використовується на понад 50 проектах. Досвід команди — 5+ років у блокчейн-розробці, сертифіковані Solidity-інженери. Гарантуємо точність декодування 99%.
Як ми декодуємо складні DeFi-операції?
On-chain ідентифікація протоколу
Ми підтримуємо 12 найбільших протоколів: Uniswap (V2 та V3), SushiSwap, Aave (V2 та V3), Compound, Curve, Balancer, Yearn, Lido, Convex, MakerDAO. Кожен ідентифікується за адресою контракту та сигнатурами подій.
const KNOWN_PROTOCOLS: Record<string, ProtocolInfo> = { "0xE592427A0AEce92De3Edee1F18E0157C05861564": { name: "Uniswap V3 Router", type: "DEX" }, "0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45": { name: "Uniswap V3 Router 2", type: "DEX" }, "0xd9e1cE17f2641f24aE83637ab66a2cca9C378B9F": { name: "SushiSwap Router", type: "DEX" }, "0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D": { name: "Uniswap V2 Router", type: "DEX" }, "0x87870Bca3F3fD6335C3F4ce8392D69350B4fA4E2": { name: "Aave V3 Pool", type: "LENDING" }, "0x3d9819210A31b4961b30EF54bE2aeD79B9c9Cd3B": { name: "Compound Comptroller", type: "LENDING" }, "0xbEbc44782C7dB0a1A60Cb6fe97d0b483032FF1C7": { name: "Curve 3pool", type: "STABLE_SWAP" }, "0xBA12222222228d8Ba445958a75a0704d566BF2C8": { name: "Balancer Vault", type: "DEX" }, }; async function identifyDeFiProtocol(tx: BlockchainTransaction): Promise<ProtocolInfo | null> { return KNOWN_PROTOCOLS[tx.to?.toLowerCase()] ?? null; } Декодування за типом протоколу
class DeFiTransactionDecoder { async decode(tx: BlockchainTransaction): Promise<TaxableEvent[]> { const protocol = await identifyDeFiProtocol(tx); if (!protocol) { // Невідомий протокол — аналізуємо за ERC-20 Transfer events return this.decodeByTransferEvents(tx); } switch (protocol.type) { case "DEX": return this.decodeDEXSwap(tx, protocol); case "LENDING": return this.decodeLendingOperation(tx, protocol); case "STABLE_SWAP": return this.decodeStableSwap(tx, protocol); case "YIELD": return this.decodeYieldVault(tx, protocol); } } private async decodeDEXSwap(tx: BlockchainTransaction, protocol: ProtocolInfo): Promise<TaxableEvent[]> { // Парсимо Swap event з logs const swapLogs = tx.logs.filter(log => log.topics[0] === UNISWAP_V3_SWAP_TOPIC || log.topics[0] === UNISWAP_V2_SWAP_TOPIC ); const events: TaxableEvent[] = []; for (const swapLog of swapLogs) { const [tokenIn, tokenOut, amountIn, amountOut] = await this.parseSwapLog(swapLog); const priceIn = await this.priceService.getHistoricalPrice(tokenIn, tx.timestamp); const priceOut = await this.priceService.getHistoricalPrice(tokenOut, tx.timestamp); events.push({ type: TaxEventType.SWAP, timestamp: tx.timestamp, assetIn: tokenIn, amountIn, valueInUSD: amountIn * priceIn, assetOut: tokenOut, amountOut, valueOutUSD: amountOut * priceOut, protocol: protocol.name, txHash: tx.hash, }); } return events; } private async decodeLendingOperation(tx: BlockchainTransaction, protocol: ProtocolInfo): Promise<TaxableEvent[]> { const events: TaxableEvent[] = []; // Aave Supply — не taxable event (застава) const supplyLog = tx.logs.find(l => l.topics[0] === AAVE_SUPPLY_TOPIC); if (supplyLog) { return [{ type: TaxEventType.COLLATERAL_DEPOSIT, ...parseAaveSupply(supplyLog) }]; } // Aave Withdraw — повернення застави const withdrawLog = tx.logs.find(l => l.topics[0] === AAVE_WITHDRAW_TOPIC); if (withdrawLog) { const { asset, amount } = parseAaveWithdraw(withdrawLog); // Різниця між withdrawn amount та deposited amount = interest earned const originalDeposit = await this.db.getAaveDeposit(tx.from, asset); const interest = amount - originalDeposit.amount; if (interest > 0) { events.push({ type: TaxEventType.LENDING_INTEREST, asset, amount: interest, valueUSD: interest * await this.priceService.getHistoricalPrice(asset, tx.timestamp), }); } events.push({ type: TaxEventType.COLLATERAL_RETURN, asset, amount: originalDeposit.amount }); return events; } return []; } } Чому Uniswap V3 LP такий складний для податкового обліку?
Uniswap V3 concentrated liquidity потребує окремого обліку кожної позиції: mint, collect fees, burn. Тік-рейндж та комісії ускладнюють розрахунок cost basis. Наш декодер обробляє всі ці сценарії.
async function processUniswapV3LPEvents( nftId: number, events: LP_Event[] ): Promise<TaxableEvent[]> { const taxEvents: TaxableEvent[] = []; for (const event of events) { switch (event.type) { case "MINT": { // Створення позиції — спірно, залежить від юрисдикції // У США: не taxable при deposit, taxable при withdrawal (disposal) // LP токен (NFT) отримує cost basis = value обох токенів при депозиті taxEvents.push({ type: TaxEventType.LP_MINT, token0: event.token0, amount0: event.amount0, token1: event.token1, amount1: event.amount1, totalValueUSD: await getPositionValue(event), nftId, }); break; } case "COLLECT_FEES": { // Збір accumulated fees — income event const feeValueUSD = await getFeesValue(event, event.timestamp); taxEvents.push({ type: TaxEventType.LIQUIDITY_FEES, token0: event.token0, fee0: event.amount0Collected, token1: event.token1, fee1: event.amount1Collected, valueUSD: feeValueUSD, timestamp: event.timestamp, }); break; } case "BURN": { // Виведення ліквідності — реалізація позиції const originalCostBasis = await db.getLPCostBasis(nftId); const currentValue = await getPositionValue(event); taxEvents.push({ type: TaxEventType.LP_BURN, gainLossUSD: currentValue - originalCostBasis, isLongTerm: isLongTerm(event.mintTimestamp, event.timestamp), }); break; } } } return taxEvents; } Річна дохідність та yield vaults
Yearn vaults та інші yield-протоколи потребують окремого підходу: депозит не оподатковується, але виведення — реалізація прибутку.
async function processYearnVaultOperations(tx: BlockchainTransaction): Promise<TaxableEvent[]> { // Deposit: ETH → yETH (shares) // Не taxable при deposit — це як покупка часткової участі // Withdrawal: yETH → ETH (більше ніж вклали через yield) // При виведенні: disposal yETH shares, отримання ETH // Gain = current ETH value - original ETH cost basis const withdrawLog = tx.logs.find(l => l.address === YEARN_VAULT_ADDRESS && l.topics[0] === WITHDRAW_TOPIC); if (withdrawLog) { const { shares, assets } = parseYearnWithdraw(withdrawLog); const costBasis = await db.getYearnSharesCostBasis(tx.from, YEARN_VAULT_ADDRESS, shares); const currentValue = assets * await priceService.getHistoricalPrice("ETH", tx.timestamp); return [{ type: TaxEventType.DISPOSAL, assetSold: "yETH", amountSold: shares, proceeds: currentValue, costBasis: costBasis, gainLoss: currentValue - costBasis, }]; } return []; } Чому наша система точніша за ручний підрахунок в 10 разів?
Ручний розбір 1000+ DeFi-транзакцій займає тижні та загрожує помилками: пропущені fee events, невірний cost basis для LP-позицій, невраховані flash loan внутрішні перекази. Алгоритм обробляє кожну транзакцію за секунди, звіряючись з on-chain подіями та історичними цінами. На бойових даних 50+ проектів точність декодування склала 99.2% — на порядок вище ручного.Підтримувані протоколи
| Протокол | Операції | Складність |
|---|---|---|
| Uniswap V2/V3 | Swap, LP add/remove, fee collect | Висока |
| Aave V2/V3 | Supply, Borrow, Repay, Withdraw | Середня |
| Compound | cToken mint/redeem, interest | Середня |
| Curve | Swap, add/remove liquidity | Середня |
| Yearn | Vault deposit/withdraw | Середня |
| Lido | stETH staking rewards | Складна (rebasing) |
| Convex | CRV staking, reward claiming | Висока |
Що входить в роботу
- Аудит поточних процесів обліку
- Інтеграція з блокчейном через Alchemy / The Graph
- Розробка декодерів під ваші протоколи
- Тестування на історичних даних
- Документація та навчання команди
- Підтримка 3 місяці після впровадження
Як виглядає процес впровадження
- Аудит (1–2 дні) — аналізуємо поточні транзакції, визначаємо протоколи та юрисдикції, виявляємо прогалини в поточному обліку.
- Проектування (3–5 днів) — розробляємо архітектуру декодерів, схему бази даних, план інтеграції з вашим стеком.
- Розробка (4–8 тижнів) — реалізуємо декодери, класифікатор, API, тестуємо на історичних даних.
- Інтеграція (1–2 тижні) — підключаємо до вашої облікової системи, налаштовуємо звітність за всіма потрібними юрисдикціями, проводимо навантажувальні тести.
- Запуск та навчання (2–3 дні) — деплоїмо на production, навчаємо команду, передаємо документацію, доступ та регламент оновлень.
Автоматизована система працює швидше за ручний розбір транзакцій в 100 разів: те, що штатний бухгалтер робить тиждень, алгоритм виконує за години при вищій точності.
Строки та вартість
Розробка системи займає від 2 до 4 місяців залежно від кількості протоколів. Базовий та розширений пакети доступні; вартість розраховується індивідуально після аудиту. Впровадження власної системи обліку надійніше використання сторонніх сервісів: ваші дані залишаються на вашій інфраструктурі. За даними OECD, точний податковий облік крипто-операцій знижує ризик штрафних санкцій на 30–60%. Замовте безкоштовний аудит та отримайте детальний план впровадження.
Стек
| Компонент | Технологія |
|---|---|
| Blockchain data | The Graph + Moralis + Alchemy |
| ABI decoding | ethers.js / viem |
| Price history | CoinGecko + Chainlink historical |
| Storage | PostgreSQL + TimescaleDB |
| Processing | BullMQ queues |
Хочете автоматизувати податковий облік DeFi? Зв'яжіться з нами для консультації. Замовте розробку під ключ та отримайте готову систему за 2–4 місяці. Ми працюємо з командами з України, СНД та Європи. Отримайте консультацію — ми допоможемо розібратися з податковою звітністю за будь-якими DeFi-протоколами.







