Разработка системы учета 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 месяцев в зависимости от количества протоколов. Базовый пакет (до 5 протоколов) — от 8 000 USD, расширенный (до 12 протоколов) — от 20 000 USD. Внедрение собственной системы учёта надёжнее использования сторонних сервисов: ваши данные остаются на вашей инфраструктуре. По данным 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-протоколам.







