Compliance

The DAC8 Reporting Workflow: Extracting Customer Transactions in CARF-Ready Format

June 15, 2026 · 9 min read

This is part 5 of our "Tools for Compliance" series. Our recent briefing, DAC8 in Italy, mapped the deadlines — collection live since 1 January 2026, first report due mid-2027. This piece is the operational half: the field-by-field workflow that turns a customer's raw on-chain activity into a CARF-ready report, and the four places that extraction quietly goes wrong.

DAC8 is widely read as a reporting obligation. Operationally it is an extraction obligation wearing a reporting deadline. The format the tax authority wants — aggregate gross amounts, unit counts, transaction counts, per user, per asset, per category, valued in fiat at the moment of each transaction — does not exist anywhere in a CASP's systems by default. It has to be reconstructed from order books, custody ledgers, and on-chain transfers that were never designed to answer the question CARF asks. The report is the easy last step. The reconstruction is the project.

4
Transaction Categories
Fiat trades, crypto swaps, transfers, payments
Per-tx
Valuation Basis
Fair market value at execution time
Gross
Reporting Basis
Aggregate gross amounts + unit + tx counts
Unhosted
The Flag That Matters
Transfers to non-CASP wallets, identified

The CARF Data Model: What the Report Actually Carries

Strip DAC8/CARF to its payload and it is a structured record per reportable user, per crypto-asset, per reference year. For each, the report carries:

  • User identity block — name, address, jurisdiction(s) of residence, TIN per jurisdiction, date/place of birth for individuals; for entities, the controlling persons with their own identity blocks
  • Per-asset, per-category aggregates — not a transaction log. For each crypto-asset and each of the four categories below: the gross amount paid/received (in fiat), the number of units, and the number of transactions — reported separately for acquisitions and disposals
  • Transfer detail — for transfers out, the fiat value, unit count, transaction count, and crucially whether the destination is an unhosted wallet (not known to be at another reporting CASP)

The shape matters because it dictates the extraction. You are not exporting a ledger; you are computing grouped aggregates with a fiat valuation attached to every leg. A pipeline that can dump transactions but cannot group-and-value them has done none of the actual work.

The Four Categories Every Transaction Must Map To

CARF reduces all reportable activity to four buckets. Every customer event has to be classified into exactly one — and misclassification is the most common silent error:

1. Crypto-to-fiat (and fiat-to-crypto)

Acquisitions of crypto against fiat and disposals of crypto for fiat. The fiat leg gives you the valuation for free — this is the easy category, and the one CASPs over-index on while under-building the others.

2. Crypto-to-crypto exchanges

A swap of one crypto-asset for another is two reportable events: a disposal of the first asset and an acquisition of the second, each valued in fiat at execution. There is no fiat leg in the transaction itself, so the valuation has to be sourced. A single Uniswap swap in a customer's history produces two CARF lines, not one — pipelines that treat a swap as one event under-report by construction.

3. Transfers

Movements of crypto to and from the user that are not trades — deposits in, withdrawals out. The reportable distinction is the destination: a transfer to another known CASP is one thing; a transfer to an unhosted wallet must be identified and flagged as such, because that is precisely the visibility gap DAC8 was written to close.

4. Retail payment transactions

Crypto used to pay for goods or services above the CARF threshold, where the CASP processes the payment. Distinct from a plain transfer because of its commercial nature, and easy to mislabel as a generic withdrawal if the payment context is not captured at the point of execution.

The classification is upstream of the report

You cannot reliably reconstruct "was this a payment or a transfer" or "is this destination unhosted" from raw chain data twelve months later. The context that makes classification correct — payment metadata, the counterparty's CASP status at the time, the customer's intent — exists at the moment of execution and decays afterward. The teams that will struggle in 2027 are the ones treating CARF as a year-end export job rather than a tagging discipline applied at transaction time. Classify on the way in, not on the way out.

The Hard Part: Valuation

Every reportable leg needs a fiat value at the time of the transaction. For crypto-to-fiat that value is the fiat leg. For everything else — swaps, transfers, payments — it has to be computed, and that is where defensibility is won or lost:

  • Price source and consistency — which reference price, which venue, which timestamp granularity? The choice must be documented and applied uniformly; the AdE's technical specs will constrain currency-conversion handling, and a programme that valued ad hoc per transaction cannot reproduce its own numbers under audit
  • Timestamp precision — block time vs order time vs settlement time. For a volatile asset, the difference is real money and the methodology has to be fixed in advance
  • Illiquid and long-tail assets — a memecoin or a thin-liquidity token has no clean reference price; the fallback methodology (last trade, pool-implied, zero) is a documented policy choice, not an engineering accident
  • Reproducibility — the same input must produce the same value on re-run two years later, when prices have moved and APIs have changed. Valuations have to be computed-and-stored, not recomputed live at report time

The Other Hard Part: Reconciliation

A customer's true activity is spread across places that don't naturally join:

  • Internal vs on-chain — trades on the CASP's own book may never touch a chain; deposits and withdrawals do. The report needs both, deduplicated, without double-counting an internal transfer that also shows as an on-chain move
  • Cross-chain — the same customer's USDT on Ethereum, TRON, and Solana is one user's position across three ledgers; the extraction has to unify them, which is the same cross-chain reconciliation problem [ongoing monitoring] faces, applied to tax rather than risk
  • Self-transfers — a customer moving funds between their own wallets is not a disposal, but on-chain it is indistinguishable from a transfer to a third party unless the CASP knows both addresses belong to the same user
  • Unhosted attribution — determining whether a destination address is at another CASP or unhosted requires address intelligence the CASP does not generate internally — it has to come from a labelled graph

The Workflow, End to End

  1. Ingest — pull the customer's internal trade/custody ledger and their on-chain deposit/withdrawal history for the reference year, across every chain in scope
  2. Resolve identity — bind activity to the reportable user and their self-certified residence/TIN set; surface entity accounts needing controlling-person breakdown
  3. Reconcile — dedupe internal vs on-chain, unify cross-chain positions, fold self-transfers out of the reportable set
  4. Classify — map each event to one of the four categories; flag unhosted destinations and retail payments using address intelligence
  5. Value — attach a stored, reproducible fiat FMV to every leg under the documented methodology
  6. Aggregate — group to per-user, per-asset, per-category gross amounts, unit counts, and transaction counts, split acquisition/disposal
  7. Format & validate — render to the AdE's schema (once published), validate against it, and retain the underlying working so the aggregates are defensible line by line

How BA Does It

Steps 1 and 3–4 are where BA's tax tooling carries the load. It reconstructs a customer's transaction history across 80+ chains into a single structured timeline — deposits, withdrawals, swaps, and payments unified per user — and resolves destinations against the BA graph of 1B+ labelled addresses, so "is this a CASP or an unhosted wallet" and "do these two addresses belong to the same customer" are answered from data rather than guessed. Crypto-to-crypto swaps are expanded into their two reportable legs, self-transfers are identified and excluded, and every leg is valued with a stored, reproducible fiat figure. The output is the structured per-user, per-asset dataset that sits directly underneath the CARF-format layer — the reconstruction done, so the reporting is a render rather than a rebuild.

CARF Extraction Checklist

  • Classification happens at transaction time, not at year-end — payment/transfer/unhosted context is captured on the way in
  • Crypto-to-crypto swaps expand to two reportable legs, each valued in fiat
  • Every leg carries a stored, reproducible FMV under a documented valuation methodology
  • Internal and on-chain activity is reconciled and deduplicated; self-transfers excluded
  • Cross-chain positions for one user are unified into one reportable view
  • Unhosted-wallet destinations are identified from address intelligence, not assumed
  • Aggregates retain their underlying working, defensible line by line under audit

Next in the series: Tools for Compliance #6 — From On-Chain Trigger to FIU SAR in 48 Hours, where the obligation shifts from periodic reporting to the time-critical path between a monitoring alert and a filed suspicious activity report.

ShareLinkedInX / TwitterTelegram

Reconstruct per-user, per-asset transaction histories across chains in structured form

Screen wallets, monitor entities, and generate compliance reports with 1B+ labeled addresses and 305+ data sources.

See Tax Solutions