-
Notifications
You must be signed in to change notification settings - Fork 19
Description
Problem
Transactions are being processed and completed even though transaction.amlCheck is never set to Pass. This causes data inconsistency between buy_crypto.amlCheck and transaction.amlCheck.
Affected data: 10 transactions, 160,661 CHF total volume, 2 users
Root Cause
The batch service in buy-crypto-batch.service.ts does not filter for amlCheck: CheckStatus.PASS. It only checks for priceDefinitionAllowedDate: Not(IsNull()).
This allows transactions to be batched and completed before the AML check has passed. When amlCheck is later set to Pass, the postProcessing method is not called because isComplete is already true.
Current filter (lines 48-60):
const search: FindOptionsWhere<BuyCrypto> = {
outputReferenceAsset: { id: Not(IsNull()) },
outputAsset: { type: Not(In([AssetType.CUSTOM, AssetType.PRESALE])) },
priceDefinitionAllowedDate: Not(IsNull()),
batch: IsNull(),
inputReferenceAmountMinusFee: Not(IsNull()),
status: In([
BuyCryptoStatus.CREATED,
BuyCryptoStatus.WAITING_FOR_LOWER_FEE,
BuyCryptoStatus.PRICE_INVALID,
BuyCryptoStatus.MISSING_LIQUIDITY,
]),
};Fix
Add amlCheck: CheckStatus.PASS to the search filter in src/subdomains/core/buy-crypto/process/services/buy-crypto-batch.service.ts:
const search: FindOptionsWhere<BuyCrypto> = {
amlCheck: CheckStatus.PASS, // ← Add this line
outputReferenceAsset: { id: Not(IsNull()) },
outputAsset: { type: Not(In([AssetType.CUSTOM, AssetType.PRESALE])) },
priceDefinitionAllowedDate: Not(IsNull()),
batch: IsNull(),
inputReferenceAmountMinusFee: Not(IsNull()),
status: In([
BuyCryptoStatus.CREATED,
BuyCryptoStatus.WAITING_FOR_LOWER_FEE,
BuyCryptoStatus.PRICE_INVALID,
BuyCryptoStatus.MISSING_LIQUIDITY,
]),
};Import required:
import { CheckStatus } from 'src/subdomains/core/aml/enums/check-status.enum';Why this fix is correct
A transaction should never be batched for payout if the AML check has not passed. This is a fundamental business rule - no funds should be transferred without AML approval. The filter ensures this invariant is enforced at the batch level.