← Console

Document de travail — N'DRI Research Lab. Cas rejouable, chiffres recalculés depuis l'index du 12/10/2026 13:35 UTC. Companion de l'onglet « Sanctions » de blockchain_tracer.html et de sanctions_screen.py. Toute valeur de ce document se rejoue en une commande (§6).


1. Le cas

Un prestataire de services sur actifs virtuels (PSAV/VASP) fictif, Sahel Pay SARL, exploite un service de dépôt et de retrait à Niamey et Abidjan. Chaque mois, le responsable conformité soumet son registre à l'index de sanctions : les adresses qui ont reçu ou émis des fonds, et les noms des contreparties qui se sont déclarées au KYC.

Le registre du mois compte 12 entrées : 8 adresses (6 de contreparties réelles, 2 de test) et 2 noms. L'index de référence est le relevé OFAC SDN + liste consolidée ONU du 12/10/2026 13:35 UTC : 20 426 désignations, 43 282 noms et alias, 505 adresses publiées par les autorités — les fichiers sources étant hashés en SHA-256 (§7).

Deux choses seulement sont réelles ici : les adresses désignées et l'index. Le VASP, ses dépôts et les deux adresses de test sont des constructions pédagogiques, marquées comme telles dans le fichier d'entrée. Un non-résultat sur une chaîne inventée ne prouve rien, ni dans un sens ni dans l'autre.

L'objectif n'est pas de montrer qu'un logiciel trouve des correspondances : c'est de montrer qu'un criblage est un acte de documentation — ce qui est criblé, contre quel index daté, avec quelles règles, et ce qui est décidé ensuite.

2. Les entrées soumises

#BlocValeur cribléeCe qu'elle représente
1A3Lpoy53K625zVeE47ZasiG5jGkAxJ27kh1Depot recu le 2026-10-03
2A0x7FF9cFad3877F21d41Da833E2F775dB0569eE3D9Meme contrepartie, reseau Ethereum
3A0xd882cfc20f52f2599d84b8e8d58c7fb62cfe344bReglement fournisseur
4A12HQDsicffSBaYdJ6BhnE22sfjTESmmzKxContrepartie SUEX OTC
5A3E7YbpXuhh3CWFks1jmvWoV8y5DvsfzE6nContrepartie CHATEX
6A3K4rjdh8A5yi6LWvft2rbmyZvqEbPSSSX4Contrepartie HYDRA MARKET
7B0x5aF00dC0FFEE0000000000000000000000000000Portefeuille chaud (test)
8B1SaheLPayTestAddressNoWaLLetAbc12Adresse de retrait (test)
9CGarantexNom a cribler
10CSahel Pay SARLNom a cribler
11DTFwjPScaJRCbSWVAywE1S1WgaUAnnexe — TRON tronquee
12D1h939dom7i4wdlckygbxup3fs9cstnrzglAnnexe — hors base58

Bloc A : registre interne. Bloc B : chaînes de test, sans portefeuille réel. Bloc C : noms. Bloc D : annexe — deux chaînes publiées par l'OFAC que le filtre de format ne reconnaît pas comme des adresses (traitées au §5.3, avec vérification).

3. Ce que le moteur répond

12 entrées criblées, 8 avec au moins une correspondance, 4 sans. Les 6 adresses de contreparties du bloc A ressortent toutes, sur 5 entités désignées distinctes ; le nom « Garantex » ressort en correspondance exacte d'alias. Les deux adresses de test ne ressortent pas — ce qui ne démontre rien. Les 2 noms du bloc C produisent à eux seuls 9 lignes de correspondance : c'est le piège du §5.2.

#ValeurDétectéVerdictLignesCorrespondances (entité · source/id · niveau · programme)
13Lpoy53K625z…kAxJ27kh1addressMATCH1<b>GARANTEX EUROPE OU</b> (entity) · OFAC/36025 · Address — exact · XBT · RUSSIA-EO14024, CYBER4
20x7FF9cFad38…0569eE3D9addressMATCH1<b>GARANTEX EUROPE OU</b> (entity) · OFAC/36025 · Address — exact · ETH · RUSSIA-EO14024, CYBER4
30xd882cfc20f…62cfe344baddressMATCH2<b>KARASAVIDI, Dmitrii</b> (individual) · OFAC/29585 · Address — exact · ETH · CYBER2<br><b>KARASAVIDI, Dmitrii</b> (individual) · OFAC/29585 · Address — exact · ETC · CYBER2
412HQDsicffSB…jTESmmzKxaddressMATCH1<b>SUEX OTC, S.R.O.</b> (entity) · OFAC/33151 · Address — exact · XBT · CYBER2
53E7YbpXuhh3C…5DvsfzE6naddressMATCH1<b>CHATEX</b> (entity) · OFAC/33854 · Address — exact · XBT · CYBER2
63K4rjdh8A5yi…qEbPSSSX4addressMATCH1<b>HYDRA MARKET</b> (entity) · OFAC/36216 · Address — exact · XBT · CYBER2
70x5aF00dC0FF…000000000addressNO MATCH——
81SaheLPayTes…LLetAbc12addressNO MATCH——
9GarantexnameMATCH1<b>GARANTEX EUROPE OU</b> (entity) · OFAC/36025 · Alias — exact · RUSSIA-EO14024, CYBER4
10Sahel Pay SARLnameMATCH8<b>NEGIN KISH INTERNATIONAL SAHEL AND FARASAHEL DEVELOPMENT</b> (entity) · OFAC/25882 · Name — partial (verify) · IRAN<br><b>NEGIN SAHEL ROYAL INVESTMENT COMPANY</b> (entity) · OFAC/25042 · Name — partial (verify) · SDGT, IFSR<br><b>OMRAN SAHEL</b> (entity) · OFAC/10493 · Name — partial (verify) · SDGT, NPWMD, IRGC<br><b>OMRAN SAHEL</b> (entity) · UN/110356 · Name — partial (verify) · Iran<br><b>RAH SAHEL</b> (entity) · UN/110348 · Name — partial (verify) · Iran<br><b>RAH SAHEL INSTITUTE</b> (entity) · OFAC/12058 · Name — partial (verify) · SDGT, NPWMD, IRGC<br><b>SAHEL CONSULTANT ENGINEERS</b> (entity) · OFAC/10494 · Name — partial (verify) · SDGT, NPWMD, IRGC<br><b>SAHEL CONSULTANT ENGINEERS</b> (entity) · UN/110342 · Name — partial (verify) · Iran
11TFwjPScaJRCbSWVAywE1S1WgaUnameNO MATCH——
121h939dom7i4w…9cstnrzglnameNO MATCH——

Le CSV d'audit (_vpsdata/cas_pratique_vasp_audit.csv) reprend le schéma de l'export de la page — 16 colonnes, une ligne par correspondance, plus une ligne « NO MATCH » par entrée sans résultat — dont index_fingerprint et index_wallets_sha256, qui rattachent chaque ligne à un index précis.

4. Trois décisions

4.1 Geler et déclarer (bloc A)

Les 6 adresses de contreparties correspondent toutes, sur 5 entités désignées distinctes : Garantex Europe OU (deux actifs différents), Karasavidi Dmitrii, SUEX OTC, Chatex et Hydra Market. La contrepartie qui s'était déclarée « Garantex » au KYC est donc confirmée par deux adresses publiées, sur deux réseaux. Décision : gel des fonds, déclaration de soupçon à la CENTIF/ANIF, sans informer la contrepartie (tipping-off), et conservation du CSV d'audit avec son empreinte d'index — c'est cette empreinte qui rend la pièce opposable six mois plus tard.

4.2 Écarter les faux positifs de nom, par écrit (bloc C)

« Sahel Pay SARL » — le VASP lui-même — ressort en 8 correspondances partielles. Aucune n'est le VASP : ce sont des entités iraniennes dont le nom contient le mot « SAHEL » (Omran Sahel, Rah Sahel, Sahel Consultant Engineers…). Le score affiché vaut 1.0 : il mesure le recouvrement de tokens, pas la probabilité d'identité. Décision : pas de gel, mais une ligne de registre qui dit pourquoi le signal a été écarté — c'est la partie du dossier qu'un superviseur demandera.

4.3 Ne rien conclure des non-résultats

Les deux adresses de test ne ressortent pas : c'est sans valeur, elles sont inventées. Et surtout, les deux chaînes de l'annexe ressortent « rien trouvé » alors qu'elles sont dans l'index : le filtre de format ne les reconnaît pas comme des adresses. Un non-résultat n'est ni un blanchiment de conformité, ni une preuve d'absence.

5. Trois pièges que ce cas démontre

5.1 Une adresse, deux actifs : compter les lignes n'est pas compter les entités

0xd882cfc20f52f2599d84b8e8d58c7fb62cfe344b est publiée par l'OFAC sous ETH et ETC. Le moteur renvoie donc deux lignes pour une seule entité (Karasavidi Dmitrii, OFAC/29585). Les 6 adresses du bloc A donnent 7 lignes de correspondance : c'est bien 5 entités qu'il faut traiter, pas 7 dossiers.

5.2 Un mot commun suffit à produire 8 « correspondances »

Le criblage partiel bascule sur un recouvrement de tokens dès qu'aucune similarité n'atteint 0.88. Introduire un nom d'entreprise contenant un mot géographique courant remplit l'écran de résultats à score 1.0. La parade n'est pas de baisser le seuil : c'est de lire les identifiants (source, numéro de désignation, pays, date de naissance) et de consigner le rejet.

5.3 Deux chaînes publiées passent sous le filtre de format

Chaîne cribléeDétectée commeVerdict du moteurPrésente dans l'indexActif publiéEntité(s) désignée(s)Pourquoi le filtre la rate
TFwjPScaJRCbSWVAywE1S1WgaUnameNO MATCHouiTRXGARANTEX EUROPE OU · OFAC/3602526 caracteres : chaine TRON tronquee (34 attendus), aucune famille d'adresse du moteur ne la reconnait
1h939dom7i4wdlckygbxup3fs9cstnrzglnameNO MATCHouiXBTKHATIBI AGHADA, Ahmad · OFAC/38419; NIKAEEN RAVARI, Amir Hossein · OFAC/3842034 caracteres dont un « l » minuscule : hors alphabet base58, donc non reconnue comme adresse

Ces deux chaînes sont conservées dans l'index telles que publiées : l'OFAC écrit parfois une adresse TRON tronquée ou une chaîne hors alphabet base58. Le moteur décide du chemin de criblage d'après le format ; une chaîne non reconnue part au criblage de noms et ne peut pas rencontrer une adresse. La parade est un contrôle d'exactitude sur l'index (l'audit le fait ici) et, à terme, une correction à la source — jamais une correction silencieuse de la donnée publiée.

6. Rejeu

cd _vpsdata
python sanctions_screen.py --file cas_pratique_vasp_wallets.txt   # 12 criblés, 8 avec correspondance, code 2
python build_cas_pratique_vasp.py                                 # réécrit audit JSON/CSV + cette note + la page HTML
node   _test_page_cas.js                                          # vérifie la page publiée contre l'audit

Le code de sortie du criblage suit la convention de grep : 0 = aucune correspondance, 2 = au moins une. Il peut donc servir de verrou dans un script de conformité, à condition de traiter séparément les correspondances partielles de nom.

Côté interface, le même fichier se colle dans l'onglet Sanctions de blockchain_tracer.html (servi en HTTP), puis « Export results (CSV) ». Les deux exports partagent le même schéma de 16 colonnes ; la colonne index_fingerprint doit valoir 531f8b9694d3465e1e17fea4cc2f3ac2… de part et d'autre. C'est le seul contrôle qui prouve que la page et le CLI ont criblé le même index.

7. Ce que ce cas n'établit pas

Annexe — empreintes des fichiers sources

FichierOctetsSHA-256
OFAC_SDN5 727 33364be7a7991059f59a2ebb43bc5dcc7e2951e1e27cbed8cbe41b0231b3a161946
OFAC_ALT1 063 323ff6075fc9635c5034475fa49c0c2e0e03300e1c9375771d75f99c4d4bf799c1b
OFAC_ADD1 685 92626a6030ede37402ba759ce0a8eb9dc08381099a7447ff287b29b227c7826f9a0
UN_CONSOLIDATED2 186 4960687d6d9b6c631d81a6f02579594236912dd655c8bd0e1e25628b2b9babad546

Empreinte de l'index (sha256 des lignes key|sha256|bytes) : 531f8b9694d3465e1e17fea4cc2f3ac2abead9d40c2f87f1e38a0b49c7a54dc5 Empreinte du fichier d'adresses servi à la page : bccea8f88dd0ab5e407836a9c3ffd528b21a237a932243f409338d4bb034173b

Note et page générées ensemble par _vpsdata/build_cas_pratique_vasp.py à partir de cas_pratique_vasp_wallets.txt ; aucune valeur n'est recopiée à la main.