Розробка системи лімітів та верифікації обмінника

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

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

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

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

  • 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

Розробка системи лімітів та верифікації обменника

Система лімітів — не просто цифри в базі даних. Це compliance інструмент, який балансує між usability (користувач хоче обміняти одразу) та regulatory вимогами (AML вимагає знати клієнта при сумах вище порогу). Правильна архітектура лімітів знижує KYC abandonment та залишається compliant.

Структура лімітів за рівнями верифікації

interface LimitTier {
  daily: number;      // USD еквівалент
  monthly: number;
  perTransaction: number;
  fiatsAllowed: boolean;
  cryptoWithdrawalLimit: number;
  requiresKYC: KYCLevel;
}

const LIMIT_TIERS: Record<string, LimitTier> = {
  ANONYMOUS: {
    daily: 500,
    monthly: 1000,
    perTransaction: 500,
    fiatsAllowed: false,
    cryptoWithdrawalLimit: 500,
    requiresKYC: KYCLevel.NONE,
  },
  BASIC: { // email верифіковано + AML screening
    daily: 2000,
    monthly: 5000,
    perTransaction: 2000,
    fiatsAllowed: false,
    cryptoWithdrawalLimit: 5000,
    requiresKYC: KYCLevel.EMAIL,
  },
  VERIFIED: { // full KYC
    daily: 50000,
    monthly: 200000,
    perTransaction: 25000,
    fiatsAllowed: true,
    cryptoWithdrawalLimit: -1, // без ліміту
    requiresKYC: KYCLevel.FULL,
  },
};

Rolling window лімiти

Фіксовані денні вікна (00:00-23:59) створюють погану UX: користувач не може обміняти в 23:50 то що планував, тому що ліміт обнулиться через 10 хвилин. Rolling window краще:

class LimitChecker {
  async checkAndConsumeLimits(
    userId: string,
    amount: number,
    currency: string
  ): Promise<LimitCheckResult> {
    const tier = await this.getUserTier(userId);
    const limits = LIMIT_TIERS[tier];
    
    const usdAmount = await this.toUSD(amount, currency);
    
    // Перевірка однієї транзакції
    if (usdAmount > limits.perTransaction) {
      return {
        allowed: false,
        reason: "exceeds_per_transaction_limit",
        limit: limits.perTransaction,
        upgradeRequired: tier !== "VERIFIED",
      };
    }
    
    // Rolling 24h вікно
    const usage24h = await this.getUsage(userId, 24 * 60 * 60 * 1000);
    if (usage24h + usdAmount > limits.daily) {
      return {
        allowed: false,
        reason: "daily_limit_exceeded",
        available: limits.daily - usage24h,
        resetsIn: await this.getNextResetTime(userId, "daily"),
      };
    }
    
    // Rolling 30d вікно
    const usage30d = await this.getUsage(userId, 30 * 24 * 60 * 60 * 1000);
    if (usage30d + usdAmount > limits.monthly) {
      return {
        allowed: false,
        reason: "monthly_limit_exceeded",
        available: limits.monthly - usage30d,
      };
    }
    
    // Якщо всё ок — резервуємо (idempotency через Redis)
    await this.reserveLimit(userId, usdAmount);
    return { allowed: true, usdAmount };
  }
  
  private async getUsage(userId: string, windowMs: number): Promise<number> {
    const since = new Date(Date.now() - windowMs);
    return this.db.sumTransactions(userId, since);
  }
}

AML пороги та автоматичні перевірки

const AML_THRESHOLDS = {
  ENHANCED_SCREENING: 1000,    // USD — додатковий AML скрининг
  KYC_REQUIRED: 1000,          // вимагає базовий KYC
  FULL_KYC_REQUIRED: 3000,     // вимагає повний KYC
  SAR_REVIEW: 10000,           // ручна review compliance офіцером
  CTR_REPORT: 10000,           // Currency Transaction Report (у деяких юрисдикціях)
};

async function preTransactionChecks(tx: ExchangeTransaction): Promise<CheckResult> {
  // Автоматичне підвищення вимог при досягненні порогів
  if (tx.usdAmount >= AML_THRESHOLDS.FULL_KYC_REQUIRED) {
    const kycStatus = await getKYCStatus(tx.userId);
    if (kycStatus < KYCLevel.FULL) {
      return {
        action: "REQUIRE_KYC",
        requiredLevel: KYCLevel.FULL,
        message: "Для суми свище $3,000 потрібна верифікація",
      };
    }
  }
  
  // Скрининг при сумах вище $1,000
  if (tx.usdAmount >= AML_THRESHOLDS.ENHANCED_SCREENING) {
    const screenResult = await screenWallet(tx.destinationAddress, tx.asset);
    if (screenResult.blocked) {
      return { action: "BLOCK", reason: screenResult.reason };
    }
  }
  
  return { action: "ALLOW" };
}

Верифікація за джерелом коштів

Для сум вище enhanced due diligence порогу — форма Source of Funds:

interface SourceOfFunds {
  source: "employment" | "business" | "investments" | "inheritance" | "other";
  description: string;
  estimatedMonthlyVolume: number;
  supportingDocuments: string[]; // IPFS hashes або S3 URLs
}

async function collectSourceOfFunds(userId: string, amount: number): Promise<boolean> {
  if (amount < SOF_THRESHOLD) return true;
  
  const existingSOF = await db.getSourceOfFunds(userId);
  
  // SOF дійсний якщо заповнений та не істік (пересбір раз на рік)
  if (existingSOF && !isExpired(existingSOF, 365)) return true;
  
  // Запрошуємо SOF через UI
  await triggerSOFCollection(userId, { requiredFor: "transaction", amount });
  return false;
}

Система лімітів з rolling windows, AML порогами та SOF collection — 2-3 тижні розробки.