Files
defi-arbitrage/deal-orchestrator.service.ts
defiQUG c697bf34af Initial commit: Deal orchestration tool - Freeze-resistant arbitrage loop
- Implemented complete arbitrage loop (Steps 0-4)
- Risk control service with hard caps (30% LTV, 25% USDTz exposure)
- Progressive redemption testing (0k → 50k → cd /home/intlc/projects/proxmox/dbis_core/src/core/defi/arbitrage && git commit -m "Initial commit: Deal orchestration tool - Freeze-resistant arbitrage loop

- Implemented complete arbitrage loop (Steps 0-4)
- Risk control service with hard caps (30% LTV, 25% USDTz exposure)
- Progressive redemption testing ($50k → $250k → $1M+)
- Graceful failure handling and state management
- CLI interface and programmatic API
- Comprehensive documentation

Features:
- Capital split into three buckets (Core ETH, Working Liquidity, Opportunistic)
- ETH wrapping and collateral supply
- USDT borrowing at controlled LTV
- Discount arbitrage execution
- Partial monetization with redemption testing
- Loop closing with profit capture

Design Principles:
- One-way risk only
- Anchor asset (ETH) untouchable
- No leverage on discounted assets
- Independent leg settlement"M+)
- Graceful failure handling and state management
- CLI interface and programmatic API
- Comprehensive documentation

Features:
- Capital split into three buckets (Core ETH, Working Liquidity, Opportunistic)
- ETH wrapping and collateral supply
- USDT borrowing at controlled LTV
- Discount arbitrage execution
- Partial monetization with redemption testing
- Loop closing with profit capture

Design Principles:
- One-way risk only
- Anchor asset (ETH) untouchable
- No leverage on discounted assets
- Independent leg settlement
2026-01-27 14:45:19 -08:00

211 lines
6.2 KiB
TypeScript

// Deal Orchestrator Service
// Main service that orchestrates the entire freeze-resistant arbitrage loop
import { Decimal } from '@prisma/client/runtime/library';
import { logger } from '@/infrastructure/monitoring/logger';
import { v4 as uuidv4 } from 'uuid';
import {
DealExecutionRequest,
DealExecutionResult,
DealState,
DealStep,
} from './types';
import { riskControlService } from './risk-control.service';
import { stepExecutionService } from './step-execution.service';
import { redemptionTestService } from './redemption-test.service';
export class DealOrchestratorService {
async executeDeal(
request: DealExecutionRequest
): Promise<DealExecutionResult> {
const dealId = `DEAL-${uuidv4()}`;
logger.info('Starting Deal Execution', {
dealId,
totalEthValue: request.totalEthValue,
});
const state: DealState = {
dealId,
step: DealStep.INITIALIZED,
buckets: {
coreEth: new Decimal(0),
workingLiquidity: new Decimal(0),
opportunisticUsdtz: new Decimal(0),
},
onChainTxHashes: {},
errors: [],
createdAt: new Date(),
updatedAt: new Date(),
};
const riskChecks: DealExecutionResult['riskChecks'] = [];
const redemptionTests: DealExecutionResult['redemptionTests'] = [];
try {
const totalNav = new Decimal(request.totalEthValue);
const initialRiskCheck = await riskControlService.validateDealRequest(
request,
totalNav
);
riskChecks.push(initialRiskCheck);
if (!initialRiskCheck.passed) {
throw new Error(
`Initial risk check failed: ${initialRiskCheck.errors.join(', ')}`
);
}
state.step = DealStep.CAPITAL_SPLIT;
const step0Result = await stepExecutionService.executeStep0(request);
state.buckets = step0Result.buckets;
state.updatedAt = new Date();
state.step = DealStep.WORKING_LIQUIDITY_GENERATED;
const step1Result = await stepExecutionService.executeStep1(
state.buckets,
request
);
state.collateralAmount = step1Result.collateralSupplied;
state.borrowedAmount = step1Result.borrowedUsdt;
if (step1Result.borrowTxHash) {
state.onChainTxHashes['borrow'] = step1Result.borrowTxHash;
}
if (step1Result.supplyTxHash) {
state.onChainTxHashes['supply'] = step1Result.supplyTxHash;
}
state.updatedAt = new Date();
const postBorrowRiskCheck = await riskControlService.checkLtvCompliance(
step1Result.collateralSupplied,
step1Result.borrowedUsdt
);
riskChecks.push(postBorrowRiskCheck);
state.step = DealStep.ARBITRAGE_EXECUTED;
const step2Result = await stepExecutionService.executeStep2(
step1Result.borrowedUsdt,
request
);
state.usdtzAcquired = step2Result.usdtzReceived;
if (step2Result.swapTxHash) {
state.onChainTxHashes['swap'] = step2Result.swapTxHash;
}
state.updatedAt = new Date();
const usdtzExposureCheck = await riskControlService.checkUsdtzExposure(
step2Result.usdtzReceived,
totalNav
);
riskChecks.push(usdtzExposureCheck);
if (!usdtzExposureCheck.passed) {
logger.warn('USDTz exposure exceeds limit, but continuing (non-critical)', {
errors: usdtzExposureCheck.errors,
});
}
state.step = DealStep.MONETIZATION_ATTEMPTED;
const testResults = await redemptionTestService.executeProgressiveTests(
step2Result.usdtzReceived
);
redemptionTests.push(...testResults);
const step3Result = await stepExecutionService.executeStep3(
step2Result.usdtzReceived,
request
);
state.usdtzRedeemed = step3Result.usdtzForRedemption;
state.usdtzColdStorage = step3Result.usdtzForColdStorage;
if (step3Result.redemptionTxHash) {
state.onChainTxHashes['redemption'] = step3Result.redemptionTxHash;
}
state.updatedAt = new Date();
let step4Result;
if (step3Result.redemptionSuccessful && step3Result.usdtReceived) {
state.step = DealStep.LOOP_CLOSED;
step4Result = await stepExecutionService.executeStep4(
step1Result.borrowedUsdt,
step3Result.usdtReceived,
step3Result.usdtzForColdStorage,
step1Result.collateralSupplied
);
if (step4Result.repayTxHash) {
state.onChainTxHashes['repay'] = step4Result.repayTxHash;
}
if (step4Result.unlockTxHash) {
state.onChainTxHashes['unlock'] = step4Result.unlockTxHash;
}
state.updatedAt = new Date();
} else {
state.step = DealStep.FROZEN;
logger.warn('Deal degraded to holding state', {
reason: 'USDTz redemption failed or frozen',
note: 'ETH collateral remains safe, loan is healthy, USDTz is optional upside',
});
}
let finalProfit: Decimal | undefined;
if (step4Result) {
finalProfit = step4Result.profitCaptured;
}
const status: DealExecutionResult['status'] =
state.step === DealStep.LOOP_CLOSED
? 'completed'
: state.step === DealStep.FROZEN
? 'frozen'
: 'partial';
logger.info('Deal Execution Complete', {
dealId,
status,
finalProfit: finalProfit?.toString(),
});
return {
dealId,
state,
step0: step0Result,
step1: step1Result,
step2: step2Result,
step3: step3Result,
step4: step4Result,
riskChecks,
redemptionTests,
finalProfit,
status,
};
} catch (error: any) {
logger.error('Deal Execution Failed', {
dealId,
error: error.message,
stack: error.stack,
});
state.step = DealStep.FAILED;
state.errors.push(error.message);
state.updatedAt = new Date();
return {
dealId,
state,
riskChecks,
redemptionTests,
status: 'failed',
};
}
}
async getDealStatus(dealId: string): Promise<DealState | null> {
return null;
}
async listDeals(limit: number = 10): Promise<DealState[]> {
return [];
}
}
export const dealOrchestratorService = new DealOrchestratorService();