OFAC Crypto Address Screening: A Complete Guide for Compliance Teams

·11 min read

OFAC Crypto Address Screening: A Complete Guide for Compliance Teams

Sanctions screening for crypto addresses is now a baseline compliance requirement, not an edge case. This guide covers what OFAC actually requires, how the published sanctions data works technically, and how to build screening into every stage of your customer lifecycle.

This is a practical guide. It assumes you already know OFAC exists and are trying to figure out what you need to implement.

What OFAC Requires from Crypto Businesses

OFAC's jurisdiction under the International Emergency Economic Powers Act (IEEPA) and the Trading with the Enemy Act (TWEA) applies to U.S. persons and, in many programs, to any transaction that "touches" the U.S. financial system. For crypto, "touches the U.S." is interpreted broadly — it includes companies incorporated in the U.S., U.S.-based employees, U.S. investors, and infrastructure hosted in the U.S.

The core legal obligation is simple: you cannot transact with any person or entity on the SDN list. For crypto, this means:

  • You cannot accept deposits from a sanctioned address
  • You cannot send funds to a sanctioned address
  • You cannot provide services (exchange, custody, lending) to an entity that is on the SDN list

The "50% rule" extends this further: any entity that is 50% or more owned (directly or indirectly) by an SDN-listed party is itself blocked, even if that entity isn't explicitly named on the list. This is relevant for crypto because wallets controlled by sanctioned entities may not appear directly on the list.

OFAC doesn't publish a prescriptive technical standard for how to implement screening. What it does is enforce outcomes. If funds flow through your platform to a sanctioned party, you have exposure — whether or not you "knew." The "reason to know" standard applies.

Penalties for Non-Compliance

OFAC penalties range from stern warning letters to eight-figure civil fines. The pattern from recent enforcement actions:

Bittrex (2022): $29.3 million penalty for processing transactions involving users in sanctioned jurisdictions. The violation stemmed from IP address data that Bittrex had but didn't use to screen users.

BitPay (2021): $507,375 penalty for processing transactions where Bitcoin payment invoices included IP addresses in sanctioned jurisdictions. This wasn't about sanctioned addresses — it was about sanctioned locations.

Kraken (2022): $362,158 penalty for providing services to users in Iran.

The common thread: the exchanges had data indicating sanctions exposure and didn't act on it. OFAC's Enforcement Guidelines consider "existence of compliance program" as a mitigating factor — meaning having a compliance program, even an imperfect one, reduces penalties compared to having nothing.

Sanctions screening for crypto addresses is one component of that program. It won't get you to zero risk, but it demonstrates a good-faith effort to comply.

How OFAC Publishes Crypto Addresses

OFAC provides its sanctions data in several formats. For crypto addresses specifically, the most complete source is the SDN Advanced XML format:

https://sanctionslistservice.ofac.treas.gov/downloads/sanctions/1.0/sdn_advanced.xml

The file uses OFAC's 1.0 schema (DistinctParty elements). Crypto addresses appear as Feature elements under a Profile, with FeatureType values like "Digital Currency Address - ETH" or "Digital Currency Address - XBT" (Bitcoin).

A simplified excerpt for a sanctioned Ethereum address looks like this:

<DistinctParty fixedRef="12345">
  <Profile ID="67890">
    <Feature FeatureTypeID="344">
      <!-- FeatureType 344 = "Digital Currency Address - ETH" -->
      <VersionDetail DetailTypeID="1432">
        <Value>0x4f47bc496083c727c5fbe3ce9cdf2b0f6496270c</Value>
      </VersionDetail>
    </Feature>
  </Profile>
  <SanctionsEntry>
    <SanctionsMeasure>
      <Comment>TORNADO_CASH_PROGRAM_IDENTIFIER</Comment>
    </SanctionsMeasure>
  </SanctionsEntry>
</DistinctParty>

The FeatureType ID values (344 for ETH, etc.) map to a separate lookup table in the same XML file. The update cadence is irregular — OFAC doesn't publish on a schedule. New addresses can be added any day of the week. The file is regenerated and replaced in full on each update.

You have two options for consuming this data:

  1. Parse it yourself. Download the XML, parse it with your preferred XML library, extract addresses and chain types, store them in your database. Run this on a cron job every 2 hours (more frequent is unnecessary; OFAC rarely updates multiple times per day).

  2. Use a screening API. Let someone else handle the parsing, validation, and storage, and query against their up-to-date database. This is what Screening API does.

If you're parsing yourself, watch out for these edge cases:

  • USDT appears under "Digital Currency Address - USDT" but can be ERC-20 (Ethereum), TRC-20 (Tron), or Omni Layer (Bitcoin). You need to detect the chain from the address format.
  • Some addresses appear in sdnEntry format (older schema) alongside the DistinctParty format. A complete parser needs to handle both.
  • Monero addresses in the OFAC list include at least one 64-character hex format that doesn't match the standard 95-character format.
  • The program identifier lives in SanctionsMeasure.Comment, not in a dedicated field.

Other Lists You Should Check

OFAC SDN is the baseline. If your business has exposure beyond the U.S., you need more.

EU Consolidated Financial Sanctions List

Published by the European Commission at the External Action Service Financial Sanctions Database (EU FSF). The EU list includes designations under EU sanctions programs — Russia, Iran, North Korea, Belarus, and others. Post-2022, the EU has been more aggressive about adding crypto-specific entries; Garantex's BTC and ETH addresses appear on the EU list.

The EU provides data in XML format via a token-authenticated URL. The token is embedded in an RSS feed and changes periodically.

As of mid-2026, the EU list has about 8 crypto-specific sanctions entries.

UK FCDO Financial Sanctions List

Post-Brexit, the UK maintains its own financial sanctions regime under OFSI (Office of Financial Sanctions Implementation). The UK list often mirrors EU and U.S. designations but is legally separate — you need to check it independently if you serve UK-regulated entities or have UK operations.

The UK publishes a CSV file (not XML). Crypto addresses appear in free-text fields ("Other Information"), not in a dedicated column. You need a regex parser to extract them.

Community and Threat Intelligence Lists

Beyond government sanctions lists, there are community-maintained lists of known bad actors: mixing services, hack-related addresses, phishing wallets. These aren't legally required the way sanctions lists are, but they give you signal about high-risk counterparties. The MyEtherWallet darklist is one example — it includes hundreds of addresses tagged with categories like PHISHING, HACK_EXPLOIT, SCAM.

Screening at Every Stage of the Customer Lifecycle

The most common gap in crypto compliance programs isn't the lack of a sanctions list — it's not screening at enough points in the customer lifecycle.

At Onboarding

When a user creates an account and provides a deposit address, screen it before you credit their account with any funds. This is standard practice for centralized exchanges and applies equally to any business that accepts crypto deposits.

from chainscreen import Client
 
client = Client(api_key="sk_live_your_key_here")
 
def validate_deposit_address(user_id: str, address: str, chain: str):
    result = client.screen(address, chain=chain)
    
    if result.risk_level in ("CRITICAL", "HIGH"):
        # Freeze account, escalate to compliance team
        log_compliance_event(user_id, address, result)
        raise ValueError(f"Address failed sanctions screening: {result.risk_level}")
    
    return result

At Withdrawal

Before processing any outbound transfer, screen the destination address. This is arguably more important than onboarding screening because you're actively sending funds. A blocked outbound transaction at the payment processor or on-chain level is recoverable; having sent funds to a sanctioned address is not.

import { Client } from '@chainscreen/sdk'
 
const client = new Client({ apiKey: 'sk_live_your_key_here' })
 
async function processWithdrawal(userId, toAddress, chain, amount) {
  let screeningResult
  
  try {
    screeningResult = await client.screen(toAddress, chain)
  } catch (err) {
    // API error — fail safe: hold the withdrawal, don't release
    await holdWithdrawal(userId, toAddress, 'screening_error', err.message)
    return
  }
  
  if (!screeningResult.isClean) {
    await flagWithdrawal(userId, toAddress, screeningResult.riskLevel)
    return
  }
  
  await releaseWithdrawal(userId, toAddress, amount)
}

The fail-safe pattern matters: if the screening API returns an error (network timeout, 5xx), you should hold the transaction rather than default to releasing it. The risk of processing a sanctioned transaction is higher than the risk of briefly delaying a legitimate one.

Periodic Re-screening

Addresses that were clean at onboarding may be added to sanctions lists later. OFAC adds new addresses regularly. Your compliance program needs to re-screen existing deposit addresses and known customer wallets against updated lists.

How often? The OFAC list updates irregularly — sometimes multiple times per week, sometimes not for two weeks. A nightly batch re-screen is a reasonable baseline. If you're in a high-risk vertical, twice daily.

# Nightly re-screening job
from chainscreen import Client
 
client = Client(api_key="sk_live_your_key_here")
 
def nightly_rescreen(address_list: list[dict]):
    """address_list: [{"address": "0x...", "chain": "ethereum", "user_id": "..."}]"""
    
    addresses = [{"address": a["address"], "chain": a["chain"]} for a in address_list]
    batch_result = client.screen_batch(addresses)
    
    for i, result in enumerate(batch_result.results):
        if not result.is_clean:
            user_id = address_list[i]["user_id"]
            flag_account_for_review(user_id, result.address, result.risk_level)

What to Do with a Match

When screening returns a CRITICAL result, the steps are:

  1. Freeze the transaction. Don't process the deposit or withdrawal. Don't release funds already credited for that address.
  2. Document everything. Record the address, the result, the timestamp, and what action you took. This audit trail is what you show OFAC if they ever ask.
  3. Escalate to your compliance officer. The compliance team decides whether to file a Suspicious Activity Report (SAR) and whether to block the account.
  4. Check for OFAC license requirements. Some transactions are permitted under OFAC licenses (e.g., transactions for food, medicine, or journalism in certain sanctioned countries). If you think a license might apply, consult legal counsel.
  5. Don't tip off the customer. In some cases, disclosing to the customer that they're on a sanctions list may itself violate regulations. Get legal advice before communicating with the affected customer.

Building It Yourself vs. Using an API

You can build your own OFAC screening pipeline. It requires:

  • A cron job that downloads and parses the OFAC XML every 2 hours
  • Parsers for the EU and UK formats (each is different)
  • Address normalization (EVM addresses are case-insensitive; Tron addresses require checksum validation; Bitcoin has multiple address formats)
  • A validation layer that rejects data with suspicious drops in address count
  • A database schema for storing addresses, run history, and labels
  • Monitoring and alerting if a pipeline run fails

This is a couple of weeks of engineering time to do correctly. The harder part is the ongoing maintenance: when OFAC changes their XML schema (it happened in 2019), when the EU token URL changes, when a new chain needs normalization support.

If your core business isn't compliance data infrastructure, using an API is the obvious trade-off: you get updated data, maintained parsers, and SLA coverage for a monthly fee instead of engineering time and ongoing maintenance.

The break-even point depends on your engineering costs. If a senior engineer costs $150k/year, two weeks of their time to build this plus ongoing maintenance is worth more than the API cost at any paid tier we offer.

What This Guide Doesn't Cover

This guide is about OFAC address screening specifically. There's a lot more to a crypto compliance program:

KYC/AML. Screening wallet addresses is not the same as KYC. You still need identity verification, customer risk scoring, and transaction monitoring. These are separate compliance functions.

Travel Rule. FATF's Travel Rule requires virtual asset service providers to share originator/beneficiary information for transfers above a threshold. This is entirely different from address sanctions screening.

Blockchain analytics. Services like Chainalysis KYT and Elliptic trace the history of funds on-chain — clustering addresses, attributing transactions to known entities, tracking fund flows through mixers. This is a different product category from address sanctions screening. See our comparison of Chainalysis alternatives.

Legal advice. This guide describes how the technology works and what the general compliance landscape looks like. It is not legal advice. If you're designing a compliance program, you need a lawyer, not just an API.


Screening API is a tool, not a compliance program. Results are informational only. You remain responsible for your compliance obligations under applicable law.

Try It

The free OFAC checker lets you test any Ethereum, Bitcoin, or Tron address against the OFAC SDN list instantly — no account required. For multi-jurisdiction screening with a full audit trail, see pricing.