diff --git a/pallets/smith-members/src/lib.rs b/pallets/smith-members/src/lib.rs
index 2a33e783b06c7f7efb3e06c8b04b98efe25af84a..1e09fe8c950c08a4a0f0e334fbd0bdceb3aba94f 100644
--- a/pallets/smith-members/src/lib.rs
+++ b/pallets/smith-members/src/lib.rs
@@ -173,7 +173,6 @@ pub mod pallet {
                 // Write CertsByReceiver
                 issuers_.sort();
                 let issuers_count = issuers_.len();
-                CertsByReceiver::<T>::insert(receiver, issuers_);
                 let smith_status = if issuers_count as u32 >= T::MinCertForMembership::get() {
                     SmithStatus::Smith
                 } else {
@@ -186,6 +185,7 @@ pub mod pallet {
                         expires_on: Some(
                             CurrentSession::<T>::get() + T::InactivityMaxDuration::get(),
                         ),
+                        received_certs: issuers_,
                     },
                 );
                 ExpiresOn::<T>::append(
@@ -196,14 +196,10 @@ pub mod pallet {
         }
     }
 
-    /// maps identity index to smith value
-    #[pallet::storage]
-    pub type CertsByReceiver<T: Config> =
-        StorageMap<_, Twox64Concat, T::IdtyIndex, Vec<T::IdtyIndex>, OptionQuery>;
-
     /// maps identity index to smith status
     #[pallet::storage]
-    pub type Smiths<T: Config> = StorageMap<_, Twox64Concat, T::IdtyIndex, SmithMeta, OptionQuery>;
+    pub type Smiths<T: Config> =
+        StorageMap<_, Twox64Concat, T::IdtyIndex, SmithMeta<T::IdtyIndex>, OptionQuery>;
 
     /// maps session index to possible smith removals
     #[pallet::storage]
@@ -242,6 +238,8 @@ pub mod pallet {
         NotAMember,
     }
 
+    // TODO: refactor with check_* and do_* functions
+
     #[pallet::call]
     impl<T: Config> Pallet<T> {
         #[pallet::call_index(0)]
@@ -270,6 +268,7 @@ pub mod pallet {
                 SmithMeta {
                     status: SmithStatus::Invited,
                     expires_on: Some(new_expires_on),
+                    received_certs: vec![],
                 },
             );
             ExpiresOn::<T>::append(new_expires_on, receiver);
@@ -322,20 +321,22 @@ pub mod pallet {
                 Error::<T>::ReceveirMustAcceptInvitation
             );
 
-            CertsByReceiver::<T>::mutate(receiver, |certs| {
-                let certs = certs.get_or_insert(vec![]);
-                certs.push(issuer);
-                Smiths::<T>::mutate(receiver, |maybe_smith_meta| {
-                    let maybe_smith_meta =
-                        maybe_smith_meta.as_mut().expect("status checked earlier");
-                    // TODO: "as u32" allowed?
-                    maybe_smith_meta.status =
-                        if certs.len() as u32 >= T::MinCertForMembership::get() {
-                            SmithStatus::Smith
-                        } else {
-                            SmithStatus::Pending
-                        };
-                });
+            Smiths::<T>::mutate(receiver, |maybe_smith_meta| {
+                let maybe_smith_meta = maybe_smith_meta.as_mut().expect("status checked earlier");
+                maybe_smith_meta.received_certs.push(issuer);
+                maybe_smith_meta.received_certs.sort();
+                // TODO: "as u32" allowed?
+                maybe_smith_meta.status = if maybe_smith_meta.received_certs.len() as u32
+                    >= T::MinCertForMembership::get()
+                {
+                    SmithStatus::Smith
+                } else {
+                    SmithStatus::Pending
+                };
+                // expiry postponed
+                let new_expires_on = CurrentSession::<T>::get() + T::InactivityMaxDuration::get();
+                maybe_smith_meta.expires_on = Some(new_expires_on);
+                // TODO: unschedule old expiry
             });
 
             Ok(().into())
@@ -405,11 +406,11 @@ impl<T: Config> Pallet<T> {
 
 impl<T: Config> Pallet<T> {
     fn do_is_member(idty_id: &T::IdtyIndex) -> bool {
-        let Some(certifications) = CertsByReceiver::<T>::get(idty_id) else {
+        let Some(smith) = Smiths::<T>::get(idty_id) else {
             return false;
         };
         let mut count = 0u32;
-        for _ in certifications {
+        for _ in smith.received_certs {
             count += 1;
         }
         return count >= T::MinCertForMembership::get();
diff --git a/pallets/smith-members/src/tests.rs b/pallets/smith-members/src/tests.rs
index a88d5e7062f3777c36a91bd47df4cb66c0bede52..3f221551077f321c863fbb5d6a13b6100bfa6bba 100644
--- a/pallets/smith-members/src/tests.rs
+++ b/pallets/smith-members/src/tests.rs
@@ -42,7 +42,6 @@ fn process_to_become_a_smith_and_lose_it() {
     })
     .execute_with(|| {
         // State before
-        assert_eq!(CertsByReceiver::<Runtime>::get(5), None);
         assert_eq!(Smiths::<Runtime>::get(5), None);
         // Try to invite
         assert_ok!(Pallet::<Runtime>::invite_smith(RuntimeOrigin::signed(1), 5));
@@ -51,30 +50,39 @@ fn process_to_become_a_smith_and_lose_it() {
             5
         )));
         // State after
-        assert_eq!(CertsByReceiver::<Runtime>::get(5), None);
         assert_eq!(
-            Smiths::<Runtime>::get(5).unwrap().status,
-            SmithStatus::Pending
+            Smiths::<Runtime>::get(5).unwrap(),
+            SmithMeta {
+                status: SmithStatus::Pending,
+                expires_on: Some(5),
+                received_certs: vec![],
+            }
         );
         // Then certification 1/2
         assert_ok!(Pallet::<Runtime>::certify_smith(
             RuntimeOrigin::signed(1),
             5
         ));
-        assert_eq!(CertsByReceiver::<Runtime>::get(5).unwrap().len(), 1);
         assert_eq!(
-            Smiths::<Runtime>::get(5).unwrap().status,
-            SmithStatus::Pending
+            Smiths::<Runtime>::get(5).unwrap(),
+            SmithMeta {
+                status: SmithStatus::Pending,
+                expires_on: Some(5),
+                received_certs: vec![1],
+            }
         );
         // Then certification 2/2
         assert_ok!(Pallet::<Runtime>::certify_smith(
             RuntimeOrigin::signed(2),
             5
         ));
-        assert_eq!(CertsByReceiver::<Runtime>::get(5).unwrap().len(), 2);
         assert_eq!(
-            Smiths::<Runtime>::get(5).unwrap().status,
-            SmithStatus::Smith
+            Smiths::<Runtime>::get(5).unwrap(),
+            SmithMeta {
+                status: SmithStatus::Smith,
+                expires_on: Some(5),
+                received_certs: vec![1, 2],
+            }
         );
 
         // On session 4 everything if fine
@@ -84,9 +92,9 @@ fn process_to_become_a_smith_and_lose_it() {
         assert_eq!(Smiths::<Runtime>::get(5).is_some(), true);
         // On session 5 no more smiths because of lack of activity
         Pallet::<Runtime>::on_new_session(5);
-        assert_eq!(Smiths::<Runtime>::get(1), None);
-        assert_eq!(Smiths::<Runtime>::get(2), None);
-        assert_eq!(Smiths::<Runtime>::get(5), None);
+        assert_eq!(Smiths::<Runtime>::get(1), None); // TODO: noautoremove (remaining certs)
+        assert_eq!(Smiths::<Runtime>::get(2), None); // TODO: noautoremove (remaining certs)
+        assert_eq!(Smiths::<Runtime>::get(5), None); // TODO: noautoremove (remaining certs)
     });
 }
 
@@ -114,27 +122,38 @@ fn should_have_checks_on_certify() {
     })
     .execute_with(|| {
         // Initially
-        assert_eq!(CertsByReceiver::<Runtime>::iter().count(), 4);
         assert_eq!(
-            Smiths::<Runtime>::get(1).unwrap().status,
-            SmithStatus::Smith
+            Smiths::<Runtime>::get(1).unwrap(),
+            SmithMeta {
+                status: SmithStatus::Smith,
+                expires_on: Some(5),
+                received_certs: vec![2, 3, 4],
+            }
         );
         assert_eq!(
-            Smiths::<Runtime>::get(2).unwrap().status,
-            SmithStatus::Smith
+            Smiths::<Runtime>::get(2).unwrap(),
+            SmithMeta {
+                status: SmithStatus::Smith,
+                expires_on: Some(5),
+                received_certs: vec![3, 4],
+            }
         );
         assert_eq!(
-            Smiths::<Runtime>::get(3).unwrap().status,
-            SmithStatus::Pending
+            Smiths::<Runtime>::get(3).unwrap(),
+            SmithMeta {
+                status: SmithStatus::Pending,
+                expires_on: Some(5),
+                received_certs: vec![4],
+            }
         );
         assert_eq!(
-            Smiths::<Runtime>::get(4).unwrap().status,
-            SmithStatus::Smith
+            Smiths::<Runtime>::get(4).unwrap(),
+            SmithMeta {
+                status: SmithStatus::Smith,
+                expires_on: Some(5),
+                received_certs: vec![1, 2],
+            }
         );
-        assert_eq!(CertsByReceiver::<Runtime>::get(1).unwrap().len(), 3);
-        assert_eq!(CertsByReceiver::<Runtime>::get(2).unwrap().len(), 2);
-        assert_eq!(CertsByReceiver::<Runtime>::get(3).unwrap().len(), 1);
-        assert_eq!(CertsByReceiver::<Runtime>::get(4).unwrap().len(), 2);
 
         // Tries all possible errors
         assert_err!(
@@ -155,10 +174,13 @@ fn should_have_checks_on_certify() {
         );
 
         // #3: state before
-        assert_eq!(CertsByReceiver::<Runtime>::get(3).unwrap().len(), 1);
         assert_eq!(
-            Smiths::<Runtime>::get(3).unwrap().status,
-            SmithStatus::Pending
+            Smiths::<Runtime>::get(3).unwrap(),
+            SmithMeta {
+                status: SmithStatus::Pending,
+                expires_on: Some(5),
+                received_certs: vec![4],
+            }
         );
         // Try to certify #3
         assert_ok!(Pallet::<Runtime>::certify_smith(
@@ -166,10 +188,13 @@ fn should_have_checks_on_certify() {
             3
         ));
         // #3: state after
-        assert_eq!(CertsByReceiver::<Runtime>::get(3).unwrap().len(), 2);
         assert_eq!(
-            Smiths::<Runtime>::get(3).unwrap().status,
-            SmithStatus::Smith
+            Smiths::<Runtime>::get(3).unwrap(),
+            SmithMeta {
+                status: SmithStatus::Smith,
+                expires_on: Some(5),
+                received_certs: vec![1, 4],
+            }
         );
     });
 }
@@ -184,9 +209,8 @@ fn smith_activity_postpones_expiration() {
                 4 => None,
             ],
             2 => btreemap![
+                3 => None,
                 4 => None,
-                4 => None,
-                5 => None,
             ]
         ],
     })
@@ -206,7 +230,8 @@ fn smith_activity_postpones_expiration() {
             Smiths::<Runtime>::get(2),
             Some(SmithMeta {
                 status: SmithStatus::Smith,
-                expires_on: None
+                expires_on: None,
+                received_certs: vec![3, 4],
             })
         );
 
@@ -218,7 +243,8 @@ fn smith_activity_postpones_expiration() {
             Smiths::<Runtime>::get(2),
             Some(SmithMeta {
                 status: SmithStatus::Smith,
-                expires_on: Some(11)
+                expires_on: Some(11),
+                received_certs: vec![3, 4],
             })
         );
         // Still not expired on session 10
@@ -228,7 +254,8 @@ fn smith_activity_postpones_expiration() {
             Smiths::<Runtime>::get(2),
             Some(SmithMeta {
                 status: SmithStatus::Smith,
-                expires_on: Some(11)
+                expires_on: Some(11),
+                received_certs: vec![3, 4],
             })
         );
         // Finally expired on session 11
diff --git a/pallets/smith-members/src/types.rs b/pallets/smith-members/src/types.rs
index f1298055190fa798a3e670ff83a476fc249d30ee..2242b81a6a48f6699100efbb179376bcbae92b8f 100644
--- a/pallets/smith-members/src/types.rs
+++ b/pallets/smith-members/src/types.rs
@@ -24,14 +24,17 @@ use pallet_authority_members::SessionIndex;
 use scale_info::TypeInfo;
 
 /// certification metadata attached to an identity
-#[derive(Encode, Decode, Clone, Copy, PartialEq, Eq, RuntimeDebug, TypeInfo)]
-pub struct SmithMeta {
+#[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo)]
+pub struct SmithMeta<IdtyIndex> {
     /// current status of the smith
     pub status: SmithStatus,
     /// the session at which the smith will expire (for lack of validation activity)
     pub expires_on: Option<SessionIndex>,
+    /// the recertifications received from other smiths
+    pub received_certs: Vec<IdtyIndex>,
 }
 
+// TODO: check what is really used
 /// certification metadata attached to an identity
 #[derive(Encode, Decode, Clone, Copy, PartialEq, Eq, RuntimeDebug, TypeInfo)]
 pub struct SmithCertMeta<BlockNumber: Default> {