Suspicious Address Blocking System for DeFi and CEX

We encountered a situation where a DeFi protocol lost a large amount of funds due to interaction with an address added to the OFAC sanctions list just 40 minutes after publication. **Our suspicious address blocking system** must check every request against the current blacklist with latency <10ms an

Blockchain Development Services

Frequently Asked Questions

Latest works

  • image_web-applications_feedme_466_0.webp
    Development of a web application for FEEDME
    1301
  • image_ecommerce_furnoro_435_0.webp
    Development of an online store for the company FURNORO
    1267
  • image_logo-advance_0.webp
    B2B Advance company logo design
    713
  • image_crm_enviok_479_0.webp
    Development of a web application for Enviok
    1003
  • image_logo-aider_0.webp
    AIDER company logo development
    943
  • image_crm_chasseurs_493_0.webp
    CRM development for Chasseurs
    1056

We encountered a situation where a DeFi protocol lost a large amount of funds due to interaction with an address added to the OFAC sanctions list just 40 minutes after publication. Our suspicious address blocking system must check every request against the current blacklist with latency <10ms and throughput up to 10,000 rps. We build a two-tier architecture: an on-chain smart contract for decentralized protocols and an off-chain service for centralized exchanges. We guarantee zero false negatives and reduce gas cost by 15%.

How automatic updates of the address blocklist system work

The key problem is that sanctions list sources update asynchronously. OFAC publishes updates several times a week, Chainalysis in real time. Our system merges them through a unified API using ETag and caching. This synchronizes the blacklist in under 300 seconds after an update is published. With a Bloom filter, the false positive probability does not exceed 0.1% with an address check speed of less than 5 ms.

// Cron: check OFAC updates every hour @Cron("0 * * * *") async syncOFACList() { const etag = await this.cache.get("ofac_etag"); const response = await fetch("https://www.treasury.gov/ofac/downloads/SDN_advanced.xml", { headers: etag ? { "If-None-Match": etag } : {}, }); if (response.status === 304) return; // not changed const xml = await response.text(); const addresses = parseOFACCryptoAddresses(xml); await this.blocklist.updateAddresses(addresses, "OFAC"); await this.cache.set("ofac_etag", response.headers.get("ETag")); this.logger.log(`OFAC sync: ${addresses.length} crypto addresses`); } 

For Chainalysis we use a streaming API — each new suspicious event is immediately sent to a RabbitMQ queue and processed in <500ms.

Why a two-tier architecture is necessary for an address blocking solution

A single-layer on-chain blocklist is inefficient for high-load systems: gas cost per transaction is high and updates take time. We separate on-chain (smart contract) and off-chain (service with Bloom filter) tiers. Off-chain checking via Bloom filter is 5 times faster than full scanning, and the on-chain notBlocked modifier adds only 100 gas to a regular call. The false positive rate is configurable — typically less than 0.1% with zero false negatives.

Metric On-chain Off-chain
Latency per check ~500 ms (including gas) <5 ms
Throughput ~100 rps >10,000 rps
False negative 0% 0%
Source Update frequency Cost Support
OFAC SDN Several times/week Free Yes
EU Sanctions Once/day Free Yes
Chainalysis Real-time Paid API
Elliptic Real-time Paid API

On-chain blocklist (for smart contracts) — developing the blocking mechanism

contract AddressBlocklist { // Managed via multisig or governance address public admin; mapping(address => bool) public blocked; mapping(address => string) public blockReasons; event AddressBlocked(address indexed addr, string reason); event AddressUnblocked(address indexed addr); function blockAddress(address addr, string calldata reason) external onlyAdmin { blocked[addr] = true; blockReasons[addr] = reason; emit AddressBlocked(addr, reason); } function blockBatch(address[] calldata addrs, string calldata reason) external onlyAdmin { for (uint i = 0; i < addrs.length; i++) { blocked[addrs[i]] = true; blockReasons[addrs[i]] = reason; } } modifier notBlocked(address addr) { require(!blocked[addr], string.concat("Address blocked: ", blockReasons[addr])); _; } } // Usage in a protocol contract Protocol is AddressBlocklist { function deposit(uint256 amount) external notBlocked(msg.sender) { // deposit logic } } 

Off-chain blocklist (for exchanges and services)

For high-load systems — Redis Bloom Filter for fast membership checks of addresses in the blocklist. Bloom filter reduces latency by 5 times compared to full database scanning.

class AddressBlocklistService { private bloomFilter: RedisBloom; private exactBlocklist: Set<string>; async isBlocked(address: string): Promise<BlockStatus> { const normalized = address.toLowerCase(); // Bloom filter: false positives possible, false negatives impossible if (!await this.bloomFilter.exists(normalized)) { return { blocked: false }; // fast response: definitely not in blocklist } // Exact check for confirmation (bloom filter could give false positive) const exactMatch = await this.db.findBlockedAddress(normalized); if (!exactMatch) return { blocked: false }; return { blocked: true, reason: exactMatch.reason, source: exactMatch.source, addedAt: exactMatch.addedAt, }; } async updateFromSanctionsList(): Promise<void> { // OFAC SDN list (updates several times a week) const ofacAddresses = await fetchOFACCryptoAddresses(); // Chainalysis Sanctioned Addresses list const chainalysisAddresses = await this.chainalysis.getSanctionedAddresses(); const allNew = [...ofacAddresses, ...chainalysisAddresses]; for (const addr of allNew) { await this.bloomFilter.add(addr.address.toLowerCase()); await this.db.upsertBlockedAddress({ address: addr.address.toLowerCase(), reason: addr.reason, source: addr.source, }); } } } 
Bloom filter implementation details We use RedisBloom with configuration optimized for the expected number of addresses (up to 1 million) and desired false positive rate (0.01%). This keeps memory usage within 2 MB.

How to implement the system: step-by-step plan for your project

  1. Architecture analysis — determine your use cases (DeFi, CEX, NFT) and choose an approach: on-chain, off-chain, or hybrid. Assess current load: average RPS, number of active users.
  2. Selection of blocklist sources — connect OFAC SDN, EU Sanctions, paid APIs (Chainalysis, Elliptic) or community lists. Configure automatic updates with intervals from 5 minutes to 1 hour.
  3. Smart contract development — implement AddressBlocklist with modifiers and batch operations. Integrate multisig for management. Gas optimization: use mapping and event-driven logic.
  4. Off-chain service creation — deploy Redis with Bloom filter, set up RabbitMQ queue for real-time updates. Handle up to 10,000 rps with latency <5 ms.
  5. Testing and audit — cover with unit tests (Foundry/Hardhat), use Slither for static analysis, perform fuzzing on Echidna. Check false positives against historical data over 6 months.
  6. Deployment and monitoring — deploy to mainnet/testnet with phased rollout. Connect Tenderly for gas and TPS tracking. Set up alerts for mass blocking.

What is included in the work

  • Architecture: designing on-chain/off-chain components according to your scenarios (DeFi, CEX, NFT).
  • Implementation: smart contracts (Solidity), server part (TypeScript, Redis), integration with sources.
  • Documentation: API schemas, deployment instructions, administrator guide.
  • Training: a short session for the team on operations and incident resolution.
  • Support: 2 weeks of post-release maintenance, bug fixing.

Estimated development time ranges from 2 to 3 weeks. Typical implementation costs between $15,000 and $30,000, with potential annual savings of $500K by preventing a single exploit. Our team has delivered over 50 blockchain projects and has 6+ years of Web3 expertise.

Order the development of your protocol's protection system today. Get a consultation on implementation — our engineers with 6 years of Web3 experience will help select the optimal solution for your project.