diff --git a/Cargo.lock b/Cargo.lock
index c06dcf48392e187fa4869af3cfe7f56968d8dea3..bbedc15e66b4abc0133c32d9704866348e986eda 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -6298,6 +6298,7 @@ dependencies = [
  "maplit",
  "pallet-authority-members",
  "pallet-balances",
+ "pallet-identity",
  "parity-scale-codec",
  "scale-info",
  "serde",
diff --git a/pallets/identity/src/types.rs b/pallets/identity/src/types.rs
index 20120f25c68a99791db7ca3ef76b2d0b26ad0b97..f8bff333c804b2a17f0152703ea267861d45cc0e 100644
--- a/pallets/identity/src/types.rs
+++ b/pallets/identity/src/types.rs
@@ -38,6 +38,7 @@ pub enum IdtyEvent<T: crate::Config> {
     /// removing an identity (unvalidated or revoked)
     // pallet wot removes associated certifications if status is not revoked
     // pallet quota removes associated quota
+    // pallet smith-members exclude smith
     Removed { status: IdtyStatus },
     // TODO add a way to unlink accounts corresponding to revoked or removed identities
 }
diff --git a/pallets/smith-members/Cargo.toml b/pallets/smith-members/Cargo.toml
index 7d09d7dffc06b3dcf433c2d59cd9c6e7924a706d..5ee739b1ecbd8e3c3867d4818d1b9a74e31883dc 100644
--- a/pallets/smith-members/Cargo.toml
+++ b/pallets/smith-members/Cargo.toml
@@ -18,6 +18,7 @@ log = { version = "0.4.17", default-features = false }
 scale-info = { version = "2.1.1", default-features = false, features = ["derive"] }
 serde = { version = "1.0.101", default-features = false, optional = true }
 pallet-authority-members = { path = "../authority-members", default-features = false }
+pallet-identity = { path = "../identity", default-features = false }
 frame-support = { git = 'https://github.com/duniter/substrate', branch = 'duniter-substrate-v0.9.42', default-features = false }
 frame-system = { git = 'https://github.com/duniter/substrate', branch = 'duniter-substrate-v0.9.42', default-features = false }
 pallet-balances = { git = 'https://github.com/duniter/substrate', branch = 'duniter-substrate-v0.9.42', default-features = false }
diff --git a/pallets/smith-members/src/impls.rs b/pallets/smith-members/src/impls.rs
index c3417028b21f708b59dbc39e2c43076e9bcfad4f..1fd68c58f869c03d84fd42f2f9f508166fb7589a 100644
--- a/pallets/smith-members/src/impls.rs
+++ b/pallets/smith-members/src/impls.rs
@@ -1,5 +1,7 @@
 use crate::{Config, CurrentSession, Pallet};
+use frame_support::Parameter;
 use pallet_authority_members::SessionIndex;
+use pallet_identity::IdtyEvent;
 use sp_runtime::traits::Convert;
 
 /// We want to remove a Smith when he is removed from the higher level set of "authorities".
@@ -47,3 +49,20 @@ impl<T: Config> pallet_authority_members::OnNewSession for Pallet<T> {
         Pallet::<T>::do_exclude_expired_smiths(index);
     }
 }
+
+// implement identity event handler
+impl<
+        IdtyIndex: Copy + Parameter,
+        T: Config<IdtyIndex = IdtyIndex> + pallet_identity::Config<IdtyIndex = IdtyIndex>,
+    > pallet_identity::traits::OnIdtyChange<T> for Pallet<T>
+{
+    fn on_idty_change(idty_id: IdtyIndex, idty_event: &IdtyEvent<T>) {
+        match idty_event {
+            // initialize quota on identity creation
+            IdtyEvent::Created { .. } => {}
+            IdtyEvent::Removed { .. } => {
+                Pallet::<T>::do_exclude_removed_wot_member(idty_id);
+            }
+        }
+    }
+}
diff --git a/pallets/smith-members/src/lib.rs b/pallets/smith-members/src/lib.rs
index 90882404d63c7c417842fb012659dbc67a09f3c2..0bffb76319a755133a94aa05f04c32097c0586f1 100644
--- a/pallets/smith-members/src/lib.rs
+++ b/pallets/smith-members/src/lib.rs
@@ -444,36 +444,7 @@ impl<T: Config> Pallet<T> {
                 if let Some(smith_meta) = Smiths::<T>::get(smith) {
                     if let Some(expires_on) = smith_meta.expires_on {
                         if expires_on == at {
-                            let mut lost_certs = vec![];
-                            Smiths::<T>::mutate(smith, |maybe_smith_meta| {
-                                let maybe_smith_meta =
-                                    maybe_smith_meta.as_mut().expect("checked earlier");
-                                maybe_smith_meta.expires_on = None;
-                                maybe_smith_meta.status = SmithStatus::Excluded;
-                                for cert in &maybe_smith_meta.received_certs {
-                                    lost_certs.push(*cert);
-                                }
-                                maybe_smith_meta.received_certs = vec![];
-                                // N.B.: the issued certs are kept in case the smith joins back
-                            });
-                            // We remove the lost certs from their issuer's stock
-                            for lost_cert in lost_certs {
-                                Smiths::<T>::mutate(lost_cert, |maybe_smith_meta| {
-                                    let maybe_smith_meta =
-                                        maybe_smith_meta.as_mut().expect("checked earlier");
-                                    if let Ok(index) =
-                                        maybe_smith_meta.issued_certs.binary_search(&smith)
-                                    {
-                                        maybe_smith_meta.issued_certs.remove(index);
-                                    }
-                                });
-                            }
-                            // Deletion done
-                            T::OnSmithDelete::on_smith_delete(
-                                smith,
-                                SmithRemovalReason::OfflineTooLong,
-                            );
-                            Self::deposit_event(Event::<T>::SmithExcluded { idty_index: smith });
+                            Self::do_exclude_smith(smith, SmithRemovalReason::OfflineTooLong);
                         }
                     }
                 }
@@ -481,6 +452,36 @@ impl<T: Config> Pallet<T> {
         }
     }
 
+    fn do_exclude_removed_wot_member(idty_index: T::IdtyIndex) {
+        Self::do_exclude_smith(idty_index, SmithRemovalReason::LostMembership);
+    }
+
+    fn do_exclude_smith(idty_index: T::IdtyIndex, reason: SmithRemovalReason) {
+        let mut lost_certs = vec![];
+        Smiths::<T>::mutate(idty_index, |maybe_smith_meta| {
+            let maybe_smith_meta = maybe_smith_meta.as_mut().expect("checked earlier");
+            maybe_smith_meta.expires_on = None;
+            maybe_smith_meta.status = SmithStatus::Excluded;
+            for cert in &maybe_smith_meta.received_certs {
+                lost_certs.push(*cert);
+            }
+            maybe_smith_meta.received_certs = vec![];
+            // N.B.: the issued certs are kept in case the smith joins back
+        });
+        // We remove the lost certs from their issuer's stock
+        for lost_cert in lost_certs {
+            Smiths::<T>::mutate(lost_cert, |maybe_smith_meta| {
+                let maybe_smith_meta = maybe_smith_meta.as_mut().expect("checked earlier");
+                if let Ok(index) = maybe_smith_meta.issued_certs.binary_search(&idty_index) {
+                    maybe_smith_meta.issued_certs.remove(index);
+                }
+            });
+        }
+        // Deletion done: notify (authority-members) for cascading
+        T::OnSmithDelete::on_smith_delete(idty_index, reason);
+        Self::deposit_event(Event::<T>::SmithExcluded { idty_index });
+    }
+
     // TODO: return what?
     fn smith_goes_online(idty_index: T::IdtyIndex) {
         if let Some(smith_meta) = Smiths::<T>::get(idty_index) {
diff --git a/pallets/smith-members/src/tests.rs b/pallets/smith-members/src/tests.rs
index caed26b8c17f009badcfa2126d6ebcb1bb2b92f7..405015f2b76bdd38f4a59c6117a27c49faa01285 100644
--- a/pallets/smith-members/src/tests.rs
+++ b/pallets/smith-members/src/tests.rs
@@ -486,3 +486,73 @@ fn invitation_on_non_wot_member() {
         );
     });
 }
+
+#[test]
+fn losing_wot_membership_cascades_to_smith_members() {
+    new_test_ext(GenesisConfig {
+        certs_by_receiver: btreemap![
+            1 => vec![2, 3, 4],
+            2 => vec![3, 4],
+            3 => vec![1, 2],
+            4 => vec![],
+        ],
+    })
+    .execute_with(|| {
+        // State before
+        assert_eq!(
+            Smiths::<Runtime>::get(1),
+            Some(SmithMeta {
+                status: Smith,
+                expires_on: Some(5),
+                issued_certs: vec![3],
+                received_certs: vec![2, 3, 4],
+            })
+        );
+        assert_eq!(
+            Smiths::<Runtime>::get(1).unwrap().issued_certs,
+            Vec::<u64>::from([3])
+        );
+        assert_eq!(
+            Smiths::<Runtime>::get(2).unwrap().issued_certs,
+            Vec::<u64>::from([1, 3])
+        );
+        assert_eq!(
+            Smiths::<Runtime>::get(3).unwrap().issued_certs,
+            Vec::<u64>::from([1, 2])
+        );
+        assert_eq!(
+            Smiths::<Runtime>::get(4).unwrap().issued_certs,
+            Vec::<u64>::from([1, 2])
+        );
+
+        Pallet::<Runtime>::do_exclude_removed_wot_member(1);
+
+        // Excluded
+        assert_eq!(
+            Smiths::<Runtime>::get(1),
+            Some(SmithMeta {
+                status: Excluded,
+                expires_on: None,
+                issued_certs: vec![3],
+                received_certs: vec![],
+            })
+        );
+        // Issued certifications updated for certifiers of 1
+        assert_eq!(
+            Smiths::<Runtime>::get(1).unwrap().issued_certs,
+            Vec::<u64>::from([3])
+        );
+        assert_eq!(
+            Smiths::<Runtime>::get(2).unwrap().issued_certs,
+            Vec::<u64>::from([3])
+        );
+        assert_eq!(
+            Smiths::<Runtime>::get(3).unwrap().issued_certs,
+            Vec::<u64>::from([2])
+        );
+        assert_eq!(
+            Smiths::<Runtime>::get(4).unwrap().issued_certs,
+            Vec::<u64>::from([2])
+        );
+    });
+}