Розробка системи податкового обліку криптовалют

Проєктуємо та розробляємо блокчейн-рішення повного циклу: від архітектури смарт-контрактів до запуску DeFi-протоколів, NFT-маркетплейсів та криптобірж. Аудит безпеки, токеноміка, інтеграція з наявною інфраструктурою.
Показано 1 з 1Усі 1306 послуг
Розробка системи податкового обліку криптовалют
Середній
~1-2 тижні
Часті запитання

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

Етапи блокчейн-розробки

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

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

Розробка системи податкового обліку крипто-валют

Податковий облік крипто-валют складніше ніж здається: кожен своп, стейкинг-нагорода, airdrop, продаж NFT — потенційно opodatkovia подія. Для користувача з активною DeFi історією це сотні транзакцій на рік. Система повинна класифікувати їх, розрахувати cost basis та сформувати звіт у форматі потрібної юрисдикції.

Класифікація податкових подій

Ключовий крок перед будь-яким розрахунком — правильна класифікація кожної транзакції:

enum TaxEventType {
  DISPOSAL = "disposal",         // продаж, своп — capital gains/losses
  INCOME = "income",             // mining reward, staking, airdrops — звичайний дохід
  PURCHASE = "purchase",         // покупка крипто за фіат — не opodatkovia сама по собі
  TRANSFER = "transfer",         // передача між своїми гаманцями — не opodatkovia
  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;       // справедлива ринкова вартість у момент подіїї
  costBasis?: number;           // для disposal: cost basis реалізуємого активу
  gainsOrLoss?: number;         // proceeds - cost_basis
  isLongTerm?: boolean;         // > 1 року володіння (у США: нижча ставка)
  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): Німеччина, Нідерланди та ряд інших країн ЄС.

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: [], // немає окремих лотів у середній вартості
    };
  }
}

Історичні ціни

Cost basis вимагає справедливої ринкової вартості в момент кожної транзакції. Джерела:

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;
  }
}

Проблема: для токенів без ліквідності (невідомі altcoins) історичні ціни можуть відсутствувати. У таких випадках або використовуємо дані CEX, або документуємо як "ціна не визначена".

Специфіка DeFi

DeFi транзакції — найскладніша частина:

Забезпечення ліквідності (Uniswap V2 LP): депозит двох токенів → отримання LP токенів. Це НЕ opodatkovia саме по собі у більшості юрисдикцій. Але при виведенні ліквідності — кожен отриманий токен порівнюється з cost basis LP токенів.

Uniswap V3 (зосереджена ліквідність): ще складніше, оскільки позиція має діапазон та impermanent loss. Кожна зміна комісій — потенційна подія доходу.

Yield farming / стейкинг нагороди: більшість юрисдикцій трактує як звичайний дохід при отриманні за справедливою ринковою вартістю.

Airdrop: спірно. США: opodatkovia дохід при отриманні. Ряд країн ЄС: opodatkovia тільки при продажу.

Формування податкового звіту

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

// США: Schedule D формат, сумісний
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",
    }));
}

// Великобританія: HMRC Capital Gains Summary
function generateHMRCSummary(events: TaxEvent[], taxYear: string): HMRCSummary {
  // Великобританія використовує метод "池" (Section 104 pool) + правило 30 днів
  const ukEvents = applyUKPoolingRules(events);
  return formatHMRCReport(ukEvents, taxYear);
}

Стек

Компонент Технологія
Імпорт транзакцій Exchange APIs (Binance, Coinbase) + wallet indexing
Історія цін CoinGecko + CryptoCompare
Cost basis двигун Node.js + PostgreSQL
Генерація звітів PDF (PDFKit) + CSV + Excel
Frontend React + TypeScript

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