Разработка системы налогового учета криптовалют

Проектируем и разрабатываем блокчейн-решения полного цикла: от архитектуры смарт-контрактов до запуска DeFi-протоколов, NFT-маркетплейсов и криптобирж. Аудит безопасности, токеномика, интеграция с существующей инфраструктурой.
Показано 1 из 1 услугВсе 1306 услуг
Разработка системы налогового учета криптовалют
Средняя
~1-2 недели
Часто задаваемые вопросы
Направления блокчейн-разработки
Этапы блокчейн-разработки
Последние работы
  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1258
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1170
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    873
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1092
  • image_logo-advance_0.png
    Разработка логотипа компании B2B Advance
    563
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    830

Разработка системы налогового учета криптовалют

Налоговый учёт криптовалют сложнее чем кажется: каждый swap, staking reward, airdrop, NFT продажа — потенциально налогооблагаемое событие. Для пользователя с активной DeFi историей это сотни транзакций в год. Система должна классифицировать их, рассчитать cost basis и сформировать отчёт в формате нужной юрисдикции.

Классификация налоговых событий

Ключевой шаг перед любым расчётом — правильная классификация каждой транзакции:

enum TaxEventType {
  DISPOSAL = "disposal",         // продажа, своп — capital gains/losses
  INCOME = "income",             // mining reward, staking, airdrops — ordinary income
  PURCHASE = "purchase",         // покупка крипты за фиат — не taxable само по себе
  TRANSFER = "transfer",         // перевод между своими кошельками — не taxable
  GAS_FEE = "gas_fee",          // может добавляться к cost basis или списываться
  GIFT_SENT = "gift_sent",
  GIFT_RECEIVED = "gift_received",
  FORK = "fork",                 // hard fork / airdrop
}

interface TaxEvent {
  id: string;
  userId: string;
  timestamp: Date;
  type: TaxEventType;
  asset: string;
  amount: number;
  usdValueAtTime: number;       // fair market value в момент события
  costBasis?: number;           // для disposal: cost basis реализуемого актива
  gainsOrLoss?: number;         // proceeds - cost_basis
  isLongTerm?: boolean;         // > 1 года владения (в US: пониженная ставка)
  txHash: string;
  exchange?: string;
  notes?: string;
}

Cost Basis методы

Разные юрисдикции требуют разные методы:

FIFO (First In, First Out): первые купленные — первые проданные. США, Великобритания, большинство юрисдикций по умолчанию.

LIFO (Last In, First Out): последние купленные — первые проданные. Разрешён в некоторых случаях в США.

HIFO (Highest In, First Out): продаём сначала самое дорогое — минимизирует налог. Выгодно при росте рынка.

Средневзвешенная (Average Cost): Германия, Нидерланды и ряд других EU стран.

class CostBasisCalculator {
  // FIFO реализация
  async calculateFIFO(
    asset: string,
    userId: string,
    disposalAmount: number,
    disposalDate: Date
  ): Promise<CostBasisResult> {
    // Получаем все покупки в хронологическом порядке
    const lots = await this.db.getAssetLots(userId, asset, {
      orderBy: "acquired_at ASC",
      remainingAmount: "> 0",
    });
    
    let remainingToDispose = disposalAmount;
    let totalCostBasis = 0;
    const usedLots: LotUsage[] = [];
    
    for (const lot of lots) {
      if (remainingToDispose <= 0) break;
      
      const amountFromThisLot = Math.min(lot.remainingAmount, remainingToDispose);
      const costBasisFromLot = (amountFromThisLot / lot.originalAmount) * lot.totalCostBasis;
      
      totalCostBasis += costBasisFromLot;
      remainingToDispose -= amountFromThisLot;
      
      usedLots.push({
        lotId: lot.id,
        amountUsed: amountFromThisLot,
        costBasisUsed: costBasisFromLot,
        acquiredAt: lot.acquiredAt,
        holdingPeriodDays: Math.floor(
          (disposalDate.getTime() - lot.acquiredAt.getTime()) / 86400000
        ),
      });
      
      // Обновляем остаток лота
      await this.db.reduceLotAmount(lot.id, amountFromThisLot);
    }
    
    return { totalCostBasis, usedLots, isLongTerm: this.isLongTerm(usedLots) };
  }
  
  // Средневзвешенная (для DE, NL)
  async calculateAverageCost(
    asset: string,
    userId: string,
    disposalAmount: number
  ): Promise<CostBasisResult> {
    const { totalAmount, totalCost } = await this.db.getAggregatedPosition(userId, asset);
    const averageCostPerUnit = totalCost / totalAmount;
    
    return {
      totalCostBasis: averageCostPerUnit * disposalAmount,
      usedLots: [], // нет отдельных лотов в average cost
    };
  }
}

Исторические цены

Cost basis требует fair market value в момент каждой транзакции. Источники:

class PriceHistoryService {
  async getHistoricalPrice(asset: string, timestamp: Date): Promise<number> {
    // 1. Проверяем собственный кеш
    const cached = await this.cache.get(asset, timestamp);
    if (cached) return cached;
    
    // 2. CoinGecko API (free tier: 1 год истории)
    const price = await this.coingecko.getHistoricalPrice(asset, timestamp);
    
    // 3. Fallback: CryptoCompare, Messari
    if (!price) {
      return this.cryptoCompare.getHistoricalClose(asset, timestamp);
    }
    
    await this.cache.set(asset, timestamp, price);
    return price;
  }
}

Проблема: для токенов без ликвидности (obscure altcoins) исторические цены могут отсутствовать. В таких случаях нужно либо использовать CEX данные, либо документировать как "price not determinable".

DeFi специфика

DeFi транзакции — самая сложная часть:

Liquidity provision (Uniswap V2 LP): депозит двух токенов → получение LP токенов. Это NOT taxable само по себе в большинстве юрисдикций. Но при выводе ликвидности — каждый полученный токен сравнивается с cost basis LP токенов.

Uniswap V3 (concentrated liquidity): ещё сложнее, так как позиция имеет range и impermanent loss. Каждое изменение fees — потенциальный income event.

Yield farming / staking rewards: большинство юрисдикций трактует как ordinary income в момент получения по fair market value.

Airdrop: спорно. США: taxable income при получении. Ряд EU стран: taxable только при продаже.

Формирование налогового отчёта

Разные форматы для разных юрисдикций:

// US: Schedule D compatible format
function generateScheduleD(events: TaxEvent[]): ScheduleDRow[] {
  return events
    .filter(e => e.type === TaxEventType.DISPOSAL)
    .map(e => ({
      description: `${e.amount} ${e.asset}`,
      dateAcquired: formatDate(e.costBasisLot.acquiredAt),
      dateSold: formatDate(e.timestamp),
      proceeds: e.usdValueAtTime,
      costBasis: e.costBasis!,
      gainOrLoss: e.gainsOrLoss!,
      term: e.isLongTerm ? "LONG" : "SHORT",
    }));
}

// UK: HMRC Capital Gains Summary
function generateHMRCSummary(events: TaxEvent[], taxYear: string): HMRCSummary {
  // UK использует "pool" method (Section 104 pool) + 30-day same-day rule
  const ukEvents = applyUKPoolingRules(events);
  return formatHMRCReport(ukEvents, taxYear);
}

Стек

Компонент Технология
Transaction import Exchange APIs (Binance, Coinbase) + wallet indexing
Price history CoinGecko + CryptoCompare
Cost basis engine Node.js + PostgreSQL
Report generation PDF (PDFKit) + CSV + Excel
Frontend React + TypeScript

Система налогового учёта с FIFO/LIFO/Average, DeFi классификацией и мультиюрисдикционными отчётами — 6-10 недель разработки.