diff --git a/.cargo/config b/.cargo/config
index f5990d7a2483c05d9a105363a6d3abd1d206d8dd..150b66ebd099121b773367ba33b15d07c31f6f6b 100644
--- a/.cargo/config
+++ b/.cargo/config
@@ -3,5 +3,6 @@ cucumber = "test -p duniter-end2end-tests --test cucumber_tests --"
 sanity-gdev = "test -p duniter-live-tests --test sanity_gdev -- --nocapture"
 tu = "test --workspace --exclude duniter-end2end-tests --exclude duniter-live-tests"
 tb = "test --features runtime-benchmarks -p"
+rbp = "run --release --features runtime-benchmarks -- benchmark pallet --chain=dev --steps=50 --repeat=20 --extrinsic=* --execution=wasm --wasm-execution=compiled --heap-pages=4096 --header=./file_header.txt --output=. --pallet"
 xtask = "run --package xtask --"
 
diff --git a/Cargo.toml b/Cargo.toml
index 05b091a4c14e585cf93c0c239cef3d0b79ee79a1..64be16415fa1a83a620f3fb0cfb9eca3e18be558 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -177,7 +177,6 @@ httparse = { opt-level = 3 }
 integer-sqrt = { opt-level = 3 }
 keccak = { opt-level = 3 }
 libm = { opt-level = 3 }
-librocksdb-sys = { opt-level = 3 }
 libsecp256k1 = { opt-level = 3 }
 libz-sys = { opt-level = 3 }
 mio = { opt-level = 3 }
diff --git a/pallets/duniter-wot/src/lib.rs b/pallets/duniter-wot/src/lib.rs
index 1ea7ae1f80d275cc1dfcc51c706ea9600239875a..1ef8df68dba9169eba6d70d3aa47f67416f14fcd 100644
--- a/pallets/duniter-wot/src/lib.rs
+++ b/pallets/duniter-wot/src/lib.rs
@@ -17,9 +17,6 @@
 #![cfg_attr(not(feature = "std"), no_std)]
 #![allow(clippy::type_complexity)]
 
-//pub mod traits;
-mod types;
-
 #[cfg(test)]
 mod mock;
 
@@ -30,14 +27,12 @@ mod tests;
 mod benchmarking;*/
 
 pub use pallet::*;
-pub use types::*;
 
 use frame_support::dispatch::UnfilteredDispatchable;
 use frame_support::pallet_prelude::*;
 use frame_system::RawOrigin;
 use pallet_certification::traits::SetNextIssuableOn;
 use pallet_identity::{IdtyEvent, IdtyStatus};
-use sp_membership::traits::IsInPendingMemberships;
 use sp_runtime::traits::IsMember;
 
 type IdtyIndex = u32;
@@ -102,32 +97,57 @@ pub mod pallet {
 impl<AccountId, T: Config<I>, I: 'static> pallet_identity::traits::EnsureIdtyCallAllowed<T>
     for Pallet<T, I>
 where
-    T: frame_system::Config<AccountId = AccountId>
-        + pallet_membership::Config<I, MetaData = MembershipMetaData<AccountId>>,
+    T: frame_system::Config<AccountId = AccountId> + pallet_membership::Config<I>,
 {
     fn can_create_identity(creator: IdtyIndex) -> bool {
-        let cert_meta = pallet_certification::Pallet::<T, I>::idty_cert_meta(creator);
-        cert_meta.received_count >= T::MinCertForCreateIdtyRight::get()
-            && cert_meta.next_issuable_on <= frame_system::pallet::Pallet::<T>::block_number()
-            && cert_meta.issued_count < T::MaxByIssuer::get()
+        if !T::IsSubWot::get() {
+            let cert_meta = pallet_certification::Pallet::<T, I>::idty_cert_meta(creator);
+            cert_meta.received_count >= T::MinCertForCreateIdtyRight::get()
+                && cert_meta.next_issuable_on <= frame_system::pallet::Pallet::<T>::block_number()
+                && cert_meta.issued_count < T::MaxByIssuer::get()
+        } else {
+            true
+        }
     }
-    fn can_confirm_identity(idty_index: IdtyIndex, owner_key: AccountId) -> bool {
-        pallet_membership::Pallet::<T, I>::force_request_membership(
-            RawOrigin::Root.into(),
-            idty_index,
-            MembershipMetaData(owner_key),
-        )
-        .is_ok()
+    fn can_confirm_identity(idty_index: IdtyIndex) -> bool {
+        if !T::IsSubWot::get() {
+            pallet_membership::Pallet::<T, I>::force_request_membership(
+                RawOrigin::Root.into(),
+                idty_index,
+                Default::default(),
+            )
+            .is_ok()
+        } else {
+            true
+        }
     }
     fn can_validate_identity(idty_index: IdtyIndex) -> bool {
-        // TODO replace this code by te commented one for distance feature
-        /*let idty_cert_meta = pallet_certification::Pallet::<T, I>::idty_cert_meta(idty_index);
-        idty_cert_meta.received_count >= T::MinCertForMembership::get() as u32*/
-        pallet_membership::Pallet::<T, I>::claim_membership(
-            RawOrigin::Root.into(),
-            Some(idty_index),
-        )
-        .is_ok()
+        if !T::IsSubWot::get() {
+            // TODO replace this code by the commented one for distance feature
+            /*let idty_cert_meta = pallet_certification::Pallet::<T, I>::idty_cert_meta(idty_index);
+            idty_cert_meta.received_count >= T::MinCertForMembership::get() as u32*/
+            pallet_membership::Pallet::<T, I>::claim_membership(
+                RawOrigin::Root.into(),
+                Some(idty_index),
+            )
+            .is_ok()
+        } else {
+            true
+        }
+    }
+    fn can_change_identity_address(idty_index: IdtyIndex) -> bool {
+        if T::IsSubWot::get() {
+            !pallet_membership::Pallet::<T, I>::is_member(&idty_index)
+        } else {
+            true
+        }
+    }
+    fn can_remove_identity(idty_index: IdtyIndex) -> bool {
+        if T::IsSubWot::get() {
+            !pallet_membership::Pallet::<T, I>::is_member(&idty_index)
+        } else {
+            true
+        }
     }
 }
 
@@ -141,14 +161,8 @@ impl<T: Config<I>, I: 'static> pallet_certification::traits::IsCertAllowed<IdtyI
             }
             if let Some(receiver_data) = pallet_identity::Pallet::<T>::identity(receiver) {
                 match receiver_data.status {
-                    IdtyStatus::ConfirmedByOwner => true,
+                    IdtyStatus::ConfirmedByOwner | IdtyStatus::Validated => true,
                     IdtyStatus::Created => false,
-                    IdtyStatus::Validated => {
-                        pallet_membership::Pallet::<T, I>::is_member(&receiver)
-                            || pallet_membership::Pallet::<T, I>::is_in_pending_memberships(
-                                receiver,
-                            )
-                    }
                 }
             } else {
                 // Receiver not found
diff --git a/pallets/duniter-wot/src/mock.rs b/pallets/duniter-wot/src/mock.rs
index b94c67dd58bfc9acb6831623d0102177194ac8a8..b32f0b46b7e1c36b27ce7ac04c131f6aa55a6a8e 100644
--- a/pallets/duniter-wot/src/mock.rs
+++ b/pallets/duniter-wot/src/mock.rs
@@ -122,7 +122,7 @@ impl pallet_identity::Config for Test {
     type ChangeOwnerKeyPeriod = ChangeOwnerKeyPeriod;
     type ConfirmPeriod = ConfirmPeriod;
     type Event = Event;
-    type EnsureIdtyCallAllowed = DuniterWot;
+    type EnsureIdtyCallAllowed = (DuniterWot, SmithsSubWot);
     type IdtyCreationPeriod = IdtyCreationPeriod;
     type IdtyData = ();
     type IdtyNameValidator = IdtyNameValidatorTestImpl;
@@ -150,7 +150,7 @@ impl pallet_membership::Config<Instance1> for Test {
     type IdtyId = IdtyIndex;
     type IdtyIdOf = IdentityIndexOf<Self>;
     type MembershipPeriod = MembershipPeriod;
-    type MetaData = crate::MembershipMetaData<u64>;
+    type MetaData = ();
     type OnEvent = DuniterWot;
     type PendingMembershipPeriod = PendingMembershipPeriod;
     type RevocationPeriod = RevocationPeriod;
@@ -206,7 +206,7 @@ impl pallet_membership::Config<Instance2> for Test {
     type IdtyId = IdtyIndex;
     type IdtyIdOf = IdentityIndexOf<Self>;
     type MembershipPeriod = SmithsMembershipPeriod;
-    type MetaData = crate::MembershipMetaData<u64>;
+    type MetaData = ();
     type OnEvent = SmithsSubWot;
     type PendingMembershipPeriod = SmithsPendingMembershipPeriod;
     type RevocationPeriod = SmithsRevocationPeriod;
diff --git a/pallets/duniter-wot/src/tests.rs b/pallets/duniter-wot/src/tests.rs
index bd3fb937c79637ed3d2d32f7a61d27cd78b14911..7e1e8e901c8b8ac93e598a618a634f226f1de6c3 100644
--- a/pallets/duniter-wot/src/tests.rs
+++ b/pallets/duniter-wot/src/tests.rs
@@ -16,11 +16,15 @@
 
 use crate::mock::*;
 use crate::mock::{Identity, System};
-use frame_support::assert_noop;
-use frame_support::assert_ok;
+use codec::Encode;
 use frame_support::instances::Instance1;
+use frame_support::{assert_noop, assert_ok};
 use frame_system::{EventRecord, Phase};
-use pallet_identity::{IdtyName, IdtyStatus};
+use pallet_identity::{
+    IdtyName, IdtyStatus, NewOwnerKeyPayload, RevocationPayload, NEW_OWNER_KEY_PAYLOAD_PREFIX,
+    REVOCATION_PAYLOAD_PREFIX,
+};
+use sp_runtime::testing::TestSignature;
 
 #[test]
 fn test_genesis_build() {
@@ -56,10 +60,7 @@ fn test_join_smiths() {
         run_to_block(2);
 
         // Dave shoud be able to request smith membership
-        assert_ok!(SmithsMembership::request_membership(
-            Origin::signed(4),
-            crate::MembershipMetaData(4)
-        ));
+        assert_ok!(SmithsMembership::request_membership(Origin::signed(4), ()));
         System::assert_has_event(Event::SmithsMembership(
             pallet_membership::Event::MembershipRequested(4),
         ));
@@ -95,6 +96,53 @@ fn test_smith_certs_expirations_should_revoke_smith_membership() {
     });
 }
 
+#[test]
+fn test_smith_member_cant_change_its_idty_address() {
+    new_test_ext(5, 3).execute_with(|| {
+        run_to_block(2);
+
+        let genesis_hash = System::block_hash(0);
+        let new_key_payload = NewOwnerKeyPayload {
+            genesis_hash: &genesis_hash,
+            idty_index: 3u32,
+            old_owner_key: &3u64,
+        };
+
+        // Identity 3 can't change it's address
+        assert_noop!(
+            Identity::change_owner_key(
+                Origin::signed(3),
+                13,
+                TestSignature(13, (NEW_OWNER_KEY_PAYLOAD_PREFIX, new_key_payload).encode())
+            ),
+            pallet_identity::Error::<Test>::NotAllowedToChangeIdtyAddress
+        );
+    });
+}
+
+#[test]
+fn test_smith_member_cant_revoke_its_idty() {
+    new_test_ext(5, 3).execute_with(|| {
+        run_to_block(2);
+
+        let revocation_payload = RevocationPayload {
+            idty_index: 3u32,
+            genesis_hash: System::block_hash(0),
+        };
+
+        // Identity 3 can't change it's address
+        assert_noop!(
+            Identity::revoke_identity(
+                Origin::signed(3),
+                3,
+                3,
+                TestSignature(3, (REVOCATION_PAYLOAD_PREFIX, revocation_payload).encode())
+            ),
+            pallet_identity::Error::<Test>::NotAllowedToRemoveIdty
+        );
+    });
+}
+
 #[test]
 fn test_revoke_smiths_them_rejoin() {
     new_test_ext(5, 4).execute_with(|| {
@@ -109,16 +157,13 @@ fn test_revoke_smiths_them_rejoin() {
         // Dave should not be able to re-request membership before the RevocationPeriod end
         run_to_block(3);
         assert_noop!(
-            SmithsMembership::request_membership(Origin::signed(4), crate::MembershipMetaData(4)),
+            SmithsMembership::request_membership(Origin::signed(4), ()),
             pallet_membership::Error::<Test, crate::Instance2>::MembershipRevokedRecently
         );
 
         // At block #6, Dave shoud be able to request smith membership
         run_to_block(6);
-        assert_ok!(SmithsMembership::request_membership(
-            Origin::signed(4),
-            crate::MembershipMetaData(4)
-        ));
+        assert_ok!(SmithsMembership::request_membership(Origin::signed(4), ()));
 
         // Then, Alice should be able to send a smith cert to Dave
         assert_ok!(SmithsCert::add_cert(Origin::signed(1), 1, 4));
diff --git a/pallets/duniter-wot/src/types.rs b/pallets/duniter-wot/src/types.rs
deleted file mode 100644
index c70663fb2ed8303898e5d0d07593f37feb8619c6..0000000000000000000000000000000000000000
--- a/pallets/duniter-wot/src/types.rs
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright 2021 Axiom-Team
-//
-// This file is part of Substrate-Libre-Currency.
-//
-// Substrate-Libre-Currency is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Affero General Public License as published by
-// the Free Software Foundation, version 3 of the License.
-//
-// Substrate-Libre-Currency is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Affero General Public License for more details.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with Substrate-Libre-Currency. If not, see <https://www.gnu.org/licenses/>.
-
-use crate::IdtyIndex;
-use frame_support::pallet_prelude::*;
-
-#[derive(Clone, Encode, Decode, Eq, PartialEq, RuntimeDebug, TypeInfo)]
-pub struct MembershipMetaData<AccountId>(pub AccountId);
-impl<AccountId: Eq> sp_membership::traits::Validate<AccountId> for MembershipMetaData<AccountId> {
-    fn validate(&self, account_id: &AccountId) -> bool {
-        &self.0 == account_id
-    }
-}
-/*impl From<AccountId> for MembershipMetaData {
-    fn from(account_id: AccountId) -> Self {
-        Self(account_id)
-    }
-}*/
-/*impl Into<AccountId> for MembershipMetaData {
-    fn into(self) -> AccountId {
-        self.0
-    }
-}*/
-
-#[cfg_attr(feature = "std", derive(Debug))]
-#[derive(codec::Decode, codec::Encode, Eq, PartialEq, TypeInfo)]
-pub enum WotDiff {
-    AddNode(IdtyIndex),
-    AddPendingLink(IdtyIndex, IdtyIndex),
-    AddLink(IdtyIndex, IdtyIndex),
-    DelLink(IdtyIndex, IdtyIndex),
-    DisableNode(IdtyIndex),
-}
-
-impl Default for WotDiff {
-    fn default() -> Self {
-        unreachable!()
-    }
-}
diff --git a/pallets/identity/src/lib.rs b/pallets/identity/src/lib.rs
index 77cba1b93f9b73b9a29cfbc3fe717eb5ce09bb2c..feebdbfc7d2252f572b7e7afab7b9f068d41e159 100644
--- a/pallets/identity/src/lib.rs
+++ b/pallets/identity/src/lib.rs
@@ -70,7 +70,8 @@ pub mod pallet {
         type ChangeOwnerKeyPeriod: Get<Self::BlockNumber>;
         /// Because this pallet emits events, it depends on the runtime's definition of an event.
         type Event: From<Event<Self>> + IsType<<Self as frame_system::Config>::Event>;
-        /// Management of the authorizations of the different calls. (The default implementation only allows root)
+        /// Management of the authorizations of the different calls.
+        /// The default implementation allows everything.
         type EnsureIdtyCallAllowed: EnsureIdtyCallAllowed<Self>;
         #[pallet::constant]
         /// Minimum duration between the creation of 2 identities by the same creator
@@ -340,7 +341,7 @@ pub mod pallet {
             if <IdentitiesNames<T>>::contains_key(&idty_name) {
                 return Err(Error::<T>::IdtyNameAlreadyExist.into());
             }
-            if !T::EnsureIdtyCallAllowed::can_confirm_identity(idty_index, who.clone()) {
+            if !T::EnsureIdtyCallAllowed::can_confirm_identity(idty_index) {
                 return Err(Error::<T>::NotAllowedToConfirmIdty.into());
             }
 
@@ -415,6 +416,11 @@ pub mod pallet {
                 Error::<T>::OwnerKeyAlreadyUsed
             );
 
+            ensure!(
+                T::EnsureIdtyCallAllowed::can_change_identity_address(idty_index),
+                Error::<T>::NotAllowedToChangeIdtyAddress
+            );
+
             let block_number = frame_system::Pallet::<T>::block_number();
             let maybe_old_old_owner_key =
                 if let Some((old_owner_key, last_change)) = idty_value.old_owner_key {
@@ -497,6 +503,11 @@ pub mod pallet {
                 Error::<T>::InvalidRevocationKey
             );
 
+            ensure!(
+                T::EnsureIdtyCallAllowed::can_remove_identity(idty_index),
+                Error::<T>::NotAllowedToRemoveIdty
+            );
+
             let genesis_hash = frame_system::Pallet::<T>::block_hash(T::BlockNumber::zero());
             let revocation_payload = RevocationPayload {
                 genesis_hash,
@@ -597,8 +608,12 @@ pub mod pallet {
         InvalidRevocationKey,
         /// Revocation payload signature is invalid
         InvalidRevocationSig,
+        /// Identity not allowed to change address
+        NotAllowedToChangeIdtyAddress,
         /// Not allowed to confirm identity
         NotAllowedToConfirmIdty,
+        /// Not allowed to remove identity
+        NotAllowedToRemoveIdty,
         /// Not allowed to validate identity
         NotAllowedToValidateIdty,
         /// Identity creation period is not respected
diff --git a/pallets/identity/src/traits.rs b/pallets/identity/src/traits.rs
index 0b492553f7c5942a4bf3bd338486c37789988a07..f196bda373a9229a177b4c806d02e879fb746810 100644
--- a/pallets/identity/src/traits.rs
+++ b/pallets/identity/src/traits.rs
@@ -21,18 +21,33 @@ use sp_runtime::traits::Saturating;
 
 pub trait EnsureIdtyCallAllowed<T: Config> {
     fn can_create_identity(creator: T::IdtyIndex) -> bool;
-    fn can_confirm_identity(idty_index: T::IdtyIndex, owner_key: T::AccountId) -> bool;
+    fn can_confirm_identity(idty_index: T::IdtyIndex) -> bool;
     fn can_validate_identity(idty_index: T::IdtyIndex) -> bool;
+    fn can_change_identity_address(idty_index: T::IdtyIndex) -> bool;
+    fn can_remove_identity(idty_index: T::IdtyIndex) -> bool;
 }
 
-impl<T: Config> EnsureIdtyCallAllowed<T> for () {
-    fn can_create_identity(_: T::IdtyIndex) -> bool {
+#[impl_for_tuples(5)]
+#[allow(clippy::let_and_return)]
+impl<T: Config> EnsureIdtyCallAllowed<T> for Tuple {
+    fn can_create_identity(creator: T::IdtyIndex) -> bool {
+        for_tuples!( #( if !Tuple::can_create_identity(creator) { return false; } )* );
+        true
+    }
+    fn can_confirm_identity(idty_index: T::IdtyIndex) -> bool {
+        for_tuples!( #( if !Tuple::can_confirm_identity(idty_index) { return false; } )* );
+        true
+    }
+    fn can_validate_identity(idty_index: T::IdtyIndex) -> bool {
+        for_tuples!( #( if !Tuple::can_validate_identity(idty_index) { return false; } )* );
         true
     }
-    fn can_confirm_identity(_: T::IdtyIndex, _: T::AccountId) -> bool {
+    fn can_change_identity_address(idty_index: T::IdtyIndex) -> bool {
+        for_tuples!( #( if !Tuple::can_change_identity_address(idty_index) { return false; } )* );
         true
     }
-    fn can_validate_identity(_: T::IdtyIndex) -> bool {
+    fn can_remove_identity(idty_index: T::IdtyIndex) -> bool {
+        for_tuples!( #( if !Tuple::can_remove_identity(idty_index) { return false; } )* );
         true
     }
 }
diff --git a/pallets/membership/src/lib.rs b/pallets/membership/src/lib.rs
index 657c4f152931f7f25280536facf2d465075f6354..93ff97dc6aeb1eda2316f1cfcdf01e17443ae930 100644
--- a/pallets/membership/src/lib.rs
+++ b/pallets/membership/src/lib.rs
@@ -72,7 +72,7 @@ pub mod pallet {
         /// Something that give the IdtyId on an account id
         type IdtyIdOf: Convert<Self::AccountId, Option<Self::IdtyId>>;
         /// Optional metadata
-        type MetaData: Parameter + Validate<Self::AccountId>;
+        type MetaData: Default + Parameter + Validate<Self::AccountId>;
         #[pallet::constant]
         /// Maximum life span of a non-renewable membership (in number of blocks)
         type MembershipPeriod: Get<Self::BlockNumber>;
diff --git a/pallets/universal-dividend/src/lib.rs b/pallets/universal-dividend/src/lib.rs
index 78be0ed1da08939ff656b8e4712cd03a427b2b23..faf5749d2fdcf667822228ae045d17364147e28d 100644
--- a/pallets/universal-dividend/src/lib.rs
+++ b/pallets/universal-dividend/src/lib.rs
@@ -398,22 +398,6 @@ pub mod pallet {
         ) -> DispatchResultWithPostInfo {
             Self::do_transfer_ud(origin, dest, value, ExistenceRequirement::KeepAlive)
         }
-
-        #[pallet::weight(T::WeightInfo::force_set_first_eligible_ud())]
-        pub fn force_set_first_eligible_ud(
-            origin: OriginFor<T>,
-            who: T::AccountId,
-            first_eligible_ud: FirstEligibleUd,
-        ) -> DispatchResultWithPostInfo {
-            ensure_root(origin)?;
-
-            T::MembersStorage::try_mutate_exists(&who, |maybe_first_eligible_ud| {
-                if let Some(ref mut first_eligible_ud_) = maybe_first_eligible_ud {
-                    *first_eligible_ud_ = first_eligible_ud;
-                }
-                Ok(().into())
-            })
-        }
     }
 
     // PUBLIC FUNCTIONS
diff --git a/pallets/universal-dividend/src/weights.rs b/pallets/universal-dividend/src/weights.rs
index 9fa338ccfc23e1b1d551108482345d5861b5a767..e3b860880991e7c3aa5e7cd04fb8a67c5d6418e2 100644
--- a/pallets/universal-dividend/src/weights.rs
+++ b/pallets/universal-dividend/src/weights.rs
@@ -26,7 +26,6 @@ pub trait WeightInfo {
     fn claim_uds(n: u32) -> Weight;
     fn transfer_ud() -> Weight;
     fn transfer_ud_keep_alive() -> Weight;
-    fn force_set_first_eligible_ud() -> Weight;
 }
 
 // Insecure weights implementation, use it for tests only!
@@ -83,11 +82,4 @@ impl WeightInfo for () {
             .saturating_add(RocksDbWeight::get().reads(2 as Weight))
             .saturating_add(RocksDbWeight::get().writes(2 as Weight))
     }
-    // Storage: Identity IdentityIndexOf (r:1 w:0)
-    // Storage: Identity Identities (r:1 w:1)
-    fn force_set_first_eligible_ud() -> Weight {
-        (0 as Weight)
-            .saturating_add(RocksDbWeight::get().reads(2 as Weight))
-            .saturating_add(RocksDbWeight::get().writes(1 as Weight))
-    }
 }
diff --git a/runtime/common/src/entities.rs b/runtime/common/src/entities.rs
index aa91be374f60ac4ff81143ba1eda7713610b59e5..1680f7b16abbfd71ae6bf6aa8bc367730d05805d 100644
--- a/runtime/common/src/entities.rs
+++ b/runtime/common/src/entities.rs
@@ -106,6 +106,11 @@ pub struct SmithsMembershipMetaData<SessionKeysWrapper> {
     pub p2p_endpoint: sp_runtime::RuntimeString,
     pub session_keys: SessionKeysWrapper,
 }
+impl<SessionKeysWrapper> Default for SmithsMembershipMetaData<SessionKeysWrapper> {
+    fn default() -> Self {
+        unreachable!()
+    }
+}
 impl<SessionKeysWrapper> sp_membership::traits::Validate<AccountId>
     for SmithsMembershipMetaData<SessionKeysWrapper>
 {
diff --git a/runtime/common/src/handlers.rs b/runtime/common/src/handlers.rs
index 0ada22e65fa5a5b8c231f4058496fda2bf8592ef..3726d216e102866e745c3845c3a051d64b17b2a0 100644
--- a/runtime/common/src/handlers.rs
+++ b/runtime/common/src/handlers.rs
@@ -75,18 +75,15 @@ where
 
 pub struct OnMembershipEventHandler<Inner, Runtime>(core::marker::PhantomData<(Inner, Runtime)>);
 
-type MembershipMetaData = pallet_duniter_wot::MembershipMetaData<AccountId>;
-
 impl<
-        Inner: sp_membership::traits::OnEvent<IdtyIndex, MembershipMetaData>,
+        Inner: sp_membership::traits::OnEvent<IdtyIndex, ()>,
         Runtime: frame_system::Config<AccountId = AccountId>
             + pallet_identity::Config<IdtyData = IdtyData, IdtyIndex = IdtyIndex>
-            + pallet_membership::Config<Instance1, MetaData = MembershipMetaData>
+            + pallet_membership::Config<Instance1, MetaData = ()>
             + pallet_universal_dividend::Config,
-    > sp_membership::traits::OnEvent<IdtyIndex, MembershipMetaData>
-    for OnMembershipEventHandler<Inner, Runtime>
+    > sp_membership::traits::OnEvent<IdtyIndex, ()> for OnMembershipEventHandler<Inner, Runtime>
 {
-    fn on_event(membership_event: &sp_membership::Event<IdtyIndex, MembershipMetaData>) -> Weight {
+    fn on_event(membership_event: &sp_membership::Event<IdtyIndex, ()>) -> Weight {
         (match membership_event {
             sp_membership::Event::MembershipRevoked(idty_index) => {
                 if let Some(idty_value) = pallet_identity::Identities::<Runtime>::get(idty_index) {
diff --git a/runtime/common/src/pallets_config.rs b/runtime/common/src/pallets_config.rs
index 45d53fa5437a9741b5b5541c9c9264fec0d5e2df..7bf469f49c270c73f436fb359c13c5891667bafd 100644
--- a/runtime/common/src/pallets_config.rs
+++ b/runtime/common/src/pallets_config.rs
@@ -430,7 +430,7 @@ macro_rules! pallets_config {
 			type ChangeOwnerKeyPeriod = ChangeOwnerKeyPeriod;
             type ConfirmPeriod = ConfirmPeriod;
             type Event = Event;
-            type EnsureIdtyCallAllowed = Wot;
+            type EnsureIdtyCallAllowed = (Wot, SmithsSubWot);
             type IdtyCreationPeriod = IdtyCreationPeriod;
 			type IdtyData = IdtyData;
             type IdtyIndex = IdtyIndex;
@@ -451,7 +451,7 @@ macro_rules! pallets_config {
             type IdtyId = IdtyIndex;
             type IdtyIdOf = common_runtime::providers::IdentityIndexOf<Self>;
             type MembershipPeriod = MembershipPeriod;
-            type MetaData = pallet_duniter_wot::MembershipMetaData<AccountId>;
+            type MetaData = ();
             type OnEvent = OnMembershipEventHandler<Wot, Runtime>;
             type PendingMembershipPeriod = PendingMembershipPeriod;
             type RevocationPeriod = frame_support::traits::ConstU32<0>;
diff --git a/runtime/common/src/weights/pallet_universal_dividend.rs b/runtime/common/src/weights/pallet_universal_dividend.rs
index d5b7bfcab636af7d843cc7412084ec622578e445..9c9efb8f91e8e234a80a53cd082edf33c3668d3c 100644
--- a/runtime/common/src/weights/pallet_universal_dividend.rs
+++ b/runtime/common/src/weights/pallet_universal_dividend.rs
@@ -96,11 +96,4 @@ impl<T: frame_system::Config> pallet_universal_dividend::WeightInfo for WeightIn
 			.saturating_add(T::DbWeight::get().reads(2 as Weight))
 			.saturating_add(T::DbWeight::get().writes(2 as Weight))
 	}
-    // Storage: Identity IdentityIndexOf (r:1 w:0)
-    // Storage: Identity Identities (r:1 w:1)
-    fn force_set_first_eligible_ud() -> Weight {
-        (57_000_000 as Weight)
-            .saturating_add(T::DbWeight::get().reads(2 as Weight))
-            .saturating_add(T::DbWeight::get().writes(1 as Weight))
-    }
 }
diff --git a/runtime/gdev/src/lib.rs b/runtime/gdev/src/lib.rs
index e010fc67c60d1ca5231a3f51791c56a7553e8026..798fe3daea02c1224f62561ec0722eb95b5b1a82 100644
--- a/runtime/gdev/src/lib.rs
+++ b/runtime/gdev/src/lib.rs
@@ -28,6 +28,8 @@ extern crate frame_benchmarking;
 
 pub mod parameters;
 
+mod migrations_v400;
+
 pub use self::parameters::*;
 pub use common_runtime::{
     constants::*, entities::*, handlers::*, AccountId, Address, Balance, BlockNumber,
@@ -127,6 +129,7 @@ pub type Executive = frame_executive::Executive<
     frame_system::ChainContext<Runtime>,
     Runtime,
     AllPalletsWithSystem,
+    migrations_v400::MigrationsV400,
 >;
 
 pub type TechnicalCommitteeInstance = Instance2;
diff --git a/runtime/gdev/src/migrations_v400.rs b/runtime/gdev/src/migrations_v400.rs
new file mode 100644
index 0000000000000000000000000000000000000000..fb82240168ba0bc64a6a1e8f95ba90a30faf8ab9
--- /dev/null
+++ b/runtime/gdev/src/migrations_v400.rs
@@ -0,0 +1,45 @@
+// Copyright 2021-2022 Axiom-Team
+//
+// This file is part of Duniter-v2S.
+//
+// Duniter-v2S is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as published by
+// the Free Software Foundation, version 3 of the License.
+//
+// Duniter-v2S is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with Duniter-v2S. If not, see <https://www.gnu.org/licenses/>.
+
+use crate::*;
+
+pub struct MigrationsV400;
+impl frame_support::traits::OnRuntimeUpgrade for MigrationsV400 {
+    fn on_runtime_upgrade() -> Weight {
+        let mut weight = 1_000_000_000; // Safety margin
+
+        type OldvalueType = AccountId;
+
+        pallet_membership::PendingMembership::<Runtime, Instance1>::translate_values(
+            |_: OldvalueType| {
+                weight += <Runtime as frame_system::Config>::DbWeight::get().write;
+                Some(())
+            },
+        );
+
+        weight
+    }
+
+    #[cfg(feature = "try-runtime")]
+    fn pre_upgrade() -> Result<(), &'static str> {
+        Ok(())
+    }
+
+    #[cfg(feature = "try-runtime")]
+    fn post_upgrade() -> Result<(), &'static str> {
+        Ok(())
+    }
+}