Category: XML Templates Last Updated: 2026-02-12 Applies To: EU DAC8 / OECD CARF XML Schema
---
Overview
Under DAC8/CARF, crypto-asset transfers are a distinct reportable transaction type. The CARF framework defines a Transfer (Section IV.C.4) as a transaction that moves a Relevant Crypto-Asset from or to the Crypto-Asset address or account of a Crypto-Asset User, excluding movements between accounts maintained by the same RCASP for the same user. This covers both outbound transfers (withdrawals to external wallets) and inbound transfers (deposits from external sources, airdrops, staking income).
This article covers when transfers must be reported, how to determine their value, and the XML encoding requirements.
What Qualifies as a Reportable Transfer
A transfer is reportable when a crypto-asset is moved from the RCASP's custody to an address or wallet that is not controlled by the same RCASP. Specifically:
Reportable
- Withdrawal to an external blockchain address (non-custodial wallet)
- Transfer to another exchange or custodian
- Transfer to a wallet controlled by a different entity, even if it is also an RCASP
Not Reportable
- Internal transfers between the user's sub-accounts on the same platform
- Transfers between wallets that are both controlled by the same RCASP (e.g., hot wallet to cold wallet movements)
- Failed or cancelled withdrawal requests that were never broadcast to the blockchain
> Note: The distinction hinges on whether the receiving address is controlled by the same RCASP. If you operate multiple platforms that share a single RCASP registration, internal transfers between those platforms may not be reportable. Consult local guidance if your corporate structure is complex.
Value Determination
Unlike crypto-to-fiat transactions where the fiat amount is known, transfers require the RCASP to determine the fair market value (FMV) of the crypto-asset at the time of the transfer.
How to Calculate Transfer Value
- Determine the quantity of crypto-asset transferred
- Obtain the market price of the crypto-asset at the time of the transfer
- Convert to reporting currency if the price is in a non-reporting currency
Example
User withdraws 1.5 ETH to an external wallet on 2025-08-20 at 10:15 UTC
ETH market price at 10:15 UTC: 1,850.00 EUR
Transfer value = 1.5 * 1,850.00 = 2,775.00 EUR
Price at Time of Transfer
Use the market price at the time the transfer is initiated (or confirmed), not the time the blockchain transaction is mined. The relevant moment is when the RCASP processes the withdrawal request. If there is a material delay between initiation and on-chain confirmation, use the initiation time.
If your platform does not have a direct fiat price for the asset, use an external price feed. Document the source.
Threshold Rules
The OECD CARF framework may apply different reporting requirements based on the value or nature of transfers. Key considerations:
- De minimis thresholds: Some jurisdictions may exempt transfers below a certain value from reporting. However, under the base CARF framework, all transfers to non-RCASP wallets are reportable regardless of amount.
- Aggregate reporting: Even if individual transfers are small, the aggregate for the year is what appears in the report. Many small transfers can add up to significant values.
> Caution: Do not assume a de minimis threshold exists unless your specific jurisdiction has explicitly published one. The safest approach is to report all qualifying transfers.
Network Fees (Gas Fees)
When a user withdraws crypto-assets, a network fee (gas fee) is typically deducted. The question is whether to report the gross amount (before fees) or the net amount (after fees).
| Approach | Value Reported |
|---|---|
| Gross (before network fee) | The full amount the user initiated for withdrawal |
| Net (after network fee) | The amount actually received at the destination address |
Example:
User requests withdrawal of 1.0 ETH
Network fee: 0.005 ETH
Amount received at destination: 0.995 ETH
The CARF framework focuses on the value that leaves the RCASP's control. Reporting the gross amount (1.0 ETH) is arguably more accurate from the RCASP's perspective, since that is the total amount debited from the user's account. However, follow your jurisdiction's specific guidance if available.
XML Encoding
Transfer Transaction Summary
<TransactionSummary>
<TransactionType>TRANSFER</TransactionType>
<NumberOfTransactions>8</NumberOfTransactions>
<AggregateTransferValue currCode="EUR">12500.00</AggregateTransferValue>
<CryptoAssetDetails>
<AssetCode>BTC</AssetCode>
<TotalUnits>0.42000000</TotalUnits>
</CryptoAssetDetails>
</TransactionSummary>
Note that transfers use AggregateTransferValue rather than AggregateGrossProceeds. This is a distinct element in the schema that applies specifically to transfer transactions.
Multiple Asset Transfers
If a user transfers both BTC and ETH to external wallets, create separate TransactionSummary blocks:
<TransactionSummary>
<TransactionType>TRANSFER</TransactionType>
<NumberOfTransactions>5</NumberOfTransactions>
<AggregateTransferValue currCode="EUR">8000.00</AggregateTransferValue>
<CryptoAssetDetails>
<AssetCode>BTC</AssetCode>
<TotalUnits>0.25000000</TotalUnits>
</CryptoAssetDetails>
</TransactionSummary>
<TransactionSummary>
<TransactionType>TRANSFER</TransactionType>
<NumberOfTransactions>3</NumberOfTransactions>
<AggregateTransferValue currCode="EUR">4500.00</AggregateTransferValue>
<CryptoAssetDetails>
<AssetCode>ETH</AssetCode>
<TotalUnits>2.50000000</TotalUnits>
</CryptoAssetDetails>
</TransactionSummary>
Identifying External Transfers
A practical challenge is determining whether a withdrawal destination is external or internal. Methods include:
Address Whitelisting
Maintain a list of all blockchain addresses controlled by your RCASP. Any withdrawal to an address not on this list is an external transfer.
SELECT w.*
FROM withdrawals w
WHERE w.destination_address NOT IN (
SELECT address FROM platform_controlled_addresses
)
AND w.status = 'COMPLETED'
AND w.executed_at >= '2026-01-01'
AND w.executed_at < '2027-01-01';
Destination Tagging
Some platforms tag withdrawals based on destination type during the withdrawal flow. For example:
EXTERNAL_WALLET-- user's own non-custodial walletOTHER_EXCHANGE-- transfer to another exchangeINTERNAL-- transfer to another account on the same platform
Use these tags to filter reportable transfers.
Aggregation Example
SELECT
w.user_id,
w.crypto_asset,
COUNT(*) AS num_transactions,
ROUND(SUM(w.amount * p.price_eur), 2) AS aggregate_transfer_value_eur,
SUM(w.amount) AS total_units
FROM withdrawals w
JOIN price_snapshots p
ON p.asset = w.crypto_asset
AND p.snapshot_time = w.executed_at
WHERE w.destination_type != 'INTERNAL'
AND w.status = 'COMPLETED'
AND w.executed_at >= '2026-01-01T00:00:00Z'
AND w.executed_at < '2027-01-01T00:00:00Z'
GROUP BY w.user_id, w.crypto_asset;
Common Pitfalls
- Forgetting to exclude internal transfers. Transfers between accounts on the same platform should not be reported as external transfers.
- Using incorrect price timing. Use the price at the time of transfer initiation, not the blockchain confirmation time.
- Mixing up AggregateTransferValue and AggregateGrossProceeds. The schema uses different elements for transfers vs. exchanges. Using the wrong element will fail validation.
- Not reporting small transfers. Unless your jurisdiction explicitly provides a de minimis threshold, all external transfers must be included in the aggregate, regardless of individual size.
- Forgetting inbound transfers. Under CARF, both inbound and outbound transfers are reportable. Section II.A.3(g) covers "Transfers to the Reportable User" (inbound, e.g., deposits from external wallets) and Section II.A.3(h) covers "Transfers by the Reportable User" (outbound, e.g., withdrawals to external wallets). Both directions must be reported separately in the XML.
Need help with DAC8 reporting?
Our team handles XML generation, TIN validation, and submission for CASPs across all 27 EU Member States.