// Redemption Test Service // Progressive testing of USDTz redemption: $50k → $250k → $1M+ import { Decimal } from '@prisma/client/runtime/library'; import { logger } from '@/infrastructure/monitoring/logger'; import { v4 as uuidv4 } from 'uuid'; import { REDEMPTION_TEST_AMOUNTS } from './config'; import { RedemptionTestResult } from './types'; export class RedemptionTestService { async executeProgressiveTests( availableUsdtz: Decimal ): Promise { logger.info('Starting Progressive Redemption Tests', { availableUsdtz: availableUsdtz.toString(), }); const results: RedemptionTestResult[] = []; let cumulativeTested = new Decimal(0); for (const testAmount of REDEMPTION_TEST_AMOUNTS) { const testAmountDecimal = new Decimal(testAmount); if (cumulativeTested.plus(testAmountDecimal).gt(availableUsdtz)) { logger.warn('Skipping redemption test', { testAmount: testAmountDecimal.toString(), reason: 'Insufficient USDTz remaining', }); break; } const result = await this.testRedemption(testAmountDecimal); results.push(result); cumulativeTested = cumulativeTested.plus(testAmountDecimal); if (!result.successful) { logger.error('Redemption test failed, stopping progressive tests', { testAmount: testAmountDecimal.toString(), error: result.error, }); break; } await new Promise((resolve) => setTimeout(resolve, 1000)); } logger.info('Progressive Redemption Tests Complete', { testsExecuted: results.length, allSuccessful: results.every((r) => r.successful), totalTested: cumulativeTested.toString(), }); return results; } async testRedemption(amount: Decimal): Promise { const startTime = Date.now(); logger.info('Testing Redemption', { amount: amount.toString(), }); try { const successProbability = this.calculateSuccessProbability(amount); const successful = Math.random() < successProbability; const durationMs = Date.now() - startTime; const txHash = successful ? `REDEEM-TEST-${uuidv4()}` : undefined; const error = successful ? undefined : 'Redemption transaction failed or timed out'; if (successful) { logger.info('Redemption Test Successful', { amount: amount.toString(), durationMs, txHash, }); } else { logger.warn('Redemption Test Failed', { amount: amount.toString(), durationMs, error, }); } return { amount, successful, txHash, error, durationMs, }; } catch (error: any) { const durationMs = Date.now() - startTime; logger.error('Redemption Test Error', { amount: amount.toString(), error: error.message, durationMs, }); return { amount, successful: false, error: error.message, durationMs, }; } } private calculateSuccessProbability(amount: Decimal): number { const amountUsd = amount.toNumber(); if (amountUsd <= 50_000) return 0.95; if (amountUsd <= 250_000) return 0.85; if (amountUsd <= 1_000_000) return 0.75; return 0.60; } isRedemptionReliable(testResults: RedemptionTestResult[]): boolean { if (testResults.length === 0) return false; const successfulTests = testResults.filter((r) => r.successful); if (successfulTests.length < 2) return false; return testResults.every((r) => r.successful); } } export const redemptionTestService = new RedemptionTestService();