diff --git a/Cargo.lock b/Cargo.lock
index 728e250212d551b350cf815c5ba3077a52436c50..2e3ce8e0ec89b8b0e4c8cdf1c353c6e5fb494362 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -9790,6 +9790,7 @@ name = "sp-membership"
 version = "3.0.0"
 dependencies = [
  "frame-support",
+ "impl-trait-for-tuples",
  "parity-scale-codec",
  "scale-info",
  "serde",
diff --git a/docs/api/runtime-calls.md b/docs/api/runtime-calls.md
index f6b99dfcd839856470772b646d0a216e0f27919e..e15a49ff9e7cf075fa9aab540e9d9c310ebdbbe9 100644
--- a/docs/api/runtime-calls.md
+++ b/docs/api/runtime-calls.md
@@ -13,7 +13,7 @@ through on-chain governance mechanisms.
 
 ## User calls
 
-There are **80** user calls from **23** pallets.
+There are **78** user calls from **23** pallets.
 
 ### Account - 1
 
@@ -642,18 +642,6 @@ Confirm the creation of an identity and give it a name
 
 The identity must have been created using `create_identity` before it can be confirmed.
 
-#### validate_identity - 2
-
-<details><summary><code>validate_identity(idty_index)</code></summary>
-
-```rust
-idty_index: T::IdtyIndex
-```
-</details>
-
-
-validate the owned identity (must meet the main wot requirements)
-
 #### change_owner_key - 3
 
 <details><summary><code>change_owner_key(new_key, new_key_sig)</code></summary>
@@ -694,20 +682,6 @@ Revoke an identity using a revocation signature
 
 Any signed origin can execute this call.
 
-#### force_remove_identity - 5
-
-<details><summary><code>force_remove_identity(idty_index, idty_name, reason)</code></summary>
-
-```rust
-idty_index: T::IdtyIndex
-idty_name: Option<IdtyName>
-reason: IdtyRemovalReason<T::IdtyRemovalOtherReason>
-```
-</details>
-
-
-remove an identity from storage
-
 #### fix_sufficients - 7
 
 <details><summary><code>fix_sufficients(owner_key, inc)</code></summary>
@@ -746,7 +720,6 @@ Link an account to an identity
 
 
 claim membership
-a pending membership should exist
 it must fullfill the requirements (certs, distance)
 for main wot claim_membership is called automatically when validating identity
 for smith wot, it means joining the authority members
@@ -762,6 +735,18 @@ for smith wot, it means joining the authority members
 
 extend the validity period of an active membership
 
+#### revoke_membership - 3
+
+<details><summary><code>revoke_membership()</code></summary>
+
+```rust
+```
+</details>
+
+
+revoke an active membership
+(only available for sub wot, automatic for main wot)
+
 ### Cert - 43
 
 #### add_cert - 0
@@ -840,18 +825,6 @@ Removes the status if `status` is `None`.
 
 ### SmithMembership - 52
 
-#### request_membership - 0
-
-<details><summary><code>request_membership()</code></summary>
-
-```rust
-```
-</details>
-
-
-submit a membership request (must have a declared identity)
-(only available for sub wot, automatic for main wot)
-
 #### claim_membership - 1
 
 <details><summary><code>claim_membership()</code></summary>
@@ -862,7 +835,6 @@ submit a membership request (must have a declared identity)
 
 
 claim membership
-a pending membership should exist
 it must fullfill the requirements (certs, distance)
 for main wot claim_membership is called automatically when validating identity
 for smith wot, it means joining the authority members
@@ -1909,7 +1881,7 @@ The dispatch origin for this call must be _Root_.
 
 ## Disabled calls
 
-There are **6** disabled calls from **3** pallets.
+There are **4** disabled calls from **2** pallets.
 
 ### System - 0
 
@@ -1985,29 +1957,3 @@ usually means being a stash account).
 - `O(1)` in number of key types. Actual cost depends on the number of length of
   `T::Keys::key_ids()` which is fixed.
 
-### Membership - 42
-
-#### request_membership - 0
-
-<details><summary><code>request_membership()</code></summary>
-
-```rust
-```
-</details>
-
-
-submit a membership request (must have a declared identity)
-(only available for sub wot, automatic for main wot)
-
-#### revoke_membership - 3
-
-<details><summary><code>revoke_membership()</code></summary>
-
-```rust
-```
-</details>
-
-
-revoke an active membership
-(only available for sub wot, automatic for main wot)
-
diff --git a/docs/api/runtime-errors.md b/docs/api/runtime-errors.md
index 1bb46f09033348fe3a2d02adca743258857fead5..5feb1cf038c4e5e5ae19be103634e356ec1b6515 100644
--- a/docs/api/runtime-errors.md
+++ b/docs/api/runtime-errors.md
@@ -1,6 +1,6 @@
 # Runtime errors
 
-There are **178** errors from **37** pallets.
+There are **186** errors from **37** pallets.
 
 <ul>
 <li>System - 0
@@ -638,77 +638,105 @@ Insufficient certifications received to claim membership.
 <li>
 <details>
 <summary>
-<code>DistanceNotOk</code> - 1</summary>
-Distance has not received a positive evaluation.
+<code>DistanceIsInvalid</code> - 1</summary>
+Distance is invalid.
 </details>
 </li>
 <li>
 <details>
 <summary>
-<code>IdtyNotAllowedToRequestMembership</code> - 2</summary>
+<code>DistanceNotEvaluated</code> - 2</summary>
+Distance is not evaluated.
+</details>
+</li>
+<li>
+<details>
+<summary>
+<code>DistanceEvaluationPending</code> - 3</summary>
+Distance evaluation has been requested but is still pending
+</details>
+</li>
+<li>
+<details>
+<summary>
+<code>DistanceEvaluationNotRequested</code> - 4</summary>
+Distance evaluation has not been requested
+</details>
+</li>
+<li>
+<details>
+<summary>
+<code>IdtyNotAllowedToRequestMembership</code> - 5</summary>
 Identity is not allowed to request membership.
 </details>
 </li>
 <li>
 <details>
 <summary>
-<code>IdtyNotAllowedToRenewMembership</code> - 3</summary>
+<code>IdtyNotAllowedToRenewMembership</code> - 6</summary>
 Identity not allowed to renew membership.
 </details>
 </li>
 <li>
 <details>
 <summary>
-<code>IdtyCreationPeriodNotRespected</code> - 4</summary>
+<code>IdtyCreationPeriodNotRespected</code> - 7</summary>
 Identity creation period not respected.
 </details>
 </li>
 <li>
 <details>
 <summary>
-<code>NotEnoughReceivedCertsToCreateIdty</code> - 5</summary>
+<code>NotEnoughReceivedCertsToCreateIdty</code> - 8</summary>
 Insufficient received certifications to create identity.
 </details>
 </li>
 <li>
 <details>
 <summary>
-<code>MaxEmittedCertsReached</code> - 6</summary>
+<code>MaxEmittedCertsReached</code> - 9</summary>
 Maximum number of emitted certifications reached.
 </details>
 </li>
 <li>
 <details>
 <summary>
-<code>NotAllowedToChangeIdtyAddress</code> - 7</summary>
+<code>NotAllowedToChangeIdtyAddress</code> - 10</summary>
 Not allowed to change identity address.
 </details>
 </li>
 <li>
 <details>
 <summary>
-<code>NotAllowedToRemoveIdty</code> - 8</summary>
+<code>NotAllowedToRemoveIdty</code> - 11</summary>
 Not allowed to remove identity.
 </details>
 </li>
 <li>
 <details>
 <summary>
-<code>IssuerCanNotEmitCert</code> - 9</summary>
-Issuer cannot emit a certification because it is not validated.
+<code>IssuerNotMember</code> - 12</summary>
+Issuer cannot emit a certification because it is not member.
+</details>
+</li>
+<li>
+<details>
+<summary>
+<code>CertToUnconfirmed</code> - 13</summary>
+Cannot issue a certification to an unconfirmed identity
 </details>
 </li>
 <li>
 <details>
 <summary>
-<code>CertToUndefined</code> - 10</summary>
-Cannot issue a certification to an identity without membership or pending membership.
+<code>CertToRevoked</code> - 14</summary>
+Cannot issue a certification to a revoked identity
 </details>
 </li>
 <li>
 <details>
 <summary>
-<code>IdtyNotFound</code> - 11</summary>
+<code>IdtyNotFound</code> - 15</summary>
 Issuer or receiver not found.
 </details>
 </li>
@@ -761,7 +789,7 @@ Invalid identity name.
 <li>
 <details>
 <summary>
-<code>IdtyNotConfirmedByOwner</code> - 6</summary>
+<code>IdtyNotConfirmed</code> - 6</summary>
 Identity not confirmed by its owner.
 </details>
 </li>
@@ -789,68 +817,82 @@ Invalid revocation key.
 <li>
 <details>
 <summary>
-<code>NotRespectIdtyCreationPeriod</code> - 10</summary>
+<code>IssuerNotMember</code> - 10</summary>
+Issuer is not member and can not perform this action
+</details>
+</li>
+<li>
+<details>
+<summary>
+<code>NotRespectIdtyCreationPeriod</code> - 11</summary>
 Identity creation period is not respected.
 </details>
 </li>
 <li>
 <details>
 <summary>
-<code>OwnerKeyAlreadyRecentlyChanged</code> - 11</summary>
+<code>OwnerKeyAlreadyRecentlyChanged</code> - 12</summary>
 Owner key already changed recently.
 </details>
 </li>
 <li>
 <details>
 <summary>
-<code>OwnerKeyAlreadyUsed</code> - 12</summary>
+<code>OwnerKeyAlreadyUsed</code> - 13</summary>
 Owner key already used.
 </details>
 </li>
 <li>
 <details>
 <summary>
-<code>ProhibitedToRevertToAnOldKey</code> - 13</summary>
+<code>ProhibitedToRevertToAnOldKey</code> - 14</summary>
 Reverting to an old key is prohibited.
 </details>
 </li>
-</ul>
+<li>
+<details>
+<summary>
+<code>AlreadyRevoked</code> - 15</summary>
+Already revoked
+</details>
 </li>
-<li>Membership - 42
-<ul>
 <li>
 <details>
 <summary>
-<code>IdtyIdNotFound</code> - 0</summary>
-Identity ID not found.
+<code>CanNotRevokeUnconfirmed</code> - 16</summary>
+Can not revoke identity that never was member
 </details>
 </li>
 <li>
 <details>
 <summary>
-<code>MembershipAlreadyAcquired</code> - 1</summary>
-Membership already acquired.
+<code>CanNotRevokeUnvalidated</code> - 17</summary>
+Can not revoke identity that never was member
 </details>
 </li>
+</ul>
+</li>
+<li>Membership - 42
+<ul>
 <li>
 <details>
 <summary>
-<code>MembershipAlreadyRequested</code> - 2</summary>
-Membership already requested.
+<code>IdtyIdNotFound</code> - 0</summary>
+Identity ID not found.
 </details>
 </li>
 <li>
 <details>
 <summary>
-<code>MembershipNotFound</code> - 3</summary>
-Membership not found.
+<code>MembershipAlreadyAcquired</code> - 1</summary>
+Membership already acquired.
 </details>
 </li>
 <li>
 <details>
 <summary>
-<code>MembershipRequestNotFound</code> - 4</summary>
-Membership request not found.
+<code>MembershipNotFound</code> - 2</summary>
+Membership not found.
 </details>
 </li>
 </ul>
@@ -966,77 +1008,105 @@ Insufficient certifications received to claim membership.
 <li>
 <details>
 <summary>
-<code>DistanceNotOk</code> - 1</summary>
-Distance has not received a positive evaluation.
+<code>DistanceIsInvalid</code> - 1</summary>
+Distance is invalid.
+</details>
+</li>
+<li>
+<details>
+<summary>
+<code>DistanceNotEvaluated</code> - 2</summary>
+Distance is not evaluated.
+</details>
+</li>
+<li>
+<details>
+<summary>
+<code>DistanceEvaluationPending</code> - 3</summary>
+Distance evaluation has been requested but is still pending
+</details>
+</li>
+<li>
+<details>
+<summary>
+<code>DistanceEvaluationNotRequested</code> - 4</summary>
+Distance evaluation has not been requested
 </details>
 </li>
 <li>
 <details>
 <summary>
-<code>IdtyNotAllowedToRequestMembership</code> - 2</summary>
+<code>IdtyNotAllowedToRequestMembership</code> - 5</summary>
 Identity is not allowed to request membership.
 </details>
 </li>
 <li>
 <details>
 <summary>
-<code>IdtyNotAllowedToRenewMembership</code> - 3</summary>
+<code>IdtyNotAllowedToRenewMembership</code> - 6</summary>
 Identity not allowed to renew membership.
 </details>
 </li>
 <li>
 <details>
 <summary>
-<code>IdtyCreationPeriodNotRespected</code> - 4</summary>
+<code>IdtyCreationPeriodNotRespected</code> - 7</summary>
 Identity creation period not respected.
 </details>
 </li>
 <li>
 <details>
 <summary>
-<code>NotEnoughReceivedCertsToCreateIdty</code> - 5</summary>
+<code>NotEnoughReceivedCertsToCreateIdty</code> - 8</summary>
 Insufficient received certifications to create identity.
 </details>
 </li>
 <li>
 <details>
 <summary>
-<code>MaxEmittedCertsReached</code> - 6</summary>
+<code>MaxEmittedCertsReached</code> - 9</summary>
 Maximum number of emitted certifications reached.
 </details>
 </li>
 <li>
 <details>
 <summary>
-<code>NotAllowedToChangeIdtyAddress</code> - 7</summary>
+<code>NotAllowedToChangeIdtyAddress</code> - 10</summary>
 Not allowed to change identity address.
 </details>
 </li>
 <li>
 <details>
 <summary>
-<code>NotAllowedToRemoveIdty</code> - 8</summary>
+<code>NotAllowedToRemoveIdty</code> - 11</summary>
 Not allowed to remove identity.
 </details>
 </li>
 <li>
 <details>
 <summary>
-<code>IssuerCanNotEmitCert</code> - 9</summary>
-Issuer cannot emit a certification because it is not validated.
+<code>IssuerNotMember</code> - 12</summary>
+Issuer cannot emit a certification because it is not member.
+</details>
+</li>
+<li>
+<details>
+<summary>
+<code>CertToUnconfirmed</code> - 13</summary>
+Cannot issue a certification to an unconfirmed identity
 </details>
 </li>
 <li>
 <details>
 <summary>
-<code>CertToUndefined</code> - 10</summary>
-Cannot issue a certification to an identity without membership or pending membership.
+<code>CertToRevoked</code> - 14</summary>
+Cannot issue a certification to a revoked identity
 </details>
 </li>
 <li>
 <details>
 <summary>
-<code>IdtyNotFound</code> - 11</summary>
+<code>IdtyNotFound</code> - 15</summary>
 Issuer or receiver not found.
 </details>
 </li>
@@ -1061,24 +1131,10 @@ Membership already acquired.
 <li>
 <details>
 <summary>
-<code>MembershipAlreadyRequested</code> - 2</summary>
-Membership already requested.
-</details>
-</li>
-<li>
-<details>
-<summary>
-<code>MembershipNotFound</code> - 3</summary>
+<code>MembershipNotFound</code> - 2</summary>
 Membership not found.
 </details>
 </li>
-<li>
-<details>
-<summary>
-<code>MembershipRequestNotFound</code> - 4</summary>
-Membership request not found.
-</details>
-</li>
 </ul>
 </li>
 <li>SmithCert - 53
diff --git a/docs/api/runtime-events.md b/docs/api/runtime-events.md
index ab06c6d7a573624e13658fce8f8293a194848cb7..cd058e2b44ecf4afb7ca98486c4ad0aefeb5649d 100644
--- a/docs/api/runtime-events.md
+++ b/docs/api/runtime-events.md
@@ -1,6 +1,6 @@
 # Runtime events
 
-There are **129** events from **37** pallets.
+There are **126** events from **37** pallets.
 
 <ul>
 <li>System - 0
@@ -1077,7 +1077,7 @@ members_count: BalanceOf<T>
 <li>
 <details>
 <summary>
-<code>UdsAutoPaidAtRemoval(count, total, who)</code> - 2</summary>
+<code>UdsAutoPaid(count, total, who)</code> - 2</summary>
 DUs were automatically transferred as part of a member removal.
 
 ```rust
@@ -1165,51 +1165,38 @@ new_owner_key: T::AccountId
 <li>
 <details>
 <summary>
-<code>IdtyRemoved(idty_index, reason)</code> - 4</summary>
-An identity has been removed.
+<code>IdtyRevoked(idty_index, reason)</code> - 4</summary>
+An identity has been revoked.
 
 ```rust
 idty_index: T::IdtyIndex
-reason: IdtyRemovalReason<T::IdtyRemovalOtherReason>
+reason: RevocationReason
 ```
 
 </details>
 </li>
-</ul>
-</li>
-<li>Membership - 42
-<ul>
 <li>
 <details>
 <summary>
-<code>MembershipAcquired(member, expire_on)</code> - 0</summary>
-A membership was acquired.
+<code>IdtyRemoved(idty_index, reason)</code> - 5</summary>
+An identity has been removed.
 
 ```rust
-member: T::IdtyId
-expire_on: BlockNumberFor<T>
+idty_index: T::IdtyIndex
+reason: RemovalReason
 ```
 
 </details>
 </li>
-<li>
-<details>
-<summary>
-<code>MembershipTerminated(member, reason)</code> - 1</summary>
-A membership was terminated.
-
-```rust
-member: T::IdtyId
-reason: MembershipTerminationReason
-```
-
-</details>
+</ul>
 </li>
+<li>Membership - 42
+<ul>
 <li>
 <details>
 <summary>
-<code>PendingMembershipAdded(member, expire_on)</code> - 2</summary>
-A pending membership was added.
+<code>MembershipAdded(member, expire_on)</code> - 0</summary>
+A membership was added.
 
 ```rust
 member: T::IdtyId
@@ -1221,11 +1208,12 @@ expire_on: BlockNumberFor<T>
 <li>
 <details>
 <summary>
-<code>PendingMembershipExpired(member)</code> - 3</summary>
-A pending membership has expired.
+<code>MembershipRemoved(member, reason)</code> - 1</summary>
+A membership was removed.
 
 ```rust
 member: T::IdtyId
+reason: MembershipRemovalReason
 ```
 
 </details>
@@ -1237,14 +1225,12 @@ member: T::IdtyId
 <li>
 <details>
 <summary>
-<code>NewCert(issuer, issuer_issued_count, receiver, receiver_received_count)</code> - 0</summary>
+<code>CertAdded(issuer, receiver)</code> - 0</summary>
 A new certification was added.
 
 ```rust
 issuer: T::IdtyIndex
-issuer_issued_count: u32
 receiver: T::IdtyIndex
-receiver_received_count: u32
 ```
 
 </details>
@@ -1252,14 +1238,12 @@ receiver_received_count: u32
 <li>
 <details>
 <summary>
-<code>RemovedCert(issuer, issuer_issued_count, receiver, receiver_received_count, expiration)</code> - 1</summary>
+<code>CertRemoved(issuer, receiver, expiration)</code> - 1</summary>
 A certification was removed.
 
 ```rust
 issuer: T::IdtyIndex
-issuer_issued_count: u32
 receiver: T::IdtyIndex
-receiver_received_count: u32
 expiration: bool
 ```
 
@@ -1268,7 +1252,7 @@ expiration: bool
 <li>
 <details>
 <summary>
-<code>RenewedCert(issuer, receiver)</code> - 2</summary>
+<code>CertRenewed(issuer, receiver)</code> - 2</summary>
 A certification was renewed.
 
 ```rust
@@ -1331,34 +1315,8 @@ status: Option<(<T as frame_system::Config>::AccountId, DistanceStatus)>
 <li>
 <details>
 <summary>
-<code>MembershipAcquired(member, expire_on)</code> - 0</summary>
-A membership was acquired.
-
-```rust
-member: T::IdtyId
-expire_on: BlockNumberFor<T>
-```
-
-</details>
-</li>
-<li>
-<details>
-<summary>
-<code>MembershipTerminated(member, reason)</code> - 1</summary>
-A membership was terminated.
-
-```rust
-member: T::IdtyId
-reason: MembershipTerminationReason
-```
-
-</details>
-</li>
-<li>
-<details>
-<summary>
-<code>PendingMembershipAdded(member, expire_on)</code> - 2</summary>
-A pending membership was added.
+<code>MembershipAdded(member, expire_on)</code> - 0</summary>
+A membership was added.
 
 ```rust
 member: T::IdtyId
@@ -1370,11 +1328,12 @@ expire_on: BlockNumberFor<T>
 <li>
 <details>
 <summary>
-<code>PendingMembershipExpired(member)</code> - 3</summary>
-A pending membership has expired.
+<code>MembershipRemoved(member, reason)</code> - 1</summary>
+A membership was removed.
 
 ```rust
 member: T::IdtyId
+reason: MembershipRemovalReason
 ```
 
 </details>
@@ -1386,14 +1345,12 @@ member: T::IdtyId
 <li>
 <details>
 <summary>
-<code>NewCert(issuer, issuer_issued_count, receiver, receiver_received_count)</code> - 0</summary>
+<code>CertAdded(issuer, receiver)</code> - 0</summary>
 A new certification was added.
 
 ```rust
 issuer: T::IdtyIndex
-issuer_issued_count: u32
 receiver: T::IdtyIndex
-receiver_received_count: u32
 ```
 
 </details>
@@ -1401,14 +1358,12 @@ receiver_received_count: u32
 <li>
 <details>
 <summary>
-<code>RemovedCert(issuer, issuer_issued_count, receiver, receiver_received_count, expiration)</code> - 1</summary>
+<code>CertRemoved(issuer, receiver, expiration)</code> - 1</summary>
 A certification was removed.
 
 ```rust
 issuer: T::IdtyIndex
-issuer_issued_count: u32
 receiver: T::IdtyIndex
-receiver_received_count: u32
 expiration: bool
 ```
 
@@ -1417,7 +1372,7 @@ expiration: bool
 <li>
 <details>
 <summary>
-<code>RenewedCert(issuer, receiver)</code> - 2</summary>
+<code>CertRenewed(issuer, receiver)</code> - 2</summary>
 A certification was renewed.
 
 ```rust
diff --git a/docs/dev/pallet_conventions.md b/docs/dev/pallet_conventions.md
index d7b9d7829280a74b1109faf2a130ff8385f286e8..d84d6f232c064f36d69ca9a22f66f65e9490ef05 100644
--- a/docs/dev/pallet_conventions.md
+++ b/docs/dev/pallet_conventions.md
@@ -5,7 +5,7 @@
 Custom Duniter pallet calls should adhere to the standard Substrate naming convention:
 
 - `action_` for regular calls (e.g., `create_identity`).
-- `force_action_`  for calls with a privileged origin (e.g., `force_remove_identity`).
+- `force_action_` for calls with a privileged origin (e.g., `force_set_distance_status`).
 
 ## Error
 
diff --git a/end2end-tests/cucumber-features/identity_creation.feature b/end2end-tests/cucumber-features/identity_creation.feature
index ce660e1aead7bba6a689a0bbdf6ace610ce06831..0e7a8a10a250a661b4e1b5e60141afea706c04e0 100644
--- a/end2end-tests/cucumber-features/identity_creation.feature
+++ b/end2end-tests/cucumber-features/identity_creation.feature
@@ -14,10 +14,10 @@ Feature: Identity creation
     # then next cert can be done after cert_period, which is 15
     When 15 block later
     When alice creates identity for dave
-    Then dave identity should be created
+    Then dave identity should be unconfirmed
     Then dave should be certified by alice
     When dave confirms his identity with pseudo "dave"
-    Then dave identity should be confirmed
+    Then dave identity should be unvalidated
     When 3 block later
     When bob certifies dave
     When charlie certifies dave
@@ -30,5 +30,5 @@ Feature: Identity creation
     When alice runs distance oracle
     When 30 blocks later
     Then dave should have distance ok
-    When eve validates dave identity
-    Then dave identity should be validated
+    When dave claims membership
+    Then dave identity should be member
diff --git a/end2end-tests/tests/common/identity.rs b/end2end-tests/tests/common/identity.rs
index 0aa26bf916fc60b821775b995e5dd16f53b478e6..57707e5b078ce10170cad3bc00ac5c97e9aa8ad5 100644
--- a/end2end-tests/tests/common/identity.rs
+++ b/end2end-tests/tests/common/identity.rs
@@ -72,27 +72,6 @@ pub async fn confirm_identity(client: &Client, from: AccountKeyring, pseudo: Str
     Ok(())
 }
 
-pub async fn validate_identity(client: &Client, from: AccountKeyring, to: u32) -> Result<()> {
-    let from = PairSigner::new(from.pair());
-
-    let _events = create_block_with_extrinsic(
-        client,
-        client
-            .tx()
-            .create_signed(
-                &gdev::tx().identity().validate_identity(to),
-                &from,
-                BaseExtrinsicParamsBuilder::new(),
-            )
-            .await
-            .unwrap(),
-    )
-    .await
-    .unwrap();
-
-    Ok(())
-}
-
 // get identity index from account keyring name
 pub async fn get_identity_index(world: &DuniterWorld, account: String) -> Result<u32> {
     let account: AccountId = AccountKeyring::from_str(&account)
diff --git a/end2end-tests/tests/common/membership.rs b/end2end-tests/tests/common/membership.rs
new file mode 100644
index 0000000000000000000000000000000000000000..d800f3387f756240b64645bda3c2859391b706db
--- /dev/null
+++ b/end2end-tests/tests/common/membership.rs
@@ -0,0 +1,40 @@
+// 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 super::*;
+use sp_keyring::AccountKeyring;
+use subxt::tx::PairSigner;
+
+pub async fn claim_membership(client: &Client, from: AccountKeyring) -> Result<()> {
+    let from = PairSigner::new(from.pair());
+
+    let _events = create_block_with_extrinsic(
+        client,
+        client
+            .tx()
+            .create_signed(
+                &gdev::tx().membership().claim_membership(),
+                &from,
+                BaseExtrinsicParamsBuilder::new(),
+            )
+            .await
+            .unwrap(),
+    )
+    .await
+    .unwrap();
+
+    Ok(())
+}
diff --git a/end2end-tests/tests/common/mod.rs b/end2end-tests/tests/common/mod.rs
index b147b9783610074e6ced6f3f4e29fc28f7ee63d6..6dbbbda5b6a216c7447b10d8168bb7bf2316a097 100644
--- a/end2end-tests/tests/common/mod.rs
+++ b/end2end-tests/tests/common/mod.rs
@@ -20,6 +20,7 @@ pub mod balances;
 pub mod cert;
 pub mod distance;
 pub mod identity;
+pub mod membership;
 pub mod oneshot;
 
 #[subxt::subxt(
diff --git a/end2end-tests/tests/cucumber_tests.rs b/end2end-tests/tests/cucumber_tests.rs
index 92f1f36eed0a4422e749acc72952cb3ef61f299c..db7e64171d002fac921e0ff0f6166c7f23661e7c 100644
--- a/end2end-tests/tests/cucumber_tests.rs
+++ b/end2end-tests/tests/cucumber_tests.rs
@@ -334,15 +334,11 @@ async fn confirm_identity(world: &mut DuniterWorld, from: String, pseudo: String
 }
 
 #[allow(clippy::needless_pass_by_ref_mut)]
-#[when(regex = r#"([a-zA-Z]+) validates ([a-zA-Z]+) identity"#)]
-async fn validate_identity(world: &mut DuniterWorld, from: String, to: String) -> Result<()> {
+#[when(regex = r#"([a-zA-Z]+) claims membership"#)]
+async fn claim_membership(world: &mut DuniterWorld, from: String) -> Result<()> {
     // input names to keyrings
     let from = AccountKeyring::from_str(&from).expect("unknown from");
-    let to: u32 = common::identity::get_identity_index(world, to)
-        .await
-        .unwrap();
-
-    common::identity::validate_identity(world.client(), from, to).await
+    common::membership::claim_membership(world.client(), from).await
 }
 
 #[allow(clippy::needless_pass_by_ref_mut)]
@@ -576,9 +572,11 @@ impl FromStr for IdtyStatus {
 
     fn from_str(input: &str) -> std::result::Result<IdtyStatus, String> {
         match input {
-            "created" => Ok(IdtyStatus::Created),
-            "confirmed" => Ok(IdtyStatus::ConfirmedByOwner),
-            "validated" => Ok(IdtyStatus::Validated),
+            "unconfirmed" => Ok(IdtyStatus::Unconfirmed),
+            "unvalidated" => Ok(IdtyStatus::Unvalidated),
+            "member" => Ok(IdtyStatus::Member),
+            "notmember" => Ok(IdtyStatus::NotMember),
+            "revoked" => Ok(IdtyStatus::Revoked),
             _ => Err(format!("'{input}' does not match a status")),
         }
     }
diff --git a/live-tests/tests/sanity_gdev.rs b/live-tests/tests/sanity_gdev.rs
index e16979c7783e4336664b8e5bcdf75829b461ea1d..d0ae6434cea09c3cb995e0b308d25eb71fee32c1 100644
--- a/live-tests/tests/sanity_gdev.rs
+++ b/live-tests/tests/sanity_gdev.rs
@@ -46,7 +46,7 @@ type IdtyData = gdev::runtime_types::common_runtime::entities::IdtyData;
 type IdtyIndex = u32;
 type IdtyValue =
     gdev::runtime_types::pallet_identity::types::IdtyValue<BlockNumber, AccountId32, IdtyData>;
-use gdev::runtime_types::pallet_identity::types::IdtyStatus;
+// use gdev::runtime_types::pallet_identity::types::IdtyStatus;
 
 struct Storage {
     accounts: HashMap<AccountId32, AccountInfo>,
@@ -110,7 +110,7 @@ async fn sanity_tests_at(client: Client, _maybe_block_hash: Option<H256>) -> any
             next_creatable_identity_on: idty_value.next_creatable_identity_on,
             old_owner_key: None, // Not used in the live test, skip the conversion
             owner_key: AccountId32::from(idty_value.owner_key.0),
-            removable_on: idty_value.removable_on,
+            next_scheduled: idty_value.next_scheduled,
             status: idty_value.status,
         };
         identities.insert(IdtyIndex::from_le_bytes(idty_index_bytes), idty_val);
@@ -275,27 +275,6 @@ mod verifier {
                         ),
                     );
                 }
-
-                match idty_value.status {
-                    IdtyStatus::Validated => {
-                        // Rule 3: If the identity is validated, removable_on should be zero
-                        self.assert(
-                            idty_value.removable_on == 0,
-                            format!(
-                                "Identity {} is corrupted: removable_on > 0 on validated idty",
-                                idty_index
-                            ),
-                        );
-                    }
-                    _ => {
-                        // Rule 4: If the identity is not validated, next_creatable_identity_on should be zero
-                        self.assert(
-							idty_value.next_creatable_identity_on == 0,
-							format!("Identity {} is corrupted: next_creatable_identity_on > 0 on non-validated idty",
-							idty_index)
-						);
-                    }
-                }
             }
 
             for (idty_index, idty_value) in identities {
diff --git a/node/src/chain_spec/gdev.rs b/node/src/chain_spec/gdev.rs
index 3b64a884c3050868c3bd6d4d40499ad180b48313..0639cbfed4d086ba965d2ce4fb8cc15f7c8d37f0 100644
--- a/node/src/chain_spec/gdev.rs
+++ b/node/src/chain_spec/gdev.rs
@@ -354,8 +354,8 @@ fn genesis_data_to_gdev_genesis_conf(
                             next_creatable_identity_on: 0,
                             old_owner_key: old_owner_key.map(|address| (address, 0)),
                             owner_key,
-                            removable_on: if active { 0 } else { 2 },
-                            status: IdtyStatus::Validated,
+                            next_scheduled: if active { 0 } else { 2 },
+                            status: IdtyStatus::Member,
                         },
                     },
                 )
diff --git a/node/src/chain_spec/gtest.rs b/node/src/chain_spec/gtest.rs
index 3b845e478734f70f9e449164a9d12a659bd06628..796b2c7de224df2f3422af8097065389ac3e534c 100644
--- a/node/src/chain_spec/gtest.rs
+++ b/node/src/chain_spec/gtest.rs
@@ -301,8 +301,8 @@ fn genesis_data_to_gtest_genesis_conf(
                             next_creatable_identity_on: 0,
                             old_owner_key: old_owner_key.clone().map(|address| (address, 0)),
                             owner_key,
-                            removable_on: if active { 0 } else { 2 },
-                            status: IdtyStatus::Validated,
+                            next_scheduled: if active { 0 } else { 2 },
+                            status: IdtyStatus::Member,
                         },
                     },
                 )
diff --git a/pallets/certification/src/lib.rs b/pallets/certification/src/lib.rs
index 6074908e27aaf08423bf0f46dba96892f73c8a76..fd60d814e7e8cef3591f1e174c434637267ec90e 100644
--- a/pallets/certification/src/lib.rs
+++ b/pallets/certification/src/lib.rs
@@ -283,38 +283,8 @@ pub mod pallet {
         ) -> DispatchResultWithPostInfo {
             let who = ensure_signed(origin)?;
 
-            // Forbid self cert
-            ensure!(issuer != receiver, Error::<T, I>::CannotCertifySelf);
-
-            // Verify caller ownership
-            let issuer_owner_key =
-                T::OwnerKeyOf::convert(issuer).ok_or(Error::<T, I>::IssuerNotFound)?;
-            ensure!(issuer_owner_key == who, DispatchError::BadOrigin);
-
-            // Verify compatibility with other pallets state
-            T::CheckCertAllowed::check_cert_allowed(issuer, receiver)?;
-
-            // Verify rule MinReceivedCertToBeAbleToIssueCert
-            let issuer_idty_cert_meta = <StorageIdtyCertMeta<T, I>>::get(issuer);
-            ensure!(
-                issuer_idty_cert_meta.received_count
-                    >= T::MinReceivedCertToBeAbleToIssueCert::get(),
-                Error::<T, I>::NotEnoughCertReceived
-            );
-
-            // Verify rule MaxByIssuer
-            ensure!(
-                issuer_idty_cert_meta.issued_count < T::MaxByIssuer::get(),
-                Error::<T, I>::IssuedTooManyCert
-            );
-
-            // Verify rule CertPeriod
             let block_number = frame_system::pallet::Pallet::<T>::block_number();
-            ensure!(
-                block_number >= issuer_idty_cert_meta.next_issuable_on,
-                Error::<T, I>::NotRespectCertPeriod
-            );
-
+            Self::check_cert_allowed(who, issuer, receiver, block_number)?;
             Self::do_add_cert(block_number, issuer, receiver)
         }
 
@@ -524,6 +494,54 @@ pub mod pallet {
             }
             total_weight
         }
+
+        /// check cert allowed
+        // first internal checks
+        // then external checks
+        fn check_cert_allowed(
+            caller_key: T::AccountId,
+            issuer: T::IdtyIndex,
+            receiver: T::IdtyIndex,
+            block_number: T::BlockNumber,
+        ) -> DispatchResult {
+            // --- first internal checks
+            // 1. Forbid self cert
+            ensure!(issuer != receiver, Error::<T, I>::CannotCertifySelf);
+
+            // 2. Verify caller ownership
+            let issuer_owner_key =
+                T::OwnerKeyOf::convert(issuer).ok_or(Error::<T, I>::IssuerNotFound)?;
+            ensure!(issuer_owner_key == caller_key, DispatchError::BadOrigin);
+
+            // 3. Verify rule MinReceivedCertToBeAbleToIssueCert
+            // (this number can differ from the one necessary to be member)
+            let issuer_idty_cert_meta = <StorageIdtyCertMeta<T, I>>::get(issuer);
+            ensure!(
+                issuer_idty_cert_meta.received_count
+                    >= T::MinReceivedCertToBeAbleToIssueCert::get(),
+                Error::<T, I>::NotEnoughCertReceived
+            );
+
+            // 4. Verify rule MaxByIssuer
+            ensure!(
+                issuer_idty_cert_meta.issued_count < T::MaxByIssuer::get(),
+                Error::<T, I>::IssuedTooManyCert
+            );
+
+            // 5. Verify rule CertPeriod
+            ensure!(
+                block_number >= issuer_idty_cert_meta.next_issuable_on,
+                Error::<T, I>::NotRespectCertPeriod
+            );
+
+            // --- then external checks
+            // - issuer is member
+            // - receiver is confirmed
+            // - receiver is not revoked
+            T::CheckCertAllowed::check_cert_allowed(issuer, receiver)?;
+
+            Ok(())
+        }
     }
 }
 
diff --git a/pallets/distance/src/mock.rs b/pallets/distance/src/mock.rs
index 17071e729f532f0e6295cfd9ada61b92537919b6..988c9b43ff3893da774cdc707856fd0953d59e2a 100644
--- a/pallets/distance/src/mock.rs
+++ b/pallets/distance/src/mock.rs
@@ -215,9 +215,10 @@ impl pallet_balances::Config for Test {
 parameter_types! {
     pub const ChangeOwnerKeyPeriod: u64 = 10;
     pub const ConfirmPeriod: u64 = 2;
+    pub const ValidationPeriod: u64 = 3;
+    pub const AutorevocationPeriod: u64 = 5;
+    pub const DeletionPeriod: u64 = 7;
     pub const IdtyCreationPeriod: u64 = 3;
-    pub const MaxInactivityPeriod: u64 = 5;
-    pub const ValidationPeriod: u64 = 2;
 }
 
 pub struct IdtyNameValidatorTestImpl;
@@ -230,17 +231,18 @@ impl pallet_identity::traits::IdtyNameValidator for IdtyNameValidatorTestImpl {
 impl pallet_identity::Config for Test {
     type ChangeOwnerKeyPeriod = ChangeOwnerKeyPeriod;
     type ConfirmPeriod = ConfirmPeriod;
+    type ValidationPeriod = ValidationPeriod;
+    type AutorevocationPeriod = AutorevocationPeriod;
+    type DeletionPeriod = DeletionPeriod;
     type CheckIdtyCallAllowed = ();
     type IdtyCreationPeriod = IdtyCreationPeriod;
     type IdtyData = ();
     type IdtyNameValidator = IdtyNameValidatorTestImpl;
     type IdtyIndex = u32;
     type AccountLinker = ();
-    type IdtyRemovalOtherReason = ();
     type Signer = UintAuthorityId;
     type Signature = TestSignature;
     type OnIdtyChange = ();
-    type RemoveIdentityConsumers = ();
     type RuntimeEvent = RuntimeEvent;
     type WeightInfo = ();
     #[cfg(feature = "runtime-benchmarks")]
@@ -277,8 +279,8 @@ pub fn new_test_ext() -> sp_io::TestExternalities {
                     next_creatable_identity_on: 0,
                     owner_key: i as u64,
                     old_owner_key: None,
-                    removable_on: 0,
-                    status: pallet_identity::IdtyStatus::Validated,
+                    next_scheduled: 0,
+                    status: pallet_identity::IdtyStatus::Member,
                 },
             })
             .collect(),
diff --git a/pallets/duniter-account/src/lib.rs b/pallets/duniter-account/src/lib.rs
index 93964997e6e7323bf58d1ee2029ec91323ff0e33..836220376dd71e95af91c86ae88bcd583115ab46 100644
--- a/pallets/duniter-account/src/lib.rs
+++ b/pallets/duniter-account/src/lib.rs
@@ -487,10 +487,7 @@ impl<T: Config> pallet_identity::traits::OnIdtyChange<T> for Pallet<T> {
             IdtyEvent::Created { owner_key, .. } => {
                 Self::do_link_identity(owner_key.clone(), idty_id);
             }
-            IdtyEvent::Confirmed
-            | IdtyEvent::Validated
-            | IdtyEvent::ChangedOwnerKey { .. }
-            | IdtyEvent::Removed { .. } => {}
+            IdtyEvent::Removed { .. } => {}
         }
     }
 }
diff --git a/pallets/duniter-wot/src/lib.rs b/pallets/duniter-wot/src/lib.rs
index 7f017280c671e4eed886346b7ffe689fdc65b8b9..41ad8db138320591f987b6a4c00870164d03bd62 100644
--- a/pallets/duniter-wot/src/lib.rs
+++ b/pallets/duniter-wot/src/lib.rs
@@ -17,8 +17,6 @@
 #![cfg_attr(not(feature = "std"), no_std)]
 #![allow(clippy::type_complexity)]
 
-mod types;
-
 #[cfg(test)]
 mod mock;
 
@@ -31,15 +29,13 @@ pub mod traits;
 mod benchmarking;*/
 
 pub use pallet::*;
-pub use types::*;
 
 use traits::*;
 
-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 pallet_membership::MembershipRemovalReason;
 use sp_runtime::traits::IsMember;
 
 type IdtyIndex = u32;
@@ -63,10 +59,8 @@ pub mod pallet {
     pub trait Config<I: 'static = ()>:
         frame_system::Config
         + pallet_certification::Config<I, IdtyIndex = IdtyIndex>
-        + pallet_identity::Config<
-            IdtyIndex = IdtyIndex,
-            IdtyRemovalOtherReason = IdtyRemovalWotReason,
-        > + pallet_membership::Config<I, IdtyId = IdtyIndex>
+        + pallet_identity::Config<IdtyIndex = IdtyIndex>
+        + pallet_membership::Config<I, IdtyId = IdtyIndex>
     {
         /// Distance evaluation provider
         type IsDistanceOk: IsDistanceOk<IdtyIndex>;
@@ -90,17 +84,6 @@ pub mod pallet {
                 block_number + T::FirstIssuableOn::get(),
             );
         }
-        pub(super) fn dispatch_idty_call(idty_call: pallet_identity::Call<T>) -> bool {
-            if !T::IsSubWot::get() {
-                if let Err(e) = idty_call.dispatch_bypass_filter(RawOrigin::Root.into()) {
-                    sp_std::if_std! {
-                        println!("fail to dispatch idty call: {:?}", e)
-                    }
-                    return false;
-                }
-            }
-            true
-        }
     }
 
     // ERRORS //
@@ -113,6 +96,10 @@ pub mod pallet {
         DistanceIsInvalid,
         /// Distance is not evaluated.
         DistanceNotEvaluated,
+        /// Distance evaluation has been requested but is still pending
+        DistanceEvaluationPending,
+        /// Distance evaluation has not been requested
+        DistanceEvaluationNotRequested,
         /// Identity is not allowed to request membership.
         IdtyNotAllowedToRequestMembership,
         /// Identity not allowed to renew membership.
@@ -127,10 +114,12 @@ pub mod pallet {
         NotAllowedToChangeIdtyAddress,
         /// Not allowed to remove identity.
         NotAllowedToRemoveIdty,
-        /// Issuer cannot emit a certification because it is not validated.
-        IssuerCanNotEmitCert,
-        /// Cannot issue a certification to an identity without membership or pending membership.
-        CertToUndefined,
+        /// Issuer cannot emit a certification because it is not member.
+        IssuerNotMember,
+        /// Cannot issue a certification to an unconfirmed identity
+        CertToUnconfirmed,
+        /// Cannot issue a certification to a revoked identity
+        CertToRevoked,
         /// Issuer or receiver not found.
         IdtyNotFound,
     }
@@ -142,48 +131,37 @@ impl<AccountId, T: Config<I>, I: 'static> pallet_identity::traits::CheckIdtyCall
 where
     T: frame_system::Config<AccountId = AccountId> + pallet_membership::Config<I>,
 {
+    // identity creation checks
     fn check_create_identity(creator: IdtyIndex) -> Result<(), DispatchError> {
         // main WoT constraints
         if !T::IsSubWot::get() {
             let cert_meta = pallet_certification::Pallet::<T, I>::idty_cert_meta(creator);
             // perform all checks
+            // 1. check that identity has the right to create an identity
+            // identity can be member with 5 certifications and still not reach identity creation threshold which could be higher (6, 7...)
             ensure!(
                 cert_meta.received_count >= T::MinCertForCreateIdtyRight::get(),
                 Error::<T, I>::NotEnoughReceivedCertsToCreateIdty
             );
+            // 2. check that issuer can emit one more certification
+            // (this is only a partial check)
             ensure!(
                 cert_meta.issued_count < T::MaxByIssuer::get(),
                 Error::<T, I>::MaxEmittedCertsReached
             );
+            // 3. check that issuer respects certification creation period
             ensure!(
                 cert_meta.next_issuable_on <= frame_system::pallet::Pallet::<T>::block_number(),
                 Error::<T, I>::IdtyCreationPeriodNotRespected
             );
         }
-        // no constraints for subwot
+        // TODO (#136) make these trait implementation work on instances rather than static to avoid checking IsSubWot
+        // smith subwot can never prevent from creating identity
         Ok(())
     }
-    fn check_confirm_identity(idty_index: IdtyIndex) -> Result<(), DispatchError> {
-        // main WoT automatic action
-        if !T::IsSubWot::get() {
-            // force add a membership request to the main WoT
-            pallet_membership::Pallet::<T, I>::force_request_membership(idty_index)
-                .map_err(|e| e.error)?;
-        }
-        // no constraints for subwot
-        Ok(())
-    }
-    fn check_validate_identity(idty_index: IdtyIndex) -> Result<(), DispatchError> {
-        // main WoT constraints
-        if !T::IsSubWot::get() {
-            // check if identity is allowed to claim membership to the main wot
-            // (will be called automatically after)
-            pallet_membership::Pallet::<T, I>::check_allowed_to_claim(idty_index)?;
-        }
-        // no constraints for subwot
-        Ok(())
-    }
-    fn check_change_identity_address(idty_index: IdtyIndex) -> Result<(), DispatchError> {
+
+    // identity change owner key cheks
+    fn change_owner_key(idty_index: IdtyIndex) -> Result<(), DispatchError> {
         // sub WoT prevents from changing identity
         if T::IsSubWot::get() {
             ensure!(
@@ -194,80 +172,44 @@ where
         // no constraints for main wot
         Ok(())
     }
-    fn check_remove_identity(idty_index: IdtyIndex) -> Result<(), DispatchError> {
-        // identity can not be removed when member of a subwot (smith in this case)
-        if T::IsSubWot::get() {
-            ensure!(
-                !pallet_membership::Pallet::<T, I>::is_member(&idty_index),
-                Error::<T, I>::NotAllowedToRemoveIdty
-            );
-        }
-        Ok(())
-    }
 }
 
 // implement cert call checks
 impl<T: Config<I>, I: 'static> pallet_certification::traits::CheckCertAllowed<IdtyIndex>
     for Pallet<T, I>
-// TODO add the following where clause once checks can be done on pallet instance
+// TODO (#136) add the following where clause once checks can be done on pallet instance
 // where
 //     T: pallet_membership::Config<I>,
 {
     // check the following:
     // - issuer has identity
-    // - issuer identity is validated
+    // - issuer identity is member
     // - receiver has identity
-    // - receiver identity is confirmed or validated
-    // - receiver has membership
-    //
-    // /!\ do not check the following:
-    // - receiver has membership
-    // - issuer has membership
-    // this has the following consequences:
-    // - receiver can receive smith certification without having requested membership
-    // - issuer can issue cert even if he lost his membership
-    //   (not renewed or passed below cert threshold and above again without claiming membership)
-    // this is counterintuitive behavior but not a big problem
-    //
-    // TODO to fix this strange behavior, we will have to make the tests
-    // (CheckCertAllowed and CheckMembershipCallAllowed) run on the relevant instance
-    // i.e. Cert for Wot, SmithCert for SmithWot...
-    // → see issue #136
+    // - receiver identity is confirmed and not revoked
     fn check_cert_allowed(issuer: IdtyIndex, receiver: IdtyIndex) -> Result<(), DispatchError> {
         // issuer checks
-        // ensure issuer has validated identity
+        // ensure issuer is member
         if let Some(issuer_data) = pallet_identity::Pallet::<T>::identity(issuer) {
             ensure!(
-                issuer_data.status == IdtyStatus::Validated,
-                Error::<T, I>::IssuerCanNotEmitCert
+                issuer_data.status == IdtyStatus::Member,
+                Error::<T, I>::IssuerNotMember
             );
         } else {
             return Err(Error::<T, I>::IdtyNotFound.into());
         }
-        // issue #136 this has to be done on the correct instance of membership pallet
-        // // ensure issuer has membership
-        // if pallet_membership::Pallet::<T, I>::membership(issuer).is_none() {
-        //     // improvement: give reason why issuer can not emit cert (not member)
-        //     return Err(Error::<T, I>::IssuerCanNotEmitCert.into());
-        // }
 
         // receiver checks
-        // ensure receiver has confirmed or validated identity
+        // ensure receiver identity is confirmed and not revoked
         if let Some(receiver_data) = pallet_identity::Pallet::<T>::identity(receiver) {
             match receiver_data.status {
-                IdtyStatus::ConfirmedByOwner | IdtyStatus::Validated => {} // able to receive cert
-                IdtyStatus::Created => return Err(Error::<T, I>::CertToUndefined.into()),
+                // able to receive cert
+                IdtyStatus::Unvalidated | IdtyStatus::Member | IdtyStatus::NotMember => {}
+                IdtyStatus::Unconfirmed => return Err(Error::<T, I>::CertToUnconfirmed.into()),
+                IdtyStatus::Revoked => return Err(Error::<T, I>::CertToRevoked.into()),
             };
         } else {
             return Err(Error::<T, I>::IdtyNotFound.into());
         }
-        // issue #136 this has to be done on the correct instance of membership pallet
-        // // ensure receiver has a membership or a pending membership
-        // if pallet_membership::Pallet::<T, I>::pending_membership(issuer).is_none()
-        //     && pallet_membership::Pallet::<T, I>::membership(issuer).is_none()
-        // {
-        //     return Err(Error::<T, I>::CertToUndefined.into());
-        // }
         Ok(())
     }
 }
@@ -276,22 +218,7 @@ impl<T: Config<I>, I: 'static> pallet_certification::traits::CheckCertAllowed<Id
 impl<T: Config<I>, I: 'static> sp_membership::traits::CheckMembershipCallAllowed<IdtyIndex>
     for Pallet<T, I>
 {
-    // membership request is only possible for subwot and when identity is validated
-    fn check_idty_allowed_to_request_membership(
-        idty_index: &IdtyIndex,
-    ) -> Result<(), DispatchError> {
-        if let Some(idty_value) = pallet_identity::Pallet::<T>::identity(idty_index) {
-            ensure!(
-                T::IsSubWot::get() && idty_value.status == IdtyStatus::Validated,
-                Error::<T, I>::IdtyNotAllowedToRequestMembership
-            );
-        } else {
-            return Err(Error::<T, I>::IdtyNotFound.into());
-        }
-        Ok(())
-    }
-
-    // membership claim is only possible when enough certs are received (both wots)
+    // membership claim is only possible when enough certs are received (both wots) and distance is ok
     fn check_idty_allowed_to_claim_membership(idty_index: &IdtyIndex) -> Result<(), DispatchError> {
         let idty_cert_meta = pallet_certification::Pallet::<T, I>::idty_cert_meta(idty_index);
         ensure!(
@@ -302,11 +229,11 @@ impl<T: Config<I>, I: 'static> sp_membership::traits::CheckMembershipCallAllowed
         Ok(())
     }
 
-    // membership renewal is only possible when identity is validated
+    // membership renewal is only possible when identity is member (otherwise it should claim again)
     fn check_idty_allowed_to_renew_membership(idty_index: &IdtyIndex) -> Result<(), DispatchError> {
         if let Some(idty_value) = pallet_identity::Pallet::<T>::identity(idty_index) {
             ensure!(
-                idty_value.status == IdtyStatus::Validated,
+                idty_value.status == IdtyStatus::Member,
                 Error::<T, I>::IdtyNotAllowedToRenewMembership
             );
             T::IsDistanceOk::is_distance_ok(idty_index)?;
@@ -326,23 +253,18 @@ where
         match membership_event {
             sp_membership::Event::<IdtyIndex>::MembershipAdded(idty_index) => {
                 if !T::IsSubWot::get() {
-                    // when membership is acquired, validate identity
+                    // when main membership is acquired, tell identity
                     // (only used on first membership acquiry)
-                    pallet_identity::Pallet::<T>::try_validate_identity(*idty_index);
+                    pallet_identity::Pallet::<T>::membership_added(*idty_index);
                 }
             }
-            sp_membership::Event::<IdtyIndex>::MembershipRemoved(_) => {}
-            sp_membership::Event::<IdtyIndex>::MembershipRenewed(_) => {}
-            sp_membership::Event::<IdtyIndex>::PendingMembershipAdded(_) => {}
-            sp_membership::Event::<IdtyIndex>::PendingMembershipExpired(idty_index) => {
-                Self::dispatch_idty_call(pallet_identity::Call::force_remove_identity {
-                    idty_index: *idty_index,
-                    idty_name: None,
-                    reason: pallet_identity::IdtyRemovalReason::Other(
-                        IdtyRemovalWotReason::MembershipExpired,
-                    ),
-                });
+            sp_membership::Event::<IdtyIndex>::MembershipRemoved(idty_index) => {
+                if !T::IsSubWot::get() {
+                    // when main membership is lost, tell identity
+                    pallet_identity::Pallet::<T>::membership_removed(*idty_index);
+                }
             }
+            sp_membership::Event::<IdtyIndex>::MembershipRenewed(_) => {}
         }
     }
 }
@@ -351,6 +273,7 @@ where
 impl<T: Config<I>, I: 'static> pallet_identity::traits::OnIdtyChange<T> for Pallet<T, I> {
     fn on_idty_change(idty_index: IdtyIndex, idty_event: &IdtyEvent<T>) {
         match idty_event {
+            // identity just has been created, a cert must be added
             IdtyEvent::Created { creator, .. } => {
                 if let Err(e) = <pallet_certification::Pallet<T, I>>::do_add_cert_checked(
                     *creator, idty_index, true,
@@ -360,25 +283,38 @@ impl<T: Config<I>, I: 'static> pallet_identity::traits::OnIdtyChange<T> for Pall
                     }
                 }
             }
-            IdtyEvent::Validated => {
-                // auto claim membership on main wot
-                <pallet_membership::Pallet<T, I>>::try_claim_membership(idty_index);
-            }
+            // TODO split in removed / revoked in two events:
+            // if identity is revoked keep it
+            // if identity is removed also remove certs
             IdtyEvent::Removed { status } => {
-                if *status != IdtyStatus::Validated {
-                    if let Err(e) =
-                        <pallet_certification::Pallet<T, I>>::remove_all_certs_received_by(
-                            frame_system::Origin::<T>::Root.into(),
-                            idty_index,
-                        )
-                    {
+                // try remove membership in any case
+                <pallet_membership::Pallet<T, I>>::do_remove_membership(
+                    idty_index,
+                    MembershipRemovalReason::Revoked,
+                );
+
+                // only remove certs if identity is unvalidated
+                match status {
+                    IdtyStatus::Unconfirmed | IdtyStatus::Unvalidated => {
+                        if let Err(e) =
+                            <pallet_certification::Pallet<T, I>>::remove_all_certs_received_by(
+                                frame_system::Origin::<T>::Root.into(),
+                                idty_index,
+                            )
+                        {
+                            sp_std::if_std! {
+                                println!("fail to remove certs received by some idty: {:?}", e)
+                            }
+                        }
+                    }
+                    IdtyStatus::Revoked => {}
+                    IdtyStatus::Member | IdtyStatus::NotMember => {
                         sp_std::if_std! {
-                            println!("fail to remove certs received by some idty: {:?}", e)
+                            println!("removed non-revoked identity: {:?}", idty_index);
                         }
                     }
                 }
             }
-            IdtyEvent::Confirmed | IdtyEvent::ChangedOwnerKey { .. } => {}
         }
     }
 }
@@ -413,12 +349,10 @@ impl<T: Config<I>, I: 'static> pallet_certification::traits::OnRemovedCert<IdtyI
             && pallet_membership::Pallet::<T, I>::is_member(&receiver)
         {
             // expire receiver membership
-            // it gives them a bit of time to get back enough certs
-            if let Err(e) = <pallet_membership::Pallet<T, I>>::force_expire_membership(receiver) {
-                sp_std::if_std! {
-                    println!("fail to expire membership: {:?}", e)
-                }
-            }
+            <pallet_membership::Pallet<T, I>>::do_remove_membership(
+                receiver,
+                MembershipRemovalReason::NotEnoughCerts,
+            )
         }
     }
 }
diff --git a/pallets/duniter-wot/src/mock.rs b/pallets/duniter-wot/src/mock.rs
index 29454df22851cd21301790b099cb650adec2c7d7..9420b482f4f48a76047750cfdd8d289f1677f83b 100644
--- a/pallets/duniter-wot/src/mock.rs
+++ b/pallets/duniter-wot/src/mock.rs
@@ -108,8 +108,10 @@ impl pallet_duniter_wot::Config<Instance1> for Test {
 parameter_types! {
     pub const ChangeOwnerKeyPeriod: u64 = 10;
     pub const ConfirmPeriod: u64 = 2;
+    pub const ValidationPeriod: u64 = 5;
+    pub const AutorevocationPeriod: u64 = 6;
+    pub const DeletionPeriod: u64 = 7;
     pub const IdtyCreationPeriod: u64 = 3;
-    pub const ValidationPeriod: u64 = 2;
 }
 
 pub struct IdtyNameValidatorTestImpl;
@@ -124,15 +126,16 @@ impl pallet_identity::Config for Test {
     type ConfirmPeriod = ConfirmPeriod;
     type CheckIdtyCallAllowed = (DuniterWot, SmithSubWot);
     type IdtyCreationPeriod = IdtyCreationPeriod;
+    type ValidationPeriod = ValidationPeriod;
+    type AutorevocationPeriod = AutorevocationPeriod;
+    type DeletionPeriod = DeletionPeriod;
     type IdtyData = ();
     type IdtyNameValidator = IdtyNameValidatorTestImpl;
     type IdtyIndex = IdtyIndex;
     type AccountLinker = ();
-    type IdtyRemovalOtherReason = IdtyRemovalWotReason;
     type Signer = UintAuthorityId;
     type Signature = TestSignature;
-    type OnIdtyChange = DuniterWot;
-    type RemoveIdentityConsumers = ();
+    type OnIdtyChange = (DuniterWot, SmithSubWot);
     type RuntimeEvent = RuntimeEvent;
     type WeightInfo = ();
     #[cfg(feature = "runtime-benchmarks")]
@@ -142,7 +145,6 @@ impl pallet_identity::Config for Test {
 // Membership
 parameter_types! {
     pub const MembershipPeriod: u64 = 8;
-    pub const PendingMembershipPeriod: u64 = 3;
 }
 
 impl pallet_membership::Config<Instance1> for Test {
@@ -154,7 +156,6 @@ impl pallet_membership::Config<Instance1> for Test {
     type OnEvent = DuniterWot;
     type RuntimeEvent = RuntimeEvent;
     type WeightInfo = ();
-    type PendingMembershipPeriod = PendingMembershipPeriod;
     #[cfg(feature = "runtime-benchmarks")]
     type BenchmarkSetupHandler = ();
 }
@@ -199,7 +200,6 @@ impl pallet_duniter_wot::Config<Instance2> for Test {
 // SmithMembership
 parameter_types! {
     pub const SmithMembershipPeriod: u64 = 20;
-    pub const SmithPendingMembershipPeriod: u64 = 3;
 }
 
 impl pallet_membership::Config<Instance2> for Test {
@@ -209,7 +209,6 @@ impl pallet_membership::Config<Instance2> for Test {
     type AccountIdOf = ();
     type MembershipPeriod = SmithMembershipPeriod;
     type OnEvent = SmithSubWot;
-    type PendingMembershipPeriod = SmithPendingMembershipPeriod;
     type WeightInfo = ();
     type RuntimeEvent = RuntimeEvent;
     #[cfg(feature = "runtime-benchmarks")]
@@ -259,8 +258,8 @@ pub fn new_test_ext(
                     next_creatable_identity_on: 0,
                     owner_key: i as u64,
                     old_owner_key: None,
-                    removable_on: 0,
-                    status: pallet_identity::IdtyStatus::Validated,
+                    next_scheduled: 0,
+                    status: pallet_identity::IdtyStatus::Member,
                 },
             })
             .collect(),
diff --git a/pallets/duniter-wot/src/tests.rs b/pallets/duniter-wot/src/tests.rs
index 71a58f5e4ef3cbea37e436063299ff0486c46a3a..3645f1979fca7d946fbddf0b408c7361467d9f3e 100644
--- a/pallets/duniter-wot/src/tests.rs
+++ b/pallets/duniter-wot/src/tests.rs
@@ -14,14 +14,13 @@
 // 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::mock::{Identity, System};
+use crate::mock::*;
 use crate::pallet as pallet_duniter_wot;
-use crate::{mock::*, IdtyRemovalWotReason};
 use codec::Encode;
 use frame_support::instances::{Instance1, Instance2};
 use frame_support::{assert_noop, assert_ok};
 use pallet_identity::{
-    IdtyIndexAccountIdPayload, IdtyName, IdtyStatus, RevocationPayload,
+    IdtyIndexAccountIdPayload, IdtyName, IdtyStatus, RevocationPayload, RevocationReason,
     NEW_OWNER_KEY_PAYLOAD_PREFIX, REVOCATION_PAYLOAD_PREFIX,
 };
 use pallet_membership::MembershipRemovalReason;
@@ -79,28 +78,15 @@ fn test_join_smiths() {
     new_test_ext(5, 3).execute_with(|| {
         run_to_block(2);
 
-        // Dave shoud be able to request smith membership
-        assert_ok!(SmithMembership::request_membership(RuntimeOrigin::signed(
-            4
-        ),));
-        System::assert_has_event(RuntimeEvent::SmithMembership(
-            pallet_membership::Event::PendingMembershipAdded {
-                member: 4,
-                expire_on: 2
-                    + <Test as pallet_membership::Config<Instance2>>::PendingMembershipPeriod::get(
-                    ),
-            },
-        ));
-
-        // Then, Alice should be able to send a smith cert to Dave
+        // Alice should be able to send a smith cert to Dave
         run_to_block(3);
         assert_ok!(SmithCert::add_cert(RuntimeOrigin::signed(1), 1, 4));
 
-        // Then, Bob should be able to send a smith cert to Dave
+        // Bob should be able to send a smith cert to Dave
         run_to_block(4);
         assert_ok!(SmithCert::add_cert(RuntimeOrigin::signed(2), 2, 4));
 
-        // Then, Dave should be able to claim his membership
+        // Dave should be able to claim his membership
         run_to_block(4);
         assert_ok!(SmithMembership::claim_membership(RuntimeOrigin::signed(4),));
         System::assert_has_event(RuntimeEvent::SmithMembership(
@@ -122,7 +108,7 @@ fn test_smith_certs_expirations_should_expire_smith_membership() {
         System::assert_has_event(RuntimeEvent::SmithMembership(
             pallet_membership::Event::MembershipRemoved {
                 member: 1,
-                reason: MembershipRemovalReason::Expired,
+                reason: MembershipRemovalReason::NotEnoughCerts,
             },
         ));
     });
@@ -153,9 +139,9 @@ fn test_smith_member_cant_change_its_idty_address() {
     });
 }
 
-/// members of the smith subwot can not remove their identity
+/// members of the smith subwot can revoke their identity
 #[test]
-fn test_smith_member_cant_revoke_its_idty() {
+fn test_smith_member_can_revoke_its_idty() {
     new_test_ext(5, 3).execute_with(|| {
         run_to_block(2);
 
@@ -165,15 +151,26 @@ fn test_smith_member_cant_revoke_its_idty() {
         };
 
         // Identity 3 can't change it's address
-        assert_noop!(
-            Identity::revoke_identity(
-                RuntimeOrigin::signed(3),
-                3,
-                3,
-                TestSignature(3, (REVOCATION_PAYLOAD_PREFIX, revocation_payload).encode())
-            ),
-            pallet_duniter_wot::Error::<Test, Instance2>::NotAllowedToRemoveIdty
-        );
+        assert_ok!(Identity::revoke_identity(
+            RuntimeOrigin::signed(3),
+            3,
+            3,
+            TestSignature(3, (REVOCATION_PAYLOAD_PREFIX, revocation_payload).encode())
+        ));
+        // membership should be removed
+        System::assert_has_event(RuntimeEvent::Membership(
+            pallet_membership::Event::MembershipRemoved {
+                member: 3,
+                reason: pallet_membership::MembershipRemovalReason::Revoked,
+            },
+        ));
+        // smith membership should be removed as well
+        System::assert_has_event(RuntimeEvent::SmithMembership(
+            pallet_membership::Event::MembershipRemoved {
+                member: 3,
+                reason: pallet_membership::MembershipRemovalReason::Revoked,
+            },
+        ));
     });
 }
 
@@ -197,8 +194,11 @@ fn test_create_idty_ok() {
             receiver: 6,
         }));
 
-        assert_eq!(Identity::identity(6).unwrap().status, IdtyStatus::Created);
-        assert_eq!(Identity::identity(6).unwrap().removable_on, 4);
+        assert_eq!(
+            Identity::identity(6).unwrap().status,
+            IdtyStatus::Unconfirmed
+        );
+        assert_eq!(Identity::identity(6).unwrap().next_scheduled, 2 + 2);
     });
 }
 
@@ -225,15 +225,9 @@ fn test_new_idty_validation() {
             receiver: 6,
         }));
 
-        // Ferdie should not be able to claim membership
-        // assert_noop!(
-        //     Membership::claim_membership(RuntimeOrigin::signed(6)),
-        //     pallet_membership::Error::<Test, Instance1>::xxx
-        // );
-
-        // Anyone should be able to validate Ferdie identity
+        // Ferdie should be able to claim membership
         run_to_block(5);
-        assert_ok!(Identity::validate_identity(RuntimeOrigin::signed(42), 6));
+        assert_ok!(Membership::claim_membership(RuntimeOrigin::signed(6)),);
         System::assert_has_event(RuntimeEvent::Membership(
             pallet_membership::Event::MembershipAdded {
                 member: 6,
@@ -254,8 +248,8 @@ fn test_new_idty_validation() {
                 next_creatable_identity_on: 0,
                 old_owner_key: None,
                 owner_key: 6,
-                removable_on: 0,
-                status: IdtyStatus::Validated,
+                next_scheduled: 0,
+                status: IdtyStatus::Member,
             })
         );
     });
@@ -277,14 +271,6 @@ fn test_confirm_idty_ok() {
             RuntimeOrigin::signed(6),
             IdtyName::from("Ferdie"),
         ));
-        System::assert_has_event(RuntimeEvent::Membership(
-            pallet_membership::Event::PendingMembershipAdded {
-                member: 6,
-                expire_on: 3
-                    + <Test as pallet_membership::Config<Instance1>>::PendingMembershipPeriod::get(
-                    ),
-            },
-        ));
         System::assert_has_event(RuntimeEvent::Identity(
             pallet_identity::Event::IdtyConfirmed {
                 idty_index: 6,
@@ -303,26 +289,37 @@ fn test_revoke_idty() {
     new_test_ext(5, 1).execute_with(|| {
         run_to_block(2);
 
-        // Alice identity can not be revoked because she's smith
-        assert_noop!(
-            Identity::revoke_identity(
-                RuntimeOrigin::signed(1),
-                1,
+        // Alice identity can be revoked
+        assert_ok!(Identity::revoke_identity(
+            RuntimeOrigin::signed(1),
+            1,
+            1,
+            TestSignature(
                 1,
-                TestSignature(
-                    1,
-                    (
-                        REVOCATION_PAYLOAD_PREFIX,
-                        RevocationPayload {
-                            idty_index: 1u32,
-                            genesis_hash: System::block_hash(0),
-                        }
-                    )
-                        .encode()
+                (
+                    REVOCATION_PAYLOAD_PREFIX,
+                    RevocationPayload {
+                        idty_index: 1u32,
+                        genesis_hash: System::block_hash(0),
+                    }
                 )
-            ),
-            pallet_duniter_wot::Error::<Test, Instance2>::NotAllowedToRemoveIdty
-        );
+                    .encode()
+            )
+        ));
+        // her membership should be removed
+        System::assert_has_event(RuntimeEvent::Membership(
+            pallet_membership::Event::MembershipRemoved {
+                member: 1,
+                reason: pallet_membership::MembershipRemovalReason::Revoked,
+            },
+        ));
+        // and her smith membership should be removed as well
+        System::assert_has_event(RuntimeEvent::SmithMembership(
+            pallet_membership::Event::MembershipRemoved {
+                member: 1,
+                reason: pallet_membership::MembershipRemovalReason::Revoked,
+            },
+        ));
 
         // Anyone should be able to submit Bob revocation certificate
         assert_ok!(Identity::revoke_identity(
@@ -343,9 +340,9 @@ fn test_revoke_idty() {
         ));
 
         System::assert_has_event(RuntimeEvent::Identity(
-            pallet_identity::Event::IdtyRemoved {
+            pallet_identity::Event::IdtyRevoked {
                 idty_index: 2,
-                reason: pallet_identity::IdtyRemovalReason::<IdtyRemovalWotReason>::Revoked,
+                reason: pallet_identity::RevocationReason::User,
             },
         ));
     });
@@ -362,8 +359,14 @@ fn test_idty_membership_expire() {
         // Bob renews his membership
         assert_ok!(Membership::renew_membership(RuntimeOrigin::signed(2)));
 
+        run_to_block(5);
+        // renew certifications so that Alice can still issue cert at block 22
+        assert_ok!(Cert::add_cert(RuntimeOrigin::signed(2), 2, 1));
+        assert_ok!(Cert::add_cert(RuntimeOrigin::signed(3), 3, 1));
+
         // Charlie's membership should expire at block #8
         run_to_block(8);
+        assert_ok!(Membership::renew_membership(RuntimeOrigin::signed(1)));
         assert!(Membership::membership(3).is_none());
 
         System::assert_has_event(RuntimeEvent::Membership(
@@ -372,35 +375,53 @@ fn test_idty_membership_expire() {
                 reason: MembershipRemovalReason::Expired,
             },
         ));
-        // membership expiry should not trigger identity removal
-        assert!(!System::events().iter().any(|record| record.event
-            == RuntimeEvent::Identity(pallet_identity::Event::IdtyRemoved {
+        assert_eq!(
+            Identity::identity(3),
+            Some(pallet_identity::IdtyValue {
+                data: (),
+                next_creatable_identity_on: 0,
+                old_owner_key: None,
+                owner_key: 3,
+                next_scheduled: 14, // = 8 (membership removal block) + 6 (auto revocation period)
+                status: IdtyStatus::NotMember,
+            })
+        );
+        // check that identity is added to auto-revoke list (currently IdentityChangeSchedule)
+        assert_eq!(Identity::next_scheduled(14), vec!(3));
+        run_to_block(14);
+        assert_ok!(Membership::renew_membership(RuntimeOrigin::signed(1)));
+        // Charlie's identity should be auto-revoked at block #11 (8 + 3)
+        System::assert_has_event(RuntimeEvent::Identity(
+            pallet_identity::Event::IdtyRevoked {
                 idty_index: 3,
-                reason: pallet_identity::IdtyRemovalReason::Other(
-                    IdtyRemovalWotReason::MembershipExpired
-                )
-            })));
-        // it should be moved to pending membership instead
-        assert!(Membership::pending_membership(3).is_some());
-
-        // then pending membership should expire and identity should finally be removed
-        run_to_block(11);
-        System::assert_has_event(RuntimeEvent::Membership(
-            pallet_membership::Event::PendingMembershipExpired { member: 3 },
+                reason: pallet_identity::RevocationReason::Expired,
+            },
         ));
+        assert_eq!(
+            Identity::identity(3),
+            Some(pallet_identity::IdtyValue {
+                data: (),
+                next_creatable_identity_on: 0,
+                old_owner_key: None,
+                owner_key: 3,
+                next_scheduled: 21, // = 14 (revocation block) + 7 (deletion period)
+                status: IdtyStatus::Revoked,
+            })
+        );
+        // Alice can't certify revoked identity
+        assert_noop!(
+            Cert::add_cert(RuntimeOrigin::signed(1), 1, 3),
+            pallet_duniter_wot::Error::<Test, Instance1>::CertToRevoked
+        );
+
+        run_to_block(21);
         System::assert_has_event(RuntimeEvent::Identity(
             pallet_identity::Event::IdtyRemoved {
                 idty_index: 3,
-                reason: pallet_identity::IdtyRemovalReason::Other(
-                    IdtyRemovalWotReason::MembershipExpired,
-                ),
+                reason: pallet_identity::RemovalReason::Revoked,
             },
         ));
-
-        // Charlie's identity should be removed at block #11
-        assert!(Identity::identity(3).is_none());
-
-        // Alice can't renew her cert to Charlie
+        // Alice can't certify removed identity
         assert_noop!(
             Cert::add_cert(RuntimeOrigin::signed(1), 1, 3),
             pallet_duniter_wot::Error::<Test, Instance1>::IdtyNotFound
@@ -423,10 +444,10 @@ fn test_unvalidated_idty_certs_removal() {
             IdtyName::from("Ferdie"),
         ));
 
-        // After PendingMembershipPeriod, Ferdie identity should expire
-        // and his received certifications should be removed
         assert_eq!(Cert::certs_by_receiver(6).len(), 1);
-        run_to_block(6);
+        // After ValidationPeriod, Ferdie identity should be automatically removed
+        // and his received certifications should be removed
+        run_to_block(8);
         assert_eq!(Cert::certs_by_receiver(6).len(), 0);
     });
 }
@@ -474,7 +495,7 @@ fn test_certification_expire() {
         System::assert_has_event(RuntimeEvent::SmithMembership(
             pallet_membership::Event::MembershipRemoved {
                 member: 1,
-                reason: MembershipRemovalReason::Expired,
+                reason: MembershipRemovalReason::NotEnoughCerts,
             },
         ));
 
@@ -498,7 +519,7 @@ fn test_certification_expire() {
         System::assert_has_event(RuntimeEvent::Membership(
             pallet_membership::Event::MembershipRemoved {
                 member: 1,
-                reason: MembershipRemovalReason::Expired,
+                reason: MembershipRemovalReason::NotEnoughCerts,
             },
         ));
 
@@ -508,7 +529,7 @@ fn test_certification_expire() {
         assert_ok!(Membership::renew_membership(RuntimeOrigin::signed(2)));
         assert_ok!(Membership::renew_membership(RuntimeOrigin::signed(3)));
 
-        // Alice can not renew her membership which does not exist because it is pending
+        // Alice can not renew her membership which does not exist
         assert_noop!(
             Membership::renew_membership(RuntimeOrigin::signed(1)),
             pallet_membership::Error::<Test, Instance1>::MembershipNotFound
@@ -521,19 +542,13 @@ fn test_certification_expire() {
         );
 
         // --- BLOCK 23 ---
-        run_to_block(23);
+        run_to_block(26);
         // println!("{:?}", System::events());
-        // after a delay (3 blocks), the pending membership finally expires
-        System::assert_has_event(RuntimeEvent::Membership(
-            pallet_membership::Event::PendingMembershipExpired { member: 1 },
-        ));
-        // and the identity is removed
+        // after a delay, the non member identity is automatically revoked
         System::assert_has_event(RuntimeEvent::Identity(
-            pallet_identity::Event::IdtyRemoved {
+            pallet_identity::Event::IdtyRevoked {
                 idty_index: 1,
-                reason: pallet_identity::IdtyRemovalReason::Other(
-                    IdtyRemovalWotReason::MembershipExpired,
-                ),
+                reason: RevocationReason::Expired,
             },
         ));
     })
@@ -588,13 +603,12 @@ fn test_cert_can_not_be_issued() {
         System::assert_has_event(RuntimeEvent::SmithMembership(
             pallet_membership::Event::MembershipRemoved {
                 member: 1,
-                reason: MembershipRemovalReason::Expired,
+                reason: MembershipRemovalReason::NotEnoughCerts,
             },
         ));
 
         run_to_block(11);
-        // /!\ COUNTERINTUITIVE BEHAVIOR
-        // Dave should not be able to receive a smith cert since he did not request smith membership
+        // Dave should be able to receive a smith cert since
         assert_ok!(SmithCert::add_cert(RuntimeOrigin::signed(3), 3, 4));
         // Bob renews his smith certification towards Alice
         assert_ok!(SmithCert::add_cert(RuntimeOrigin::signed(2), 2, 1));
@@ -637,7 +651,7 @@ fn test_cert_can_not_be_issued() {
         System::assert_has_event(RuntimeEvent::Membership(
             pallet_membership::Event::MembershipRemoved {
                 member: 1,
-                reason: MembershipRemovalReason::Expired,
+                reason: MembershipRemovalReason::NotEnoughCerts,
             }, // pending membership expires at 23
         ));
 
@@ -655,3 +669,54 @@ fn test_cert_can_not_be_issued() {
         // she would have been able to emit a cert without being member
     })
 }
+
+/// test non smith identity can not emit smith cert
+#[test]
+fn test_non_smith_can_not_issue_smith_cert() {
+    new_test_ext(4, 3).execute_with(|| {
+        assert_noop!(
+            SmithCert::add_cert(RuntimeOrigin::signed(4), 4, 1),
+            pallet_certification::Error::<Test, Instance2>::NotEnoughCertReceived
+        );
+    })
+}
+
+/// FIXME this test should not fail with NotRespectCertPeriod but NotSmith or somthing like that
+/// test non smith identity can not emit smith cert
+#[test]
+fn test_non_smith_with_certs_can_not_issue_smith_cert() {
+    new_test_ext(4, 3).execute_with(|| {
+        run_to_block(2);
+        assert_ok!(SmithCert::add_cert(RuntimeOrigin::signed(1), 1, 4));
+        assert_ok!(SmithCert::add_cert(RuntimeOrigin::signed(2), 2, 4));
+        assert_ok!(SmithCert::add_cert(RuntimeOrigin::signed(3), 3, 4));
+        assert_noop!(
+            SmithCert::add_cert(RuntimeOrigin::signed(4), 4, 1),
+            pallet_certification::Error::<Test, Instance2>::NotRespectCertPeriod
+        );
+    })
+}
+
+/// FIXME this test should not succeed because Dave should not be able to issue cert
+/// after revocation of his smith membership
+/// test non smith identity can not emit smith cert
+#[test]
+fn test_revoked_smith_with_certs_can_not_issue_smith_cert() {
+    new_test_ext(4, 3).execute_with(|| {
+        run_to_block(2);
+        assert_ok!(SmithCert::add_cert(RuntimeOrigin::signed(1), 1, 4));
+        assert_ok!(SmithCert::add_cert(RuntimeOrigin::signed(2), 2, 4));
+        assert_ok!(SmithCert::add_cert(RuntimeOrigin::signed(3), 3, 4));
+        assert_ok!(SmithMembership::claim_membership(RuntimeOrigin::signed(4)));
+        assert_noop!(
+            SmithCert::add_cert(RuntimeOrigin::signed(4), 4, 1),
+            pallet_certification::Error::<Test, Instance2>::NotRespectCertPeriod
+        );
+        run_to_block(4);
+        assert_ok!(SmithCert::add_cert(RuntimeOrigin::signed(4), 4, 1),);
+        run_to_block(5);
+        assert_ok!(SmithMembership::revoke_membership(RuntimeOrigin::signed(4)));
+        run_to_block(6);
+        assert_ok!(SmithCert::add_cert(RuntimeOrigin::signed(4), 4, 1),);
+    })
+}
diff --git a/pallets/duniter-wot/src/types.rs b/pallets/duniter-wot/src/types.rs
deleted file mode 100644
index 2a049f86d03ead978e494605e924b8c7a1c82d19..0000000000000000000000000000000000000000
--- a/pallets/duniter-wot/src/types.rs
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright 2023 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 codec::{Decode, Encode};
-use frame_support::pallet_prelude::*;
-use scale_info::TypeInfo;
-
-#[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo)]
-pub enum IdtyRemovalWotReason {
-    MembershipExpired,
-    Other,
-}
diff --git a/pallets/identity/README.md b/pallets/identity/README.md
index 1d728ed92a602053153a15a3f45e62971fb74eea..e8da9f126f9ff87610106d9323a479af506881e1 100644
--- a/pallets/identity/README.md
+++ b/pallets/identity/README.md
@@ -9,13 +9,15 @@ A Duniter identity contains:
 - its **owner key** (that can change)
 - an optional **old owner key** with the date of the key change
 - a **status** that can be
-  - created (by an existing identity)
-  - confirmed (by owner, comes with a name)
-  - validated (that has become member in the allowed timeframe)
+  - unconfirmed (created by a member identity)
+  - unvalidated (confirmed by owner = given a name)
+  - member (of the main wot)
+  - notmember (of the main wot)
+  - revoked (automatically of manually)
 
 It also contains:
 
-- the block number at which it can emit its **next certification**
+- the block number at which it can emit its **next certification** (TODO distinguish next certification and next identity creation)
 - the block number at which it can be **removed from storage**
 
 It also contains attached data defined by the runtime that can be for example
@@ -24,7 +26,7 @@ It also contains attached data defined by the runtime that can be for example
 
 ### Name
 
-Each identity is declared with a name emited on confirmation event. Duniter keeps a list of identity names hash to ensure unicity. 
+Each identity is declared with a name emited on confirmation event. Duniter keeps a list of identity names hash to ensure unicity.
 
 ### Owner key
 
@@ -40,4 +42,4 @@ The next certification is a rate limit to the emission of certification (and the
 
 ### Revokation
 
-Revoking an identity basically means deleting it.
\ No newline at end of file
+Revoking an identity basically means deleting it.
diff --git a/pallets/identity/src/benchmarking.rs b/pallets/identity/src/benchmarking.rs
index 2ec4a1352222780f506d2b14baf263b1f707f9df..fea88edfd280be3f36bcee60b0f84a66fc8069e2 100644
--- a/pallets/identity/src/benchmarking.rs
+++ b/pallets/identity/src/benchmarking.rs
@@ -40,7 +40,7 @@ struct Account<T: Config> {
     key: T::AccountId,
     index: T::IdtyIndex,
     origin: <T as frame_system::Config>::RuntimeOrigin,
-    name: IdtyName,
+    // name: IdtyName,
 }
 
 // Create and confirm one account using Alice authorized account.
@@ -48,7 +48,10 @@ struct Account<T: Config> {
 // Alice next_creatable_identity_on is reinitialized at the end so several account can be
 // created in a row.
 fn create_one_identity<T: Config>(owner_key: T::AccountId) -> Result<Account<T>, &'static str> {
-    let caller: T::AccountId = Identities::<T>::get(T::IdtyIndex::one()).unwrap().owner_key;
+    // get Alice account to create identity
+    let caller: T::AccountId = Identities::<T>::get(T::IdtyIndex::from(1u32))
+        .unwrap()
+        .owner_key;
     let caller_origin: <T as frame_system::Config>::RuntimeOrigin =
         RawOrigin::Signed(caller.clone()).into();
     let owner_key_origin: <T as frame_system::Config>::RuntimeOrigin =
@@ -57,17 +60,23 @@ fn create_one_identity<T: Config>(owner_key: T::AccountId) -> Result<Account<T>,
     let name = IdtyName("new_identity".into());
     Pallet::<T>::confirm_identity(owner_key_origin.clone(), name.clone())?;
     let idty_index = IdentityIndexOf::<T>::get(&owner_key).unwrap();
+    // make identity member
+    <Identities<T>>::mutate_exists(T::IdtyIndex::from(idty_index), |idty_val_opt| {
+        if let Some(ref mut idty_val) = idty_val_opt {
+            idty_val.status = IdtyStatus::Member;
+        }
+    });
     // Reset next_creatable_identity_on to add more identities with Alice
-    <Identities<T>>::mutate_exists(T::IdtyIndex::one(), |idty_val_opt| {
+    <Identities<T>>::mutate_exists(T::IdtyIndex::from(1u32), |idty_val_opt| {
         if let Some(ref mut idty_val) = idty_val_opt {
             idty_val.next_creatable_identity_on = T::BlockNumber::zero();
         }
     });
     Ok(Account {
         key: owner_key,
-        origin: owner_key_origin,
-        name: name,
         index: idty_index,
+        origin: owner_key_origin,
+        // name: name,
     })
 }
 
@@ -75,19 +84,19 @@ fn create_one_identity<T: Config>(owner_key: T::AccountId) -> Result<Account<T>,
 fn create_dummy_identity<T: Config>(i: u32) -> Result<(), &'static str> {
     let idty_index: T::IdtyIndex = i.into();
     let owner_key: T::AccountId = account("Bob", i, SEED);
-    let removable_on = T::BlockNumber::zero();
+    let next_scheduled = T::BlockNumber::zero();
     let value = IdtyValue {
         data: Default::default(),
         next_creatable_identity_on: T::BlockNumber::zero(),
         old_owner_key: None,
         owner_key: owner_key.clone(),
-        removable_on,
-        status: IdtyStatus::ConfirmedByOwner,
+        next_scheduled,
+        status: IdtyStatus::Unvalidated,
     };
     let name = i.to_le_bytes();
     let idty_name = IdtyName(name.into());
     <Identities<T>>::insert(idty_index, value);
-    IdentitiesRemovableOn::<T>::append(removable_on, (idty_index, IdtyStatus::Created));
+    IdentityChangeSchedule::<T>::append(next_scheduled, idty_index);
     IdentityIndexOf::<T>::insert(owner_key.clone(), idty_index);
     <IdentitiesNames<T>>::insert(idty_name.clone(), idty_index);
     Ok(())
@@ -114,6 +123,8 @@ benchmarks! {
             T::AccountId: From<AccountId32>,
             T::IdtyIndex: From<u32>,
     }
+
+    // create identity
     create_identity {
         let caller: T::AccountId  = Identities::<T>::get(T::IdtyIndex::one()).unwrap().owner_key; // Alice
         let caller_origin: <T as frame_system::Config>::RuntimeOrigin = RawOrigin::Signed(caller.clone()).into();
@@ -125,6 +136,7 @@ benchmarks! {
         assert_has_event::<T>(Event::<T>::IdtyCreated { idty_index: idty_index.unwrap(), owner_key: owner_key }.into());
     }
 
+    // confirm identity
     confirm_identity {
         let caller: T::AccountId  = Identities::<T>::get(T::IdtyIndex::one()).unwrap().owner_key;
         let caller_origin: <T as frame_system::Config>::RuntimeOrigin = RawOrigin::Signed(caller.clone()).into();
@@ -137,26 +149,7 @@ benchmarks! {
         assert_has_event::<T>(Event::<T>::IdtyConfirmed { idty_index: idty_index.unwrap(), owner_key: owner_key, name: IdtyName("new_identity".into()) }.into());
     }
 
-    validate_identity {
-        let index = NextIdtyIndex::<T>::get();
-        let caller: T::AccountId  = Identities::<T>::get(T::IdtyIndex::one()).unwrap().owner_key;
-        let caller_origin: <T as frame_system::Config>::RuntimeOrigin = RawOrigin::Signed(caller.clone()).into();
-        let owner_key: T::AccountId = account("new_identity", 2, SEED);
-        let owner_key_origin: <T as frame_system::Config>::RuntimeOrigin = RawOrigin::Signed(owner_key.clone()).into();
-        let name = IdtyName("new_identity".into());
-        Pallet::<T>::create_identity(caller_origin.clone(), owner_key.clone())?;
-        Pallet::<T>::confirm_identity(owner_key_origin.clone(), name.clone())?;
-        // Should be superior to the minimal number of certificates to gain membership.
-        for j in 0..100 {
-            let issuer: T::IdtyIndex = j.into();
-            T::BenchmarkSetupHandler::add_cert(&issuer, &index);
-        }
-        T::BenchmarkSetupHandler::force_status_ok(&index, &owner_key);
-    }: _<T::RuntimeOrigin>(caller_origin, index.into())
-    verify {
-        assert_has_event::<T>(Event::<T>::IdtyValidated { idty_index: index.into() }.into());
-    }
-
+    // change owner key
     change_owner_key {
         let old_key: T::AccountId = account("new_identity", 2, SEED);
         let account: Account<T> = create_one_identity(old_key.clone())?;
@@ -194,12 +187,13 @@ benchmarks! {
         assert!(IdentityIndexOf::<T>::get(&caller).unwrap() == account.index, "Owner key not changed");
     }
 
+    // revoke identity
     revoke_identity {
         let old_key: T::AccountId = account("new_identity", 2, SEED);
         let account: Account<T> = create_one_identity(old_key.clone())?;
 
         // Change key
-        //  The sufficients for the old key will drop to 0 during benchmark
+        //  The sufficients for the old key will drop to 0 during benchmark (not for revoke, only for remove)
         let genesis_hash = frame_system::Pallet::<T>::block_hash(T::BlockNumber::zero());
         let new_key_payload = IdtyIndexAccountIdPayload {
             genesis_hash: &genesis_hash,
@@ -221,22 +215,9 @@ benchmarks! {
         let signature = sr25519_sign(0.into(), &caller_public, &message).unwrap().into();
     }: _<T::RuntimeOrigin>(account.origin.clone(), account.index.clone().into(), caller.clone(), signature)
     verify {
-        assert_has_event::<T>(Event::<T>::IdtyRemoved { idty_index: account.index, reason: IdtyRemovalReason::Revoked }.into());
-        assert!(IdentityIndexOf::<T>::get(&account.key).is_none(), "Identity not revoked");
-    }
-
-    force_remove_identity {
-        let new_identity: T::AccountId = account("new_identity", 2, SEED);
-        let account: Account<T> = create_one_identity(new_identity)?;
-        let identities = Pallet::<T>::identities_count();
-    }: _<T::RuntimeOrigin>(RawOrigin::Root.into(), account.index.clone(), Some(account.name.clone()), IdtyRemovalReason::Manual)
-    verify {
-        assert!(
-            Pallet::<T>::identities_count() == identities - 1,
-            "Identities not removed"
-        );
-        assert_has_event::<T>(Event::<T>::IdtyRemoved { idty_index: account.index, reason: IdtyRemovalReason::Manual }.into());
-        assert!(IdentityIndexOf::<T>::get(&account.key).is_none(), "Identity not removed");
+        assert_has_event::<T>(Event::<T>::IdtyRevoked { idty_index: account.index, reason: RevocationReason::User }.into());
+        // revocation does not mean deletion anymore
+        // assert!(IdentityIndexOf::<T>::get(&account.key).is_none(), "Identity not revoked");
     }
 
     // The complexity depends on the number of identities to prune
@@ -258,6 +239,7 @@ benchmarks! {
         }
     }
 
+    // fix sufficients identity
     fix_sufficients {
         let new_identity: T::AccountId = account("Bob", 2, SEED);
         let account: Account<T> = create_one_identity(new_identity)?;
@@ -267,6 +249,7 @@ benchmarks! {
         assert!(sufficient < frame_system::Pallet::<T>::sufficients(&account.key), "Sufficient not incremented");
     }
 
+    // link account
     link_account {
         let alice_origin = RawOrigin::Signed(Identities::<T>::get(T::IdtyIndex::one()).unwrap().owner_key);
         let bob_public = sr25519_generate(0.into(), None);
@@ -277,13 +260,36 @@ benchmarks! {
         ).encode();
         let signature = sr25519_sign(0.into(), &bob_public, &payload).unwrap().into();
     }: _<T::RuntimeOrigin>(alice_origin.into(), bob, signature)
+
     // Base weight of an empty initialize
     on_initialize {
     }: {Pallet::<T>::on_initialize(BlockNumberFor::<T>::zero());}
+
+    // --- do revoke identity
+    do_revoke_identity_noop {
+        let idty_index: T::IdtyIndex = 0u32.into();
+        assert!(Identities::<T>::get(idty_index).is_none());
+    }: {Pallet::<T>::do_revoke_identity(idty_index, RevocationReason::Root);}
+    do_revoke_identity {
+        let idty_index: T::IdtyIndex = 1u32.into();
+        let new_identity: T::AccountId = account("Bob", 2, SEED);
+        assert!(Identities::<T>::get(idty_index).is_some());
+        Identities::<T>::mutate( idty_index, |id| {
+            if let Some(id) = id {
+                id.old_owner_key = Some((new_identity, BlockNumberFor::<T>::zero()));
+            }
+        });
+        assert!(Identities::<T>::get(idty_index).unwrap().old_owner_key.is_some());
+    }: {Pallet::<T>::do_revoke_identity(idty_index, RevocationReason::Root);}
+    verify {
+        assert_has_event::<T>(Event::<T>::IdtyRevoked { idty_index, reason: RevocationReason::Root }.into());
+    }
+
+    // --- do remove identity
     do_remove_identity_noop {
         let idty_index: T::IdtyIndex = 0u32.into();
         assert!(Identities::<T>::get(idty_index).is_none());
-    }: {Pallet::<T>::do_remove_identity(idty_index, IdtyRemovalReason::Revoked);}
+    }: {Pallet::<T>::do_remove_identity(idty_index, RemovalReason::Revoked);}
     do_remove_identity {
         let idty_index: T::IdtyIndex = 1u32.into();
         let new_identity: T::AccountId = account("Bob", 2, SEED);
@@ -294,24 +300,27 @@ benchmarks! {
             }
         });
         assert!(Identities::<T>::get(idty_index).unwrap().old_owner_key.is_some());
-    }: {Pallet::<T>::do_remove_identity(idty_index, IdtyRemovalReason::Revoked);}
+    }: {Pallet::<T>::do_remove_identity(idty_index, RemovalReason::Revoked);}
     verify {
-        assert_has_event::<T>(Event::<T>::IdtyRemoved { idty_index, reason: IdtyRemovalReason::Revoked }.into());
+        assert_has_event::<T>(Event::<T>::IdtyRemoved { idty_index, reason: RemovalReason::Revoked }.into());
     }
+
+    // --- prune identities
     prune_identities_noop {
-        assert!(IdentitiesRemovableOn::<T>::try_get(T::BlockNumber::zero()).is_err());
+        assert!(IdentityChangeSchedule::<T>::try_get(T::BlockNumber::zero()).is_err());
     }: {Pallet::<T>::prune_identities(T::BlockNumber::zero());}
+
     prune_identities_none {
         let idty_index: T::IdtyIndex = 100u32.into();
-        IdentitiesRemovableOn::<T>::append(T::BlockNumber::zero(), (idty_index, IdtyStatus::Created));
-        assert!(IdentitiesRemovableOn::<T>::try_get(T::BlockNumber::zero()).is_ok());
+        IdentityChangeSchedule::<T>::append(T::BlockNumber::zero(), idty_index);
+        assert!(IdentityChangeSchedule::<T>::try_get(T::BlockNumber::zero()).is_ok());
         assert!(<Identities<T>>::try_get(idty_index).is_err());
     }: {Pallet::<T>::prune_identities(T::BlockNumber::zero());}
+
     prune_identities_err {
         let idty_index: T::IdtyIndex = 100u32.into();
         create_dummy_identity::<T>(100u32)?;
-        IdentitiesRemovableOn::<T>::append(T::BlockNumber::zero(), (idty_index, IdtyStatus::Created));
-        assert!(<Identities<T>>::get(idty_index).unwrap().status != IdentitiesRemovableOn::<T>::get(T::BlockNumber::zero())[0].1);
+        IdentityChangeSchedule::<T>::append(T::BlockNumber::zero(), idty_index);
     }: {Pallet::<T>::prune_identities(T::BlockNumber::zero());}
 
     impl_benchmark_test_suite!(
@@ -326,8 +335,8 @@ benchmarks! {
                     next_creatable_identity_on: 0,
                     old_owner_key: None,
                     owner_key: account("Alice", 1, SEED),
-                    removable_on: 0,
-                    status: crate::IdtyStatus::Validated,
+                    next_scheduled: 0,
+                    status: crate::IdtyStatus::Member,
                 },
             },
             GenesisIdty {
@@ -338,8 +347,8 @@ benchmarks! {
                     next_creatable_identity_on: 0,
                     old_owner_key: None,
                     owner_key: account("Bob", 1, SEED),
-                    removable_on: 0,
-                    status: crate::IdtyStatus::Created,
+                    next_scheduled: 0,
+                    status: crate::IdtyStatus::Unconfirmed,
                 },
             },
         ]}),
diff --git a/pallets/identity/src/lib.rs b/pallets/identity/src/lib.rs
index e60ab74ace75e67907a355c6831fd93e4e45f990..dcbf64d3bfb98d49fca9f38beb911ae7bd9ca835 100644
--- a/pallets/identity/src/lib.rs
+++ b/pallets/identity/src/lib.rs
@@ -67,18 +67,32 @@ pub mod pallet {
 
     #[pallet::config]
     pub trait Config: frame_system::Config {
-        #[pallet::constant]
         /// Period during which the owner can confirm the new identity.
+        // something like 2 days but this should be done quickly as the first certifier is helping
+        #[pallet::constant]
         type ConfirmPeriod: Get<Self::BlockNumber>;
+        /// Period before which the identity has to be validated (become member).
+        // this is the 2 month period in v1
+        #[pallet::constant]
+        type ValidationPeriod: Get<Self::BlockNumber>;
+        /// Period before which an identity who lost membership is automatically revoked.
+        // this is the 1 year period in v1
+        #[pallet::constant]
+        type AutorevocationPeriod: Get<Self::BlockNumber>;
+        /// Period after which a revoked identity is removed and the keys are freed.
         #[pallet::constant]
+        type DeletionPeriod: Get<Self::BlockNumber>;
         /// Minimum duration between two owner key changes
+        // to avoid stealing the identity without means to revoke
+        #[pallet::constant]
         type ChangeOwnerKeyPeriod: Get<Self::BlockNumber>;
+        /// Minimum duration between the creation of 2 identities by the same creator
+        // it should be greater or equal than the certification period in certification pallet
+        #[pallet::constant]
+        type IdtyCreationPeriod: Get<Self::BlockNumber>;
         /// Management of the authorizations of the different calls.
         /// The default implementation allows everything.
         type CheckIdtyCallAllowed: CheckIdtyCallAllowed<Self>;
-        #[pallet::constant]
-        /// Minimum duration between the creation of 2 identities by the same creator
-        type IdtyCreationPeriod: Get<Self::BlockNumber>;
         /// Custom data to store in each identity
         type IdtyData: Clone
             + Codec
@@ -101,17 +115,12 @@ pub mod pallet {
         type AccountLinker: LinkIdty<Self::AccountId, Self::IdtyIndex>;
         /// Handle logic to validate an identity name
         type IdtyNameValidator: IdtyNameValidator;
-        /// Additional reasons for identity removal
-        type IdtyRemovalOtherReason: Clone + Codec + Debug + Eq + TypeInfo;
         /// On identity confirmed by its owner
         type OnIdtyChange: OnIdtyChange<Self>;
         /// Signing key of a payload
         type Signer: IdentifyAccount<AccountId = Self::AccountId>;
         /// Signature of a payload
         type Signature: Parameter + Verify<Signer = Self::Signer>;
-        /// Handle the logic that removes all identity consumers.
-        /// "identity consumers" meaning all things that rely on the existence of the identity.
-        type RemoveIdentityConsumers: RemoveIdentityConsumers<Self::IdtyIndex>;
         /// Because this pallet emits events, it depends on the runtime's definition of an event.
         type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>;
         /// Type representing the weight of this pallet
@@ -167,11 +176,8 @@ pub mod pallet {
                 let _ = Pallet::<T>::get_next_idty_index();
                 // use instead custom provided index
                 let idty_index = idty.index;
-                if idty.value.removable_on > T::BlockNumber::zero() {
-                    <IdentitiesRemovableOn<T>>::append(
-                        idty.value.removable_on,
-                        (idty_index, idty.value.status),
-                    )
+                if idty.value.next_scheduled > T::BlockNumber::zero() {
+                    <IdentityChangeSchedule<T>>::append(idty.value.next_scheduled, idty_index)
                 }
                 <Identities<T>>::insert(idty_index, idty.value.clone());
                 IdentitiesNames::<T>::insert(idty.name.clone(), idty_index);
@@ -215,9 +221,9 @@ pub mod pallet {
 
     /// maps block number to the list of identities set to be removed at this bloc
     #[pallet::storage]
-    #[pallet::getter(fn removable_on)]
-    pub type IdentitiesRemovableOn<T: Config> =
-        StorageMap<_, Twox64Concat, T::BlockNumber, Vec<(T::IdtyIndex, IdtyStatus)>, ValueQuery>;
+    #[pallet::getter(fn next_scheduled)]
+    pub type IdentityChangeSchedule<T: Config> =
+        StorageMap<_, Twox64Concat, T::BlockNumber, Vec<T::IdtyIndex>, ValueQuery>;
 
     // HOOKS //
 
@@ -256,10 +262,15 @@ pub mod pallet {
             idty_index: T::IdtyIndex,
             new_owner_key: T::AccountId,
         },
+        /// An identity has been revoked.
+        IdtyRevoked {
+            idty_index: T::IdtyIndex,
+            reason: RevocationReason,
+        },
         /// An identity has been removed.
         IdtyRemoved {
             idty_index: T::IdtyIndex,
-            reason: IdtyRemovalReason<T::IdtyRemovalOtherReason>,
+            reason: RemovalReason,
         },
     }
 
@@ -284,35 +295,18 @@ pub mod pallet {
             // Verification phase //
             let who = ensure_signed(origin)?;
 
-            let creator =
-                IdentityIndexOf::<T>::try_get(&who).map_err(|_| Error::<T>::IdtyIndexNotFound)?;
-            let creator_idty_val =
-                Identities::<T>::try_get(creator).map_err(|_| Error::<T>::IdtyNotFound)?;
-
-            if IdentityIndexOf::<T>::contains_key(&owner_key) {
-                return Err(Error::<T>::IdtyAlreadyCreated.into());
-            }
-
-            // run checks for identity creation
-            T::CheckIdtyCallAllowed::check_create_identity(creator)?;
-
             let block_number = frame_system::pallet::Pallet::<T>::block_number();
-
-            if creator_idty_val.next_creatable_identity_on > block_number {
-                return Err(Error::<T>::NotRespectIdtyCreationPeriod.into());
-            }
+            let creator_index = Self::check_create_identity(&who, &owner_key, block_number)?;
 
             // Apply phase //
             frame_system::Pallet::<T>::inc_sufficients(&owner_key);
-            <Identities<T>>::mutate_exists(creator, |idty_val_opt| {
+            <Identities<T>>::mutate_exists(creator_index, |idty_val_opt| {
                 if let Some(ref mut idty_val) = idty_val_opt {
                     idty_val.next_creatable_identity_on =
                         block_number + T::IdtyCreationPeriod::get();
                 }
             });
 
-            let removable_on = block_number + T::ConfirmPeriod::get();
-
             let idty_index = Self::get_next_idty_index();
             <Identities<T>>::insert(
                 idty_index,
@@ -321,17 +315,26 @@ pub mod pallet {
                     next_creatable_identity_on: T::BlockNumber::zero(),
                     old_owner_key: None,
                     owner_key: owner_key.clone(),
-                    removable_on,
-                    status: IdtyStatus::Created,
+                    next_scheduled: Self::schedule_identity_change(
+                        idty_index,
+                        T::ConfirmPeriod::get(),
+                    ),
+                    status: IdtyStatus::Unconfirmed,
                 },
             );
-            IdentitiesRemovableOn::<T>::append(removable_on, (idty_index, IdtyStatus::Created));
+
             IdentityIndexOf::<T>::insert(owner_key.clone(), idty_index);
             Self::deposit_event(Event::IdtyCreated {
                 idty_index,
                 owner_key: owner_key.clone(),
             });
-            T::OnIdtyChange::on_idty_change(idty_index, &IdtyEvent::Created { creator, owner_key });
+            T::OnIdtyChange::on_idty_change(
+                idty_index,
+                &IdtyEvent::Created {
+                    creator: creator_index,
+                    owner_key,
+                },
+            );
             Ok(().into())
         }
 
@@ -352,10 +355,10 @@ pub mod pallet {
             let idty_index =
                 IdentityIndexOf::<T>::try_get(&who).map_err(|_| Error::<T>::IdtyIndexNotFound)?;
 
-            let mut idty_value =
+            let idty_value =
                 Identities::<T>::try_get(idty_index).map_err(|_| Error::<T>::IdtyNotFound)?;
 
-            if idty_value.status != IdtyStatus::Created {
+            if idty_value.status != IdtyStatus::Unconfirmed {
                 return Err(Error::<T>::IdtyAlreadyConfirmed.into());
             }
             if !T::IdtyNameValidator::validate(&idty_name) {
@@ -364,52 +367,21 @@ pub mod pallet {
             if <IdentitiesNames<T>>::contains_key(&idty_name) {
                 return Err(Error::<T>::IdtyNameAlreadyExist.into());
             }
-            T::CheckIdtyCallAllowed::check_confirm_identity(idty_index)?;
 
             // Apply phase //
-            idty_value.status = IdtyStatus::ConfirmedByOwner;
+            Self::update_identity_status(
+                idty_index,
+                idty_value,
+                IdtyStatus::Unvalidated,
+                T::ValidationPeriod::get(),
+            );
 
-            <Identities<T>>::insert(idty_index, idty_value);
             <IdentitiesNames<T>>::insert(idty_name.clone(), idty_index);
             Self::deposit_event(Event::IdtyConfirmed {
                 idty_index,
                 owner_key: who,
                 name: idty_name,
             });
-            T::OnIdtyChange::on_idty_change(idty_index, &IdtyEvent::Confirmed);
-            Ok(().into())
-        }
-
-        #[pallet::call_index(2)]
-        #[pallet::weight(T::WeightInfo::validate_identity())]
-        /// validate the owned identity (must meet the main wot requirements)
-        // automatically claim membership if not done
-        pub fn validate_identity(
-            origin: OriginFor<T>,
-            idty_index: T::IdtyIndex,
-        ) -> DispatchResultWithPostInfo {
-            // Verification phase //
-            let _ = ensure_signed(origin)?;
-
-            let mut idty_value =
-                Identities::<T>::try_get(idty_index).map_err(|_| Error::<T>::IdtyNotFound)?;
-
-            match idty_value.status {
-                IdtyStatus::Created => return Err(Error::<T>::IdtyNotConfirmedByOwner.into()),
-                IdtyStatus::ConfirmedByOwner => {
-                    T::CheckIdtyCallAllowed::check_validate_identity(idty_index)?;
-                }
-                IdtyStatus::Validated => return Err(Error::<T>::IdtyAlreadyValidated.into()),
-            }
-
-            // Apply phase //
-            idty_value.removable_on = T::BlockNumber::zero();
-            idty_value.status = IdtyStatus::Validated;
-
-            <Identities<T>>::insert(idty_index, idty_value);
-            Self::deposit_event(Event::IdtyValidated { idty_index });
-            T::OnIdtyChange::on_idty_change(idty_index, &IdtyEvent::Validated);
-
             Ok(().into())
         }
 
@@ -440,7 +412,7 @@ pub mod pallet {
                 Error::<T>::OwnerKeyAlreadyUsed
             );
 
-            T::CheckIdtyCallAllowed::check_change_identity_address(idty_index)?;
+            T::CheckIdtyCallAllowed::change_owner_key(idty_index)?;
 
             let block_number = frame_system::Pallet::<T>::block_number();
             let maybe_old_old_owner_key =
@@ -486,12 +458,6 @@ pub mod pallet {
                 idty_index,
                 new_owner_key: new_key.clone(),
             });
-            T::OnIdtyChange::on_idty_change(
-                idty_index,
-                &IdtyEvent::ChangedOwnerKey {
-                    new_owner_key: new_key,
-                },
-            );
 
             Ok(().into())
         }
@@ -516,6 +482,14 @@ pub mod pallet {
 
             let idty_value = Identities::<T>::get(idty_index).ok_or(Error::<T>::IdtyNotFound)?;
 
+            match idty_value.status {
+                IdtyStatus::Unconfirmed => return Err(Error::<T>::CanNotRevokeUnconfirmed.into()),
+                IdtyStatus::Unvalidated => return Err(Error::<T>::CanNotRevokeUnvalidated.into()),
+                IdtyStatus::Member => (),
+                IdtyStatus::NotMember => (),
+                IdtyStatus::Revoked => return Err(Error::<T>::AlreadyRevoked.into()),
+            };
+
             ensure!(
                 if let Some((ref old_owner_key, last_change)) = idty_value.old_owner_key {
                     // old owner key can also revoke the identity until the period expired
@@ -529,9 +503,6 @@ pub mod pallet {
                 Error::<T>::InvalidRevocationKey
             );
 
-            // make sure that no wot prevents identity removal
-            T::CheckIdtyCallAllowed::check_remove_identity(idty_index)?;
-
             // then check payload signature
             let genesis_hash = frame_system::Pallet::<T>::block_hash(T::BlockNumber::zero());
             let revocation_payload = RevocationPayload {
@@ -546,26 +517,7 @@ pub mod pallet {
             );
 
             // finally if all checks pass, remove identity
-            Self::do_remove_identity(idty_index, IdtyRemovalReason::Revoked);
-            Ok(().into())
-        }
-
-        #[pallet::call_index(5)]
-        #[pallet::weight(T::WeightInfo::force_remove_identity())]
-        /// remove an identity from storage
-        pub fn force_remove_identity(
-            origin: OriginFor<T>,
-            idty_index: T::IdtyIndex,
-            idty_name: Option<IdtyName>,
-            reason: IdtyRemovalReason<T::IdtyRemovalOtherReason>,
-        ) -> DispatchResultWithPostInfo {
-            ensure_root(origin)?;
-
-            Self::do_remove_identity(idty_index, reason);
-            if let Some(idty_name) = idty_name {
-                <IdentitiesNames<T>>::remove(idty_name);
-            }
-
+            Self::do_revoke_identity(idty_index, RevocationReason::User);
             Ok(().into())
         }
 
@@ -655,13 +607,15 @@ pub mod pallet {
         /// Invalid identity name.
         IdtyNameInvalid,
         /// Identity not confirmed by its owner.
-        IdtyNotConfirmedByOwner,
+        IdtyNotConfirmed,
         /// Identity not found.
         IdtyNotFound,
         /// Invalid payload signature.
         InvalidSignature,
         /// Invalid revocation key.
         InvalidRevocationKey,
+        /// Issuer is not member and can not perform this action
+        IssuerNotMember,
         /// Identity creation period is not respected.
         NotRespectIdtyCreationPeriod,
         /// Owner key already changed recently.
@@ -670,60 +624,103 @@ pub mod pallet {
         OwnerKeyAlreadyUsed,
         /// Reverting to an old key is prohibited.
         ProhibitedToRevertToAnOldKey,
+        /// Already revoked
+        AlreadyRevoked,
+        /// Can not revoke identity that never was member
+        CanNotRevokeUnconfirmed,
+        /// Can not revoke identity that never was member
+        CanNotRevokeUnvalidated,
     }
 
-    // PUBLIC FUNCTIONS //
+    // INTERNAL FUNCTIONS //
 
     impl<T: Config> Pallet<T> {
+        /// get identity count
         pub fn identities_count() -> u32 {
             Identities::<T>::count()
         }
-    }
 
-    // INTERNAL FUNCTIONS //
-
-    impl<T: Config> Pallet<T> {
-        /// try to validate identity
-        // (used when membership is claimed first)
-        pub fn try_validate_identity(idty_index: T::IdtyIndex) {
+        /// membership added
+        // when an identity becomes member, update its status
+        // unschedule identity action, this falls back to membership scheduling
+        // no identity schedule while membership is active
+        pub fn membership_added(idty_index: T::IdtyIndex) {
             if let Some(mut idty_value) = Identities::<T>::get(idty_index) {
-                // only does something if identity is not yet validated
-                if idty_value.status != IdtyStatus::Validated {
-                    idty_value.removable_on = T::BlockNumber::zero();
-                    idty_value.status = IdtyStatus::Validated;
+                Self::unschedule_identity_change(idty_index, idty_value.next_scheduled);
+                idty_value.next_scheduled = T::BlockNumber::zero();
+                idty_value.status = IdtyStatus::Member;
+                <Identities<T>>::insert(idty_index, idty_value);
+                Self::deposit_event(Event::IdtyValidated { idty_index });
+            }
+            // else should not happen
+        }
 
-                    <Identities<T>>::insert(idty_index, idty_value);
-                    Self::deposit_event(Event::IdtyValidated { idty_index });
+        /// membership removed
+        // only does something if identity is actually member
+        // a membership can be removed when the identity is revoked
+        // in this case, this does nothing
+        pub fn membership_removed(idty_index: T::IdtyIndex) {
+            if let Some(idty_value) = Identities::<T>::get(idty_index) {
+                if idty_value.status == IdtyStatus::Member {
+                    Self::update_identity_status(
+                        idty_index,
+                        idty_value,
+                        IdtyStatus::NotMember,
+                        T::AutorevocationPeriod::get(),
+                    );
                 }
-                // already validated, no need to re-validate
             }
+            // else should not happen
         }
 
         /// perform identity removal
-        pub(super) fn do_remove_identity(
-            idty_index: T::IdtyIndex,
-            reason: IdtyRemovalReason<T::IdtyRemovalOtherReason>,
-        ) -> Weight {
-            if let Some(idty_val) = Identities::<T>::get(idty_index) {
-                let _ = T::RemoveIdentityConsumers::remove_idty_consumers(idty_index);
-                IdentityIndexOf::<T>::remove(&idty_val.owner_key);
+        // (kind of garbage collector)
+        // this should not be called while the identity is still member
+        // otherwise there will still be a membership in storage, but no more identity
+        pub fn do_remove_identity(idty_index: T::IdtyIndex, reason: RemovalReason) -> Weight {
+            if let Some(idty_value) = Identities::<T>::get(idty_index) {
+                // this line allows the owner key to be used after that
+                IdentityIndexOf::<T>::remove(&idty_value.owner_key);
                 // Identity should be removed after the consumers of the identity
                 Identities::<T>::remove(idty_index);
-                frame_system::Pallet::<T>::dec_sufficients(&idty_val.owner_key);
-                if let Some((old_owner_key, _last_change)) = idty_val.old_owner_key {
+                frame_system::Pallet::<T>::dec_sufficients(&idty_value.owner_key);
+                if let Some((old_owner_key, _last_change)) = idty_value.old_owner_key {
                     frame_system::Pallet::<T>::dec_sufficients(&old_owner_key);
                 }
                 Self::deposit_event(Event::IdtyRemoved { idty_index, reason });
                 T::OnIdtyChange::on_idty_change(
                     idty_index,
                     &IdtyEvent::Removed {
-                        status: idty_val.status,
+                        status: idty_value.status,
                     },
                 );
                 return T::WeightInfo::do_remove_identity();
             }
             T::WeightInfo::do_remove_identity_noop()
         }
+
+        /// revoke identity
+        pub fn do_revoke_identity(idty_index: T::IdtyIndex, reason: RevocationReason) -> Weight {
+            if let Some(idty_value) = Identities::<T>::get(idty_index) {
+                Self::update_identity_status(
+                    idty_index,
+                    idty_value,
+                    IdtyStatus::Revoked,
+                    T::DeletionPeriod::get(),
+                );
+
+                Self::deposit_event(Event::IdtyRevoked { idty_index, reason });
+                T::OnIdtyChange::on_idty_change(
+                    idty_index,
+                    &IdtyEvent::Removed {
+                        status: IdtyStatus::Revoked,
+                    },
+                );
+                return T::WeightInfo::do_revoke_identity();
+            }
+            T::WeightInfo::do_revoke_identity_noop()
+        }
+
         /// incremental counter for identity index
         fn get_next_idty_index() -> T::IdtyIndex {
             if let Ok(next_index) = <NextIdtyIndex<T>>::try_get() {
@@ -734,15 +731,35 @@ pub mod pallet {
                 T::IdtyIndex::one()
             }
         }
-        /// remove identities planned for removal at the given block if their status did not change
+
+        /// remove identities planned for removal at the given block
         pub fn prune_identities(block_number: T::BlockNumber) -> Weight {
             let mut total_weight = Weight::zero();
 
-            for (idty_index, idty_status) in IdentitiesRemovableOn::<T>::take(block_number) {
+            for idty_index in IdentityChangeSchedule::<T>::take(block_number) {
                 if let Ok(idty_val) = <Identities<T>>::try_get(idty_index) {
-                    if idty_val.removable_on == block_number && idty_val.status == idty_status {
-                        total_weight +=
-                            Self::do_remove_identity(idty_index, IdtyRemovalReason::Expired)
+                    if idty_val.next_scheduled == block_number {
+                        match idty_val.status {
+                            IdtyStatus::Unconfirmed => {
+                                total_weight +=
+                                    Self::do_remove_identity(idty_index, RemovalReason::Unconfirmed)
+                            }
+                            IdtyStatus::Unvalidated => {
+                                total_weight +=
+                                    Self::do_remove_identity(idty_index, RemovalReason::Unvalidated)
+                            }
+                            IdtyStatus::Revoked => {
+                                total_weight +=
+                                    Self::do_remove_identity(idty_index, RemovalReason::Revoked)
+                            }
+                            IdtyStatus::NotMember => {
+                                total_weight +=
+                                    Self::do_revoke_identity(idty_index, RevocationReason::Expired)
+                            }
+                            IdtyStatus::Member => { // do not touch identities of member accounts
+                                 // this should not happen
+                            }
+                        }
                     } else {
                         total_weight += T::WeightInfo::prune_identities_err()
                             .saturating_sub(T::WeightInfo::prune_identities_none())
@@ -761,11 +778,82 @@ pub mod pallet {
             // call account linker
             T::AccountLinker::link_identity(account_id, idty_index);
         }
+
+        /// change identity status and reschedule next action
+        fn update_identity_status(
+            idty_index: T::IdtyIndex,
+            mut idty_value: IdtyValue<T::BlockNumber, T::AccountId, T::IdtyData>,
+            new_status: IdtyStatus,
+            period: T::BlockNumber,
+        ) {
+            Self::unschedule_identity_change(idty_index, idty_value.next_scheduled);
+            idty_value.next_scheduled = Self::schedule_identity_change(idty_index, period);
+            idty_value.status = new_status;
+            <Identities<T>>::insert(idty_index, idty_value);
+        }
+
+        /// unschedule identity change
+        fn unschedule_identity_change(idty_id: T::IdtyIndex, block_number: T::BlockNumber) {
+            let mut scheduled = IdentityChangeSchedule::<T>::get(block_number);
+            if let Some(pos) = scheduled.iter().position(|x| *x == idty_id) {
+                scheduled.swap_remove(pos);
+                IdentityChangeSchedule::<T>::set(block_number, scheduled);
+            }
+        }
+        /// schedule identity change after given period
+        fn schedule_identity_change(
+            idty_id: T::IdtyIndex,
+            period: T::BlockNumber,
+        ) -> T::BlockNumber {
+            let block_number = frame_system::pallet::Pallet::<T>::block_number();
+            let next_scheduled = block_number + period;
+            IdentityChangeSchedule::<T>::append(next_scheduled, idty_id);
+            next_scheduled
+        }
+
+        /// check create identity
+        // first internal checks
+        // then other pallet checks trough trait
+        fn check_create_identity(
+            issuer_key: &T::AccountId,
+            receiver_key: &T::AccountId,
+            block_number: T::BlockNumber,
+        ) -> Result<T::IdtyIndex, DispatchError> {
+            // first get issuer details
+            let creator_index = IdentityIndexOf::<T>::try_get(issuer_key)
+                .map_err(|_| Error::<T>::IdtyIndexNotFound)?;
+            let creator_idty_val =
+                Identities::<T>::try_get(creator_index).map_err(|_| Error::<T>::IdtyNotFound)?;
+
+            // --- some checks can be done internally
+            // 1. issuer is member
+            ensure!(
+                creator_idty_val.status == IdtyStatus::Member,
+                Error::<T>::IssuerNotMember
+            );
+
+            // 2. issuer respects identity creation period
+            ensure!(
+                creator_idty_val.next_creatable_identity_on <= block_number,
+                Error::<T>::NotRespectIdtyCreationPeriod
+            );
+
+            // 3. receiver key is not already used by another identity
+            ensure!(
+                !IdentityIndexOf::<T>::contains_key(receiver_key),
+                Error::<T>::IdtyAlreadyCreated
+            );
+
+            // --- other checks depend on other pallets
+            // run checks for identity creation
+            T::CheckIdtyCallAllowed::check_create_identity(creator_index)?;
+
+            Ok(creator_index)
+        }
     }
 }
 
 // implement getting owner key of identity index
-
 impl<T: Config> sp_runtime::traits::Convert<T::IdtyIndex, Option<T::AccountId>> for Pallet<T> {
     fn convert(idty_index: T::IdtyIndex) -> Option<T::AccountId> {
         Identities::<T>::get(idty_index).map(|idty_val| idty_val.owner_key)
@@ -773,7 +861,6 @@ impl<T: Config> sp_runtime::traits::Convert<T::IdtyIndex, Option<T::AccountId>>
 }
 
 // implement StoredMap trait for this pallet
-
 impl<T> frame_support::traits::StoredMap<T::AccountId, T::IdtyData> for Pallet<T>
 where
     T: Config,
diff --git a/pallets/identity/src/mock.rs b/pallets/identity/src/mock.rs
index 8311e4aa69078a57562a12ce82d278d8eba26fed..9421a70f03547f9b1f426658289cbf9f1b870025 100644
--- a/pallets/identity/src/mock.rs
+++ b/pallets/identity/src/mock.rs
@@ -88,9 +88,10 @@ impl system::Config for Test {
 parameter_types! {
     pub const ChangeOwnerKeyPeriod: u64 = 10;
     pub const ConfirmPeriod: u64 = 2;
+    pub const ValidationPeriod: u64 = 3;
+    pub const AutorevocationPeriod: u64 = 5;
+    pub const DeletionPeriod: u64 = 7;
     pub const IdtyCreationPeriod: u64 = 3;
-    pub const MaxInactivityPeriod: u64 = 5;
-    pub const ValidationPeriod: u64 = 2;
 }
 
 pub struct IdtyNameValidatorTestImpl;
@@ -103,17 +104,18 @@ impl pallet_identity::traits::IdtyNameValidator for IdtyNameValidatorTestImpl {
 impl pallet_identity::Config for Test {
     type ChangeOwnerKeyPeriod = ChangeOwnerKeyPeriod;
     type ConfirmPeriod = ConfirmPeriod;
+    type ValidationPeriod = ValidationPeriod;
+    type AutorevocationPeriod = AutorevocationPeriod;
+    type DeletionPeriod = DeletionPeriod;
     type CheckIdtyCallAllowed = ();
     type IdtyCreationPeriod = IdtyCreationPeriod;
     type IdtyData = ();
     type IdtyNameValidator = IdtyNameValidatorTestImpl;
     type IdtyIndex = u64;
     type AccountLinker = ();
-    type IdtyRemovalOtherReason = ();
     type Signer = AccountPublic;
     type Signature = Signature;
     type OnIdtyChange = ();
-    type RemoveIdentityConsumers = ();
     type RuntimeEvent = RuntimeEvent;
     type WeightInfo = ();
     #[cfg(feature = "runtime-benchmarks")]
diff --git a/pallets/identity/src/tests.rs b/pallets/identity/src/tests.rs
index f112fa173c33fe79a9ebb6446bfe9737caaa3953..7d8c3abc618523f278b2cddcb40e5483b1beeffa 100644
--- a/pallets/identity/src/tests.rs
+++ b/pallets/identity/src/tests.rs
@@ -15,11 +15,7 @@
 // along with Duniter-v2S. If not, see <https://www.gnu.org/licenses/>.
 
 use crate::mock::*;
-use crate::{
-    pallet, Error, GenesisIdty, IdtyIndexAccountIdPayload, IdtyName, IdtyRemovalReason, IdtyValue,
-    RevocationPayload, LINK_IDTY_PAYLOAD_PREFIX, NEW_OWNER_KEY_PAYLOAD_PREFIX,
-    REVOCATION_PAYLOAD_PREFIX,
-};
+use crate::*;
 use codec::Encode;
 use frame_support::dispatch::DispatchResultWithPostInfo;
 use frame_support::{assert_noop, assert_ok};
@@ -58,8 +54,8 @@ fn alice() -> GenesisIdty<Test> {
             next_creatable_identity_on: 0,
             old_owner_key: None,
             owner_key: account(1).id,
-            removable_on: 0,
-            status: crate::IdtyStatus::Validated,
+            next_scheduled: 0,
+            status: crate::IdtyStatus::Member,
         },
     }
 }
@@ -73,8 +69,8 @@ fn bob() -> GenesisIdty<Test> {
             next_creatable_identity_on: 0,
             old_owner_key: None,
             owner_key: account(2).id,
-            removable_on: 0,
-            status: crate::IdtyStatus::Validated,
+            next_scheduled: 0,
+            status: crate::IdtyStatus::Member,
         },
     }
 }
@@ -88,8 +84,8 @@ fn inactive_bob() -> GenesisIdty<Test> {
             next_creatable_identity_on: 0,
             old_owner_key: None,
             owner_key: account(2).id,
-            removable_on: 2,
-            status: crate::IdtyStatus::Validated,
+            next_scheduled: 2,
+            status: crate::IdtyStatus::NotMember,
         },
     }
 }
@@ -112,8 +108,8 @@ fn test_identity_index() {
     })
     .execute_with(|| {
         assert_eq!(Identity::identities_count(), 2);
-        // assert_eq!(NextIdtyIndex, 3); // TODO see if we can debug that
-        // TODO create identity and check it was incremented
+        // assert_eq!(NextIdtyIndex, 3); // TODO check how to test that
+        // ... create identity and check it was incremented
     });
 }
 
@@ -154,12 +150,12 @@ fn test_create_identity_but_not_confirm_it() {
             account(2).id
         ));
 
-        // The identity shoud expire in blocs #3
+        // The identity should expire in blocs #3
         run_to_block(3);
 
         System::assert_has_event(RuntimeEvent::Identity(crate::Event::IdtyRemoved {
             idty_index: 2,
-            reason: IdtyRemovalReason::<()>::Expired,
+            reason: RemovalReason::Unconfirmed,
         }));
 
         // We shoud be able to recreate the identity
@@ -304,8 +300,8 @@ fn test_change_owner_key() {
                 next_creatable_identity_on: 0,
                 old_owner_key: Some((account(1).id, 1)),
                 owner_key: account(10).id,
-                removable_on: 0,
-                status: crate::IdtyStatus::Validated,
+                next_scheduled: 0,
+                status: crate::IdtyStatus::Member,
             })
         );
         // Alice still sufficient
@@ -364,10 +360,10 @@ fn test_change_owner_key() {
                     .encode()
             )
         ));
-        // Old owner key should not be sufficient anymore
-        assert_eq!(System::sufficients(&account(10).id), 0);
-        // Last owner key should not be sufficient anymore
-        assert_eq!(System::sufficients(&account(100).id), 0);
+        // Old owner key is still sufficient (identity is revoked but not removed)
+        assert_eq!(System::sufficients(&account(10).id), 1);
+        // Last owner key should still be sufficient  (identity is revoked but not removed)
+        assert_eq!(System::sufficients(&account(100).id), 1);
     });
 }
 
@@ -586,17 +582,23 @@ fn test_idty_revocation() {
             )
         ));
 
-        System::assert_has_event(RuntimeEvent::System(frame_system::Event::KilledAccount {
-            account: account(1).id,
-        }));
-        System::assert_has_event(RuntimeEvent::Identity(crate::Event::IdtyRemoved {
+        // // account is not killed anymore for revoked identity
+        // System::assert_has_event(RuntimeEvent::System(frame_system::Event::KilledAccount {
+        //     account: account(1).id,
+        // }));
+        // // identity is not removed immediately after revocation
+        // System::assert_has_event(RuntimeEvent::Identity(crate::Event::IdtyRemoved {
+        //     idty_index: 1,
+        //     reason: RemovalReason::Revoked,
+        // }));
+        System::assert_has_event(RuntimeEvent::Identity(crate::Event::IdtyRevoked {
             idty_index: 1,
-            reason: IdtyRemovalReason::<()>::Revoked,
+            reason: RevocationReason::User,
         }));
 
         run_to_block(2);
 
-        // The identity no longer exists
+        // The identity can not be revoked multiple times
         assert_eq!(
             Identity::revoke_identity(
                 RuntimeOrigin::signed(account(1).id),
@@ -607,7 +609,7 @@ fn test_idty_revocation() {
                     (REVOCATION_PAYLOAD_PREFIX, revocation_payload).encode()
                 )
             ),
-            Err(Error::<Test>::IdtyNotFound.into())
+            Err(Error::<Test>::AlreadyRevoked.into())
         );
     });
 }
@@ -629,16 +631,17 @@ fn test_inactive_genesis_members() {
         // alice identity remains untouched
         assert!(pallet::Identities::<Test>::get(alice.index).is_some());
         assert!(pallet::IdentityIndexOf::<Test>::get(&alice.value.owner_key).is_some());
-        // but bob identity has been removed
-        assert!(pallet::Identities::<Test>::get(bob.index).is_none());
-        assert!(pallet::IdentityIndexOf::<Test>::get(&bob.value.owner_key).is_none());
+        // but bob identity has been revoked
+        assert!(pallet::Identities::<Test>::get(bob.index).is_some());
+        assert!(pallet::IdentityIndexOf::<Test>::get(&bob.value.owner_key).is_some());
 
-        System::assert_has_event(RuntimeEvent::Identity(crate::Event::IdtyRemoved {
+        System::assert_has_event(RuntimeEvent::Identity(crate::Event::IdtyRevoked {
             idty_index: bob.index,
-            reason: IdtyRemovalReason::Expired,
+            reason: RevocationReason::Expired,
         }));
     });
 }
+
 #[test]
 fn test_revocation_of_genesis_member() {
     let alice = alice();
@@ -660,13 +663,13 @@ fn test_revocation_of_genesis_member() {
         // alice identity remains untouched
         assert!(pallet::Identities::<Test>::get(alice.index).is_some());
         assert!(pallet::IdentityIndexOf::<Test>::get(&alice.value.owner_key).is_some());
-        // but bob identity has been removed
-        assert!(pallet::Identities::<Test>::get(bob.index).is_none());
-        assert!(pallet::IdentityIndexOf::<Test>::get(&bob.value.owner_key).is_none());
+        // but bob identity has been revoked
+        assert!(pallet::Identities::<Test>::get(bob.index).is_some());
+        assert!(pallet::IdentityIndexOf::<Test>::get(&bob.value.owner_key).is_some());
 
-        System::assert_has_event(RuntimeEvent::Identity(crate::Event::IdtyRemoved {
+        System::assert_has_event(RuntimeEvent::Identity(crate::Event::IdtyRevoked {
             idty_index: bob.index,
-            reason: IdtyRemovalReason::Revoked,
+            reason: RevocationReason::User, // because called manually by revoke_self_identity
         }));
     });
 }
@@ -689,3 +692,5 @@ fn revoke_self_identity(idty: GenesisIdty<Test>) -> DispatchResultWithPostInfo {
         ),
     )
 }
+
+// TODO add tests for all periods (confirmation, validation, autorevocation, deletion)
diff --git a/pallets/identity/src/traits.rs b/pallets/identity/src/traits.rs
index 536208cd062539f7d89fad8294f69ff07c9eddf7..a152bd39c13c00bb67ad08cece0bb4d9d49c1c11 100644
--- a/pallets/identity/src/traits.rs
+++ b/pallets/identity/src/traits.rs
@@ -20,10 +20,7 @@ use impl_trait_for_tuples::impl_for_tuples;
 
 pub trait CheckIdtyCallAllowed<T: Config> {
     fn check_create_identity(creator: T::IdtyIndex) -> Result<(), DispatchError>;
-    fn check_confirm_identity(idty_index: T::IdtyIndex) -> Result<(), DispatchError>;
-    fn check_validate_identity(idty_index: T::IdtyIndex) -> Result<(), DispatchError>;
-    fn check_change_identity_address(idty_index: T::IdtyIndex) -> Result<(), DispatchError>;
-    fn check_remove_identity(idty_index: T::IdtyIndex) -> Result<(), DispatchError>;
+    fn change_owner_key(idty_index: T::IdtyIndex) -> Result<(), DispatchError>;
 }
 
 #[impl_for_tuples(5)]
@@ -32,20 +29,8 @@ impl<T: Config> CheckIdtyCallAllowed<T> for Tuple {
         for_tuples!( #( Tuple::check_create_identity(creator)?; )* );
         Ok(())
     }
-    fn check_confirm_identity(idty_index: T::IdtyIndex) -> Result<(), DispatchError> {
-        for_tuples!( #( Tuple::check_confirm_identity(idty_index)?; )* );
-        Ok(())
-    }
-    fn check_validate_identity(idty_index: T::IdtyIndex) -> Result<(), DispatchError> {
-        for_tuples!( #( Tuple::check_validate_identity(idty_index)?; )* );
-        Ok(())
-    }
-    fn check_change_identity_address(idty_index: T::IdtyIndex) -> Result<(), DispatchError> {
-        for_tuples!( #( Tuple::check_change_identity_address(idty_index)?; )* );
-        Ok(())
-    }
-    fn check_remove_identity(idty_index: T::IdtyIndex) -> Result<(), DispatchError> {
-        for_tuples!( #( Tuple::check_remove_identity(idty_index)?; )* );
+    fn change_owner_key(idty_index: T::IdtyIndex) -> Result<(), DispatchError> {
+        for_tuples!( #( Tuple::change_owner_key(idty_index)?; )* );
         Ok(())
     }
 }
@@ -66,15 +51,6 @@ impl<T: Config> OnIdtyChange<T> for Tuple {
     }
 }
 
-pub trait RemoveIdentityConsumers<IndtyIndex> {
-    fn remove_idty_consumers(idty_index: IndtyIndex) -> Weight;
-}
-impl<IndtyIndex> RemoveIdentityConsumers<IndtyIndex> for () {
-    fn remove_idty_consumers(_: IndtyIndex) -> Weight {
-        Weight::zero()
-    }
-}
-
 /// trait used to link an account to an identity
 pub trait LinkIdty<AccountId, IdtyIndex> {
     fn link_identity(account_id: AccountId, idty_index: IdtyIndex);
diff --git a/pallets/identity/src/types.rs b/pallets/identity/src/types.rs
index f497ac34d7a8b34e09e609143208949d380d846f..20120f25c68a99791db7ca3ef76b2d0b26ad0b97 100644
--- a/pallets/identity/src/types.rs
+++ b/pallets/identity/src/types.rs
@@ -23,28 +23,44 @@ use scale_info::TypeInfo;
 use serde::{Deserialize, Serialize};
 use sp_std::vec::Vec;
 
-/// events related to identity
+/// internal events related to identity
 pub enum IdtyEvent<T: crate::Config> {
+    /// IdtyEvent::Created
     /// creation of a new identity by an other
+    // pallet account links account to identity
+    // pallet wot adds certification
+    // pallet quota adds storage item for this identity
     Created {
         creator: T::IdtyIndex,
         owner_key: T::AccountId,
     },
-    /// confirmation of an identity (with a given name)
-    Confirmed,
-    /// validation of an identity
-    Validated,
-    /// changing the owner key of the identity
-    ChangedOwnerKey { new_owner_key: T::AccountId },
-    /// removing an identity
+    /// IdtyEvent::Removed
+    /// removing an identity (unvalidated or revoked)
+    // pallet wot removes associated certifications if status is not revoked
+    // pallet quota removes associated quota
     Removed { status: IdtyStatus },
+    // TODO add a way to unlink accounts corresponding to revoked or removed identities
 }
 
 #[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo)]
-pub enum IdtyRemovalReason<OtherReason: TypeInfo + Decode + Encode + Eq + Clone> {
+pub enum RevocationReason {
+    /// revoked by root (e.g. governance or migration)
+    Root,
+    /// revoked by user action (revocation document)
+    User,
+    /// revoked due to inactive period
     Expired,
-    Manual,
-    Other(OtherReason),
+}
+
+#[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo)]
+pub enum RemovalReason {
+    /// removed by root
+    Root,
+    /// removed because unconfirmed
+    Unconfirmed,
+    /// removed because unvalidated
+    Unvalidated,
+    /// removed automatically after revocation buffer
     Revoked,
 }
 
@@ -85,20 +101,22 @@ impl<'de> serde::Deserialize<'de> for IdtyName {
 }
 
 /// status of the identity
-/// used for temporary period before validation
-/// also used for buffer when losing membership before being deleted
+// this is a kind of index to tell the state of the identity
 #[cfg_attr(feature = "std", derive(Deserialize, Serialize))]
 #[derive(Encode, Decode, Default, Clone, Copy, PartialEq, Eq, RuntimeDebug, TypeInfo)]
 pub enum IdtyStatus {
-    /// created through a first certification
+    /// created through a first certification but unconfirmed
     #[default]
-    Created,
-    /// confirmed by owner with a name published
-    ConfirmedByOwner,
-    /// validated by the main web of trust
-    Validated,
-    // disabled by the main web of trust, deletion planned
-    // Disabled,
+    Unconfirmed,
+    /// confirmed by key owner with a name published but unvalidated
+    Unvalidated,
+    /// member of the main web of trust
+    // (there must be a membership in membership pallet storage)
+    Member,
+    /// not member of the main web of trust, auto-revocation planned
+    NotMember,
+    /// revoked manually or automatically, deletion possible
+    Revoked,
 }
 
 /// identity value (as in key/value)
@@ -114,10 +132,9 @@ pub struct IdtyValue<BlockNumber, AccountId, IdtyData> {
     pub old_owner_key: Option<(AccountId, BlockNumber)>,
     /// current owner key of this identity
     pub owner_key: AccountId,
-    /// block before which this identity can not be removed
-    /// used only for temporary period before validation
-    /// equals 0 for a validated identity
-    pub removable_on: BlockNumber,
+    /// next action scheduled on identity
+    // 0 if no action scheduled
+    pub next_scheduled: BlockNumber,
     /// current status of the identity (until validation)
     pub status: IdtyStatus,
 }
diff --git a/pallets/identity/src/weights.rs b/pallets/identity/src/weights.rs
index 729d3a8ef0343105ca762fc0dc0de8207532a5cd..ee07fdec978c74ce96b9b7f70f25c263b8e50fa5 100644
--- a/pallets/identity/src/weights.rs
+++ b/pallets/identity/src/weights.rs
@@ -18,18 +18,17 @@
 
 use frame_support::weights::{constants::RocksDbWeight, Weight};
 
-/// Weight functions needed for pallet_universal_dividend.
 pub trait WeightInfo {
     fn create_identity() -> Weight;
     fn confirm_identity() -> Weight;
-    fn validate_identity() -> Weight;
     fn change_owner_key() -> Weight;
     fn revoke_identity() -> Weight;
-    fn force_remove_identity() -> Weight;
     fn prune_item_identities_names(i: u32) -> Weight;
     fn fix_sufficients() -> Weight;
     fn link_account() -> Weight;
     fn on_initialize() -> Weight;
+    fn do_revoke_identity_noop() -> Weight;
+    fn do_revoke_identity() -> Weight;
     fn do_remove_identity_noop() -> Weight;
     fn do_remove_identity() -> Weight;
     fn prune_identities_noop() -> Weight;
@@ -39,183 +38,149 @@ pub trait WeightInfo {
 
 // Insecure weights implementation, use it for tests only!
 impl WeightInfo for () {
-    // Storage: Identity IdentityIndexOf (r:2 w:1)
-    // Storage: Identity Identities (r:2 w:2)
-    // Storage: Cert StorageIdtyCertMeta (r:2 w:2)
-    // Storage: Parameters ParametersStorage (r:1 w:0)
-    // Storage: System Account (r:1 w:1)
-    // Storage: Identity NextIdtyIndex (r:1 w:1)
-    // Storage: Identity CounterForIdentities (r:1 w:1)
-    // Storage: Identity IdentitiesRemovableOn (r:1 w:1)
-    // Storage: Cert StorageCertsRemovableOn (r:1 w:1)
-    // Storage: Cert CertsByReceiver (r:1 w:1)
     fn create_identity() -> Weight {
-        // Minimum execution time: 440_987 nanoseconds.
-        Weight::from_parts(462_747_000 as u64, 0)
-            .saturating_add(RocksDbWeight::get().reads(13 as u64))
-            .saturating_add(RocksDbWeight::get().writes(11 as u64))
+        // Proof Size summary in bytes:
+        //  Measured:  `1165`
+        //  Estimated: `7105`
+        // Minimum execution time: 1_643_969_000 picoseconds.
+        Weight::from_parts(1_781_521_000, 0)
+            .saturating_add(Weight::from_parts(0, 7105))
+            .saturating_add(RocksDbWeight::get().reads(14))
+            .saturating_add(RocksDbWeight::get().writes(12))
     }
-    // Storage: Identity IdentityIndexOf (r:1 w:0)
-    // Storage: Identity Identities (r:1 w:1)
-    // Storage: Identity IdentitiesNames (r:1 w:1)
-    // Storage: Membership PendingMembership (r:1 w:1)
-    // Storage: Membership Membership (r:1 w:0)
-    // Storage: Parameters ParametersStorage (r:1 w:0)
-    // Storage: Membership PendingMembershipsExpireOn (r:1 w:1)
     fn confirm_identity() -> Weight {
-        // Minimum execution time: 186_617 nanoseconds.
-        Weight::from_parts(309_527_000 as u64, 0)
-            .saturating_add(RocksDbWeight::get().reads(7 as u64))
-            .saturating_add(RocksDbWeight::get().writes(4 as u64))
-    }
-    // Storage: Identity Identities (r:1 w:1)
-    // Storage: Membership Membership (r:1 w:1)
-    // Storage: Cert StorageIdtyCertMeta (r:1 w:0)
-    // Storage: Parameters ParametersStorage (r:1 w:0)
-    // Storage: Membership PendingMembership (r:1 w:1)
-    // Storage: Membership CounterForMembership (r:1 w:1)
-    // Storage: Membership MembershipsExpireOn (r:1 w:1)
-    // Storage: UniversalDividend CurrentUdIndex (r:1 w:0)
-    fn validate_identity() -> Weight {
-        // Minimum execution time: 299_920 nanoseconds.
-        Weight::from_parts(320_025_000 as u64, 0)
-            .saturating_add(RocksDbWeight::get().reads(8 as u64))
-            .saturating_add(RocksDbWeight::get().writes(5 as u64))
+        // Proof Size summary in bytes:
+        //  Measured:  `661`
+        //  Estimated: `6601`
+        // Minimum execution time: 564_892_000 picoseconds.
+        Weight::from_parts(588_761_000, 0)
+            .saturating_add(Weight::from_parts(0, 6601))
+            .saturating_add(RocksDbWeight::get().reads(5))
+            .saturating_add(RocksDbWeight::get().writes(4))
     }
-    // Storage: Identity IdentityIndexOf (r:2 w:2)
-    // Storage: Identity Identities (r:1 w:1)
-    // Storage: SmithMembership Membership (r:1 w:0)
-    // Storage: System BlockHash (r:1 w:0)
-    // Storage: System Account (r:1 w:1)
-    // Storage: AuthorityMembers Members (r:1 w:0)
     fn change_owner_key() -> Weight {
-        // Minimum execution time: 442_260 nanoseconds.
-        Weight::from_parts(728_714_000 as u64, 0)
-            .saturating_add(RocksDbWeight::get().reads(7 as u64))
-            .saturating_add(RocksDbWeight::get().writes(4 as u64))
+        // Proof Size summary in bytes:
+        //  Measured:  `837`
+        //  Estimated: `6777`
+        // Minimum execution time: 991_641_000 picoseconds.
+        Weight::from_parts(1_071_332_000, 0)
+            .saturating_add(Weight::from_parts(0, 6777))
+            .saturating_add(RocksDbWeight::get().reads(7))
+            .saturating_add(RocksDbWeight::get().writes(5))
     }
-    // Storage: Identity Identities (r:1 w:1)
-    // Storage: SmithMembership Membership (r:1 w:0)
-    // Storage: System BlockHash (r:1 w:0)
-    // Storage: Membership Membership (r:1 w:1)
-    // Storage: Identity CounterForIdentities (r:1 w:1)
-    // Storage: System Account (r:1 w:1)
-    // Storage: Cert CertsByReceiver (r:1 w:1)
-    // Storage: Cert StorageIdtyCertMeta (r:2 w:2)
-    // Storage: Parameters ParametersStorage (r:1 w:0)
-    // Storage: Identity IdentityIndexOf (r:0 w:1)
     fn revoke_identity() -> Weight {
-        // Minimum execution time: 494_407 nanoseconds.
-        Weight::from_parts(800_824_000 as u64, 0)
-            .saturating_add(RocksDbWeight::get().reads(10 as u64))
-            .saturating_add(RocksDbWeight::get().writes(8 as u64))
-    }
-    // Storage: Identity Identities (r:1 w:1)
-    // Storage: SmithMembership Membership (r:1 w:0)
-    // Storage: Membership Membership (r:1 w:1)
-    // Storage: Identity CounterForIdentities (r:1 w:1)
-    // Storage: System Account (r:1 w:1)
-    // Storage: Cert CertsByReceiver (r:1 w:1)
-    // Storage: Cert StorageIdtyCertMeta (r:2 w:2)
-    // Storage: Parameters ParametersStorage (r:1 w:0)
-    // Storage: Identity IdentityIndexOf (r:0 w:1)
-    // Storage: Identity IdentitiesNames (r:0 w:1)
-    fn force_remove_identity() -> Weight {
-        // Minimum execution time: 302_574 nanoseconds.
-        Weight::from_parts(504_132_000 as u64, 0)
-            .saturating_add(RocksDbWeight::get().reads(9 as u64))
-            .saturating_add(RocksDbWeight::get().writes(9 as u64))
+        // Proof Size summary in bytes:
+        //  Measured:  `778`
+        //  Estimated: `6718`
+        // Minimum execution time: 829_174_000 picoseconds.
+        Weight::from_parts(869_308_000, 0)
+            .saturating_add(Weight::from_parts(0, 6718))
+            .saturating_add(RocksDbWeight::get().reads(6))
+            .saturating_add(RocksDbWeight::get().writes(6))
     }
-    // Storage: Identity IdentitiesNames (r:0 w:20)
-    /// The range of component `i` is `[1, 1000]`.
     fn prune_item_identities_names(i: u32) -> Weight {
-        // Minimum execution time: 22_533 nanoseconds.
-        Weight::from_parts(282_674_421 as u64, 0)
-            // Standard Error: 170_391
-            .saturating_add(Weight::from_parts(5_660_460 as u64, 0).saturating_mul(i as u64))
-            .saturating_add(RocksDbWeight::get().writes((1 as u64).saturating_mul(i as u64)))
+        // Proof Size summary in bytes:
+        //  Measured:  `0`
+        //  Estimated: `0`
+        // Minimum execution time: 51_362_000 picoseconds.
+        Weight::from_parts(80_389_000, 0)
+            .saturating_add(Weight::from_parts(0, 0))
+            // Standard Error: 75_232
+            .saturating_add(Weight::from_parts(30_016_649, 0).saturating_mul(i.into()))
+            .saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(i.into())))
     }
-    // Storage: System Account (r:1 w:1)
     fn fix_sufficients() -> Weight {
-        // Minimum execution time: 112_793 nanoseconds.
-        Weight::from_parts(122_192_000 as u64, 0)
-            .saturating_add(RocksDbWeight::get().reads(1 as u64))
-            .saturating_add(RocksDbWeight::get().writes(1 as u64))
+        // Proof Size summary in bytes:
+        //  Measured:  `67`
+        //  Estimated: `3591`
+        // Minimum execution time: 154_343_000 picoseconds.
+        Weight::from_parts(156_117_000, 0)
+            .saturating_add(Weight::from_parts(0, 3591))
+            .saturating_add(RocksDbWeight::get().reads(1))
+            .saturating_add(RocksDbWeight::get().writes(1))
     }
-    /// Storage: Identity IdentityIndexOf (r:1 w:0)
-    /// Proof Skipped: Identity IdentityIndexOf (max_values: None, max_size: None, mode: Measured)
-    /// Storage: System BlockHash (r:1 w:0)
-    /// Proof: System BlockHash (max_values: None, max_size: Some(44), added: 2519, mode: MaxEncodedLen)
-    /// Storage: System Account (r:1 w:1)
-    /// Proof: System Account (max_values: None, max_size: Some(126), added: 2601, mode: MaxEncodedLen)
     fn link_account() -> Weight {
         // Proof Size summary in bytes:
-        //  Measured:  `359`
-        //  Estimated: `3824`
-        // Minimum execution time: 543_046_000 picoseconds.
-        Weight::from_parts(544_513_000, 0)
-            .saturating_add(Weight::from_parts(0, 3824))
+        //  Measured:  `307`
+        //  Estimated: `3772`
+        // Minimum execution time: 538_773_000 picoseconds.
+        Weight::from_parts(591_354_000, 0)
+            .saturating_add(Weight::from_parts(0, 3772))
             .saturating_add(RocksDbWeight::get().reads(3))
             .saturating_add(RocksDbWeight::get().writes(1))
     }
     fn on_initialize() -> Weight {
         // Proof Size summary in bytes:
-        //  Measured:  `359`
-        //  Estimated: `3824`
-        // Minimum execution time: 543_046_000 picoseconds.
-        Weight::from_parts(544_513_000, 0)
-            .saturating_add(Weight::from_parts(0, 3824))
-            .saturating_add(RocksDbWeight::get().reads(3))
-            .saturating_add(RocksDbWeight::get().writes(1))
+        //  Measured:  `0`
+        //  Estimated: `0`
+        // Minimum execution time: 4_529_000 picoseconds.
+        Weight::from_parts(7_360_000, 0).saturating_add(Weight::from_parts(0, 0))
+    }
+    fn do_revoke_identity_noop() -> Weight {
+        // Proof Size summary in bytes:
+        //  Measured:  `269`
+        //  Estimated: `3734`
+        // Minimum execution time: 103_668_000 picoseconds.
+        Weight::from_parts(107_679_000, 0)
+            .saturating_add(Weight::from_parts(0, 3734))
+            .saturating_add(RocksDbWeight::get().reads(1))
+    }
+    fn do_revoke_identity() -> Weight {
+        // Proof Size summary in bytes:
+        //  Measured:  `1525`
+        //  Estimated: `7465`
+        // Minimum execution time: 2_204_911_000 picoseconds.
+        Weight::from_parts(2_225_493_000, 0)
+            .saturating_add(Weight::from_parts(0, 7465))
+            .saturating_add(RocksDbWeight::get().reads(17))
+            .saturating_add(RocksDbWeight::get().writes(20))
     }
     fn do_remove_identity_noop() -> Weight {
         // Proof Size summary in bytes:
-        //  Measured:  `359`
-        //  Estimated: `3824`
-        // Minimum execution time: 543_046_000 picoseconds.
-        Weight::from_parts(544_513_000, 0)
-            .saturating_add(Weight::from_parts(0, 3824))
-            .saturating_add(RocksDbWeight::get().reads(3))
-            .saturating_add(RocksDbWeight::get().writes(1))
+        //  Measured:  `269`
+        //  Estimated: `3734`
+        // Minimum execution time: 104_296_000 picoseconds.
+        Weight::from_parts(115_316_000, 0)
+            .saturating_add(Weight::from_parts(0, 3734))
+            .saturating_add(RocksDbWeight::get().reads(1))
     }
     fn do_remove_identity() -> Weight {
         // Proof Size summary in bytes:
-        //  Measured:  `359`
-        //  Estimated: `3824`
-        // Minimum execution time: 543_046_000 picoseconds.
-        Weight::from_parts(544_513_000, 0)
-            .saturating_add(Weight::from_parts(0, 3824))
-            .saturating_add(RocksDbWeight::get().reads(3))
-            .saturating_add(RocksDbWeight::get().writes(1))
+        //  Measured:  `1432`
+        //  Estimated: `6192`
+        // Minimum execution time: 2_870_497_000 picoseconds.
+        Weight::from_parts(4_159_994_000, 0)
+            .saturating_add(Weight::from_parts(0, 6192))
+            .saturating_add(RocksDbWeight::get().reads(16))
+            .saturating_add(RocksDbWeight::get().writes(22))
     }
     fn prune_identities_noop() -> Weight {
         // Proof Size summary in bytes:
-        //  Measured:  `359`
-        //  Estimated: `3824`
-        // Minimum execution time: 543_046_000 picoseconds.
-        Weight::from_parts(544_513_000, 0)
-            .saturating_add(Weight::from_parts(0, 3824))
-            .saturating_add(RocksDbWeight::get().reads(3))
-            .saturating_add(RocksDbWeight::get().writes(1))
+        //  Measured:  `108`
+        //  Estimated: `3573`
+        // Minimum execution time: 68_859_000 picoseconds.
+        Weight::from_parts(71_836_000, 0)
+            .saturating_add(Weight::from_parts(0, 3573))
+            .saturating_add(RocksDbWeight::get().reads(1))
     }
     fn prune_identities_none() -> Weight {
         // Proof Size summary in bytes:
-        //  Measured:  `359`
-        //  Estimated: `3824`
-        // Minimum execution time: 543_046_000 picoseconds.
-        Weight::from_parts(544_513_000, 0)
-            .saturating_add(Weight::from_parts(0, 3824))
-            .saturating_add(RocksDbWeight::get().reads(3))
+        //  Measured:  `292`
+        //  Estimated: `3757`
+        // Minimum execution time: 178_332_000 picoseconds.
+        Weight::from_parts(186_982_000, 0)
+            .saturating_add(Weight::from_parts(0, 3757))
+            .saturating_add(RocksDbWeight::get().reads(2))
             .saturating_add(RocksDbWeight::get().writes(1))
     }
     fn prune_identities_err() -> Weight {
         // Proof Size summary in bytes:
-        //  Measured:  `359`
-        //  Estimated: `3824`
-        // Minimum execution time: 543_046_000 picoseconds.
-        Weight::from_parts(544_513_000, 0)
-            .saturating_add(Weight::from_parts(0, 3824))
-            .saturating_add(RocksDbWeight::get().reads(3))
-            .saturating_add(RocksDbWeight::get().writes(1))
+        //  Measured:  `1177`
+        //  Estimated: `4642`
+        // Minimum execution time: 1_427_848_000 picoseconds.
+        Weight::from_parts(2_637_229_000, 0)
+            .saturating_add(Weight::from_parts(0, 4642))
+            .saturating_add(RocksDbWeight::get().reads(8))
+            .saturating_add(RocksDbWeight::get().writes(8))
     }
 }
diff --git a/pallets/membership/README.md b/pallets/membership/README.md
index 116b2addd9d736c6452d4dc3dcbe83f1959c62de..4bcd6020fa90de4d182c84c1e0145d80a95fc04e 100644
--- a/pallets/membership/README.md
+++ b/pallets/membership/README.md
@@ -1,25 +1,23 @@
 # Duniter membership pallet
 
-Duniter membership is related to duniter Web of Trust and more specific than [parity membership pallet](https://github.com/paritytech/substrate/tree/master/frame/membership). It is used only internally by the identity, WoT, and distance pallets. In particular, it is adding the concept of "pending membership" which is an intermediate state where the identity is waiting to become member.
+Duniter membership is related to duniter Web of Trust and more specific than [parity membership pallet](https://github.com/paritytech/substrate/tree/master/frame/membership). It is used only internally by the identity, WoT, and distance pallets.
 
 ## Main Web of Trust
 
 When used in conjunction with the main Web of Trust, the membership pallet is combined with the Duniter-WoT pallet and the identity pallet, resulting in the following functionality:
 
-- `request_membership` is automatically invoked when confirming identity and should not be called manually. It will add the identity to the pending membership.
-- `claim_membership` is automatically triggered during identity validation and should not be manually invoked. This process requires a pending membership, sufficient membership certificates, and a valid distance. Membership is granted upon successful completion of these requirements.
+- `claim_membership` requires enough certifications, and a valid distance
 - `renew_membership` requires a valid membership and a valid distance status to extend the validity period of a membership.
-- `revoke_membership` is automatically executed when a membership expires and should not be called manually.
+- `revoke_membership` (to be removed?)
 
-In practice, a new user creates an account, confirms identity using the `confirm_identity` call from the identity pallet, and is added to the pending membership. The user then validates it identity using the `validate_identity` call from the identity pallet, triggering a membership claim. If the certification and distance requirements are met, the identity is granted membership.
+In practice, a new user creates an account, confirms identity using the `confirm_identity` call from the identity pallet. The user then validates its identity using `claim_membership`. If the certification and distance requirements are met, the identity is granted membership.
 
 ## Sub Web of Trust Smith
 
 Functionality related to the Smith Web of Trust involves the following:
 
-- `request_membership` requires a validated identity for the member to be added to the pending membership.
-- `claim_membership` requires a pending membership, sufficient smith certificates, and a valid distance status for the identity to be included among the authority members.
-- `renew_membership` needs a valid membership and a valid distance status to extend the membership's validity period.
+- `claim_membership` requires to be member of the main wot and have enough smith certifications
+- `renew_membership` needs a valid membership to extend the membership's validity period.
 - `revoke_membership` requires a valid origin to revoke the membership.
 
-In practice, a user must complete all steps to gain membership in the main Web Of Trust. They can then manually request smith membership using the `request_membership` call of the membership pallet. The membership can be claimed using the `claim_membership` call from the membership pallet, and if the identity meets smith certificate and distance requirements, it will be added to the authority members.
\ No newline at end of file
+In practice, a user must complete all steps to gain membership in the main Web Of Trust. They can call `claim_membership` to be added to the authority members.
diff --git a/pallets/membership/src/benchmarking.rs b/pallets/membership/src/benchmarking.rs
index f389dd5966c8673cddbf02cab6286c737d250e68..48849bd51e2adee83a09740d3ed6143478cfdd9d 100644
--- a/pallets/membership/src/benchmarking.rs
+++ b/pallets/membership/src/benchmarking.rs
@@ -19,7 +19,6 @@
 use super::*;
 
 use frame_benchmarking::benchmarks_instance_pallet;
-use frame_support::dispatch::UnfilteredDispatchable;
 use frame_system::pallet_prelude::BlockNumberFor;
 use frame_system::RawOrigin;
 use sp_runtime::traits::{Convert, One};
@@ -38,28 +37,11 @@ benchmarks_instance_pallet! {
         where
             T::IdtyId: From<u32>,
     }
-    request_membership {
-        // Dave identity (4)
-        // for main wot, no constraints
-        // for smith subwot, his pubkey is hardcoded in default metadata
-        let idty: T::IdtyId = 4.into();
-        Membership::<T, I>::take(idty);
-        let caller: T::AccountId = T::AccountIdOf::convert(idty.clone()).unwrap();
-        let caller_origin: <T as frame_system::Config>::RuntimeOrigin = RawOrigin::Signed(caller.clone()).into();
-        // Lazily prepare call as this extrinsic will always return an errror when in subwot
-        let call = Call::<T, I>::request_membership { };
-    }: {
-        call.dispatch_bypass_filter(caller_origin).ok();
-    }
-    verify {
-        if T::CheckMembershipCallAllowed::check_idty_allowed_to_request_membership(&idty).is_ok() {
-            assert_has_event::<T, I>(Event::<T, I>::PendingMembershipAdded{member: idty, expire_on: BlockNumberFor::<T>::one() + T::PendingMembershipPeriod::get()}.into());
-        }
-    }
+
+    // claim membership
     claim_membership {
         let idty: T::IdtyId = 3.into();
         Membership::<T, I>::take(idty);
-        PendingMembership::<T, I>::insert(idty.clone(), ());
         let caller: T::AccountId = T::AccountIdOf::convert(idty.clone()).unwrap();
         let caller_origin: <T as frame_system::Config>::RuntimeOrigin = RawOrigin::Signed(caller.clone()).into();
         T::BenchmarkSetupHandler::force_status_ok(&idty, &caller);
@@ -67,6 +49,8 @@ benchmarks_instance_pallet! {
     verify {
         assert_has_event::<T, I>(Event::<T, I>::MembershipAdded{member: idty, expire_on: BlockNumberFor::<T>::one() + T::MembershipPeriod::get()}.into());
     }
+
+    // renew membership
     renew_membership {
         let idty: T::IdtyId = 3.into();
         let caller: T::AccountId = T::AccountIdOf::convert(idty.clone()).unwrap();
@@ -76,6 +60,8 @@ benchmarks_instance_pallet! {
     verify {
         assert_has_event::<T, I>(Event::<T, I>::MembershipAdded{member: idty, expire_on: BlockNumberFor::<T>::one() + T::MembershipPeriod::get()}.into());
     }
+
+    // revoke membership
     revoke_membership {
         let idty: T::IdtyId = 3.into();
         let caller: T::AccountId = T::AccountIdOf::convert(idty.clone()).unwrap();
@@ -84,23 +70,11 @@ benchmarks_instance_pallet! {
     verify {
         assert_has_event::<T, I>(Event::<T, I>::MembershipRemoved{member: idty, reason: MembershipRemovalReason::Revoked}.into());
     }
+
     // Base weight of an empty initialize
     on_initialize {
     }: {Pallet::<T, I>::on_initialize(BlockNumberFor::<T>::zero());}
-    expire_pending_memberships {
-        let i in 0..1024;
-        let mut idties: Vec<T::IdtyId> = Vec::new();
-        for j in 0..i {
-            let j: T::IdtyId = j.into();
-            PendingMembership::<T, I>::insert(j, ());
-            idties.push(j);
-        }
-        PendingMembershipsExpireOn::<T, I>::insert(BlockNumberFor::<T>::zero(), idties);
-        assert_eq!(PendingMembershipsExpireOn::<T, I>::get(BlockNumberFor::<T>::zero()).len(), i as usize);
-    }: {Pallet::<T, I>::expire_pending_memberships(BlockNumberFor::<T>::zero());}
-    verify {
-        assert_eq!(PendingMembershipsExpireOn::<T, I>::get(BlockNumberFor::<T>::zero()).len(), 0 as usize);
-    }
+
     expire_memberships {
         let i in 0..1024;
         let mut idties: Vec<T::IdtyId> = Vec::new();
diff --git a/pallets/membership/src/lib.rs b/pallets/membership/src/lib.rs
index d582576991b0622fc22fe587acf089707f388afa..4f44e11dce4bdee1559422732cf30d2309c47f37 100644
--- a/pallets/membership/src/lib.rs
+++ b/pallets/membership/src/lib.rs
@@ -56,8 +56,14 @@ impl<IdtyId, AccountId> SetupBenchmark<IdtyId, AccountId> for () {
 
 #[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo)]
 pub enum MembershipRemovalReason {
+    // reach end of life
     Expired,
+    // was explicitly revoked
     Revoked,
+    // received certs count passed below threshold
+    NotEnoughCerts,
+    // system reasons (consumers, authority members, or root)
+    System,
 }
 
 #[frame_support::pallet]
@@ -92,9 +98,6 @@ pub mod pallet {
         type MembershipPeriod: Get<Self::BlockNumber>;
         /// On event handler
         type OnEvent: OnEvent<Self::IdtyId>;
-        #[pallet::constant]
-        /// Maximum period (in number of blocks), where an identity can remain pending subscription.
-        type PendingMembershipPeriod: Get<Self::BlockNumber>;
         /// Because this pallet emits events, it depends on the runtime's definition of an event.
         type RuntimeEvent: From<Event<Self, I>>
             + IsType<<Self as frame_system::Config>::RuntimeEvent>;
@@ -144,18 +147,6 @@ pub mod pallet {
     pub type MembershipsExpireOn<T: Config<I>, I: 'static = ()> =
         StorageMap<_, Twox64Concat, T::BlockNumber, Vec<T::IdtyId>, ValueQuery>;
 
-    /// identities with pending membership request
-    #[pallet::storage]
-    #[pallet::getter(fn pending_membership)]
-    pub type PendingMembership<T: Config<I>, I: 'static = ()> =
-        StorageMap<_, Twox64Concat, T::IdtyId, (), OptionQuery>;
-
-    /// maps block number to the list of memberships set to expire at this block
-    #[pallet::storage]
-    #[pallet::getter(fn pending_memberships_expire_on)]
-    pub type PendingMembershipsExpireOn<T: Config<I>, I: 'static = ()> =
-        StorageMap<_, Twox64Concat, T::BlockNumber, Vec<T::IdtyId>, ValueQuery>;
-
     // EVENTS //
 
     #[pallet::event]
@@ -171,13 +162,6 @@ pub mod pallet {
             member: T::IdtyId,
             reason: MembershipRemovalReason,
         },
-        /// A pending membership was added.
-        PendingMembershipAdded {
-            member: T::IdtyId,
-            expire_on: BlockNumberFor<T>,
-        },
-        /// A pending membership has expired.
-        PendingMembershipExpired { member: T::IdtyId },
     }
 
     // ERRORS//
@@ -188,12 +172,8 @@ pub mod pallet {
         IdtyIdNotFound,
         /// Membership already acquired.
         MembershipAlreadyAcquired,
-        /// Membership already requested.
-        MembershipAlreadyRequested,
         /// Membership not found.
         MembershipNotFound,
-        /// Membership request not found.
-        MembershipRequestNotFound,
     }
 
     // HOOKS //
@@ -202,9 +182,7 @@ pub mod pallet {
     impl<T: Config<I>, I: 'static> Hooks<BlockNumberFor<T>> for Pallet<T, I> {
         fn on_initialize(n: T::BlockNumber) -> Weight {
             if n > T::BlockNumber::zero() {
-                Self::expire_pending_memberships(n)
-                    .saturating_add(Self::expire_memberships(n))
-                    .saturating_add(T::WeightInfo::on_initialize())
+                T::WeightInfo::on_initialize().saturating_add(Self::expire_memberships(n))
             } else {
                 T::WeightInfo::on_initialize()
             }
@@ -215,24 +193,9 @@ pub mod pallet {
 
     #[pallet::call]
     impl<T: Config<I>, I: 'static> Pallet<T, I> {
-        /// submit a membership request (must have a declared identity)
-        /// (only available for sub wot, automatic for main wot)
-        #[pallet::call_index(0)]
-        #[pallet::weight(T::WeightInfo::request_membership())]
-        pub fn request_membership(origin: OriginFor<T>) -> DispatchResultWithPostInfo {
-            let who = ensure_signed(origin)?;
-
-            let idty_id = T::IdtyIdOf::convert(who.clone()).ok_or(Error::<T, I>::IdtyIdNotFound)?;
-
-            T::CheckMembershipCallAllowed::check_idty_allowed_to_request_membership(&idty_id)?;
-
-            Self::do_request_membership(idty_id)
-        }
-
         /// claim membership
-        /// a pending membership should exist
         /// it must fullfill the requirements (certs, distance)
-        /// for main wot claim_membership is called automatically when validating identity
+        /// TODO #159 for main wot claim_membership is called automatically when distance is evaluated positively
         /// for smith wot, it means joining the authority members
         #[pallet::call_index(1)]
         #[pallet::weight(T::WeightInfo::claim_membership())]
@@ -241,7 +204,7 @@ pub mod pallet {
             let idty_id = Self::get_idty_id(origin)?;
 
             Self::check_allowed_to_claim(idty_id)?;
-            Self::do_claim_membership(idty_id);
+            Self::do_add_membership(idty_id);
             Ok(().into())
         }
 
@@ -273,7 +236,7 @@ pub mod pallet {
             let idty_id = Self::get_idty_id(origin)?;
 
             // Apply phase
-            Self::do_revoke_membership(idty_id);
+            Self::do_remove_membership(idty_id, MembershipRemovalReason::Revoked);
 
             Ok(().into())
         }
@@ -282,33 +245,6 @@ pub mod pallet {
     // INTERNAL FUNCTIONS //
 
     impl<T: Config<I>, I: 'static> Pallet<T, I> {
-        /// force request membership
-        pub fn force_request_membership(idty_id: T::IdtyId) -> DispatchResultWithPostInfo {
-            Self::do_request_membership(idty_id)
-        }
-
-        /// force expire membership
-        pub fn force_expire_membership(idty_id: T::IdtyId) -> DispatchResultWithPostInfo {
-            let new_expire_on = frame_system::pallet::Pallet::<T>::block_number()
-                + T::PendingMembershipPeriod::get();
-            Self::do_expire_membership(idty_id, new_expire_on);
-
-            Ok(().into())
-        }
-
-        /// try to claim membership if not already done
-        pub fn try_claim_membership(idty_id: T::IdtyId) {
-            if Self::check_allowed_to_claim(idty_id).is_ok() {
-                Self::do_claim_membership(idty_id);
-            }
-            // else { should not try to claim membership if not allowed}
-        }
-
-        /// force revoke membership
-        pub fn force_revoke_membership(idty_id: T::IdtyId) {
-            Self::do_revoke_membership(idty_id);
-        }
-
         /// unschedule membership expiry
         fn unschedule_membership_expiry(idty_id: T::IdtyId, block_number: T::BlockNumber) {
             let mut scheduled = MembershipsExpireOn::<T, I>::get(block_number);
@@ -331,76 +267,31 @@ pub mod pallet {
             });
         }
 
-        /// perform the membership request
-        fn do_request_membership(idty_id: T::IdtyId) -> DispatchResultWithPostInfo {
-            // checks
-            if PendingMembership::<T, I>::contains_key(idty_id) {
-                return Err(Error::<T, I>::MembershipAlreadyRequested.into());
-            }
-            if Membership::<T, I>::contains_key(idty_id) {
-                return Err(Error::<T, I>::MembershipAlreadyAcquired.into());
-            }
-
-            let block_number = frame_system::pallet::Pallet::<T>::block_number();
-            let expire_on = block_number + T::PendingMembershipPeriod::get();
-
-            // apply membership request
-            PendingMembership::<T, I>::insert(idty_id, ());
-            PendingMembershipsExpireOn::<T, I>::append(expire_on, idty_id);
-            Self::deposit_event(Event::PendingMembershipAdded {
-                member: idty_id,
-                expire_on,
-            });
-            T::OnEvent::on_event(&sp_membership::Event::PendingMembershipAdded(idty_id));
-
-            Ok(().into())
-        }
-
         /// check that membership can be claimed
         pub fn check_allowed_to_claim(idty_id: T::IdtyId) -> Result<(), DispatchError> {
-            PendingMembership::<T, I>::get(idty_id)
-                .ok_or(Error::<T, I>::MembershipRequestNotFound)?;
             // enough certifications and distance rule for example
             T::CheckMembershipCallAllowed::check_idty_allowed_to_claim_membership(&idty_id)?;
             Ok(())
         }
 
-        /// perform membership claim
-        fn do_claim_membership(idty_id: T::IdtyId) {
-            if PendingMembership::<T, I>::take(idty_id).is_some() {
-                Self::insert_membership_and_schedule_expiry(idty_id);
-                T::OnEvent::on_event(&sp_membership::Event::MembershipAdded(idty_id));
-            }
-            // else { unreachable if check_allowed_to_claim called before }
+        /// perform membership addition
+        fn do_add_membership(idty_id: T::IdtyId) {
+            Self::insert_membership_and_schedule_expiry(idty_id);
+            T::OnEvent::on_event(&sp_membership::Event::MembershipAdded(idty_id));
         }
 
-        /// perform membership revokation
-        fn do_revoke_membership(idty_id: T::IdtyId) {
+        /// perform membership removal
+        pub fn do_remove_membership(idty_id: T::IdtyId, reason: MembershipRemovalReason) {
             if let Some(membership_data) = Membership::<T, I>::take(idty_id) {
                 Self::unschedule_membership_expiry(idty_id, membership_data.expire_on);
                 Self::deposit_event(Event::MembershipRemoved {
                     member: idty_id,
-                    reason: MembershipRemovalReason::Revoked,
+                    reason,
                 });
                 T::OnEvent::on_event(&sp_membership::Event::MembershipRemoved(idty_id));
             }
         }
 
-        /// perform membership expiration
-        // add pending membership and schedule expiry of pending membership
-        fn do_expire_membership(idty_id: T::IdtyId, expire_on: T::BlockNumber) {
-            if Membership::<T, I>::take(idty_id).is_some() {
-                PendingMembership::<T, I>::insert(idty_id, ());
-                PendingMembershipsExpireOn::<T, I>::append(expire_on, idty_id);
-            } // else should not happen
-
-            Self::deposit_event(Event::MembershipRemoved {
-                member: idty_id,
-                reason: MembershipRemovalReason::Expired,
-            });
-            T::OnEvent::on_event(&sp_membership::Event::MembershipRemoved(idty_id));
-        }
-
         /// check the origin and get identity id if valid
         fn get_idty_id(origin: OriginFor<T>) -> Result<T::IdtyId, DispatchError> {
             if let Ok(RawOrigin::Signed(account_id)) = origin.into() {
@@ -409,36 +300,21 @@ pub mod pallet {
                 Err(BadOrigin.into())
             }
         }
+
         /// perform the membership expiry scheduled at given block
-        // MembershipExpired events should be handeled by main wot and delete identity
-        // expired membership get back to pending membership
         pub fn expire_memberships(block_number: T::BlockNumber) -> Weight {
             let mut expired_idty_count = 0u32;
-            let new_expire_on = block_number + T::PendingMembershipPeriod::get();
 
             for idty_id in MembershipsExpireOn::<T, I>::take(block_number) {
                 // remove membership (take)
-                Self::do_expire_membership(idty_id, new_expire_on);
+                Self::do_remove_membership(idty_id, MembershipRemovalReason::Expired);
                 expired_idty_count = 0;
             }
             T::WeightInfo::expire_memberships(expired_idty_count)
         }
-        /// perform the expiration of pending membership planned at given block
-        // only expire pending membership if still pending
-        pub fn expire_pending_memberships(block_number: T::BlockNumber) -> Weight {
-            let mut expired_idty_count = 0u32;
-            for idty_id in PendingMembershipsExpireOn::<T, I>::take(block_number) {
-                if PendingMembership::<T, I>::take(idty_id).is_some() {
-                    Self::deposit_event(Event::PendingMembershipExpired { member: idty_id });
-                    T::OnEvent::on_event(&sp_membership::Event::PendingMembershipExpired(idty_id));
-                    expired_idty_count = 0;
-                }
-            }
-            T::WeightInfo::expire_pending_memberships(expired_idty_count)
-        }
 
         /// check if identity is member
-        pub(super) fn do_is_member(idty_id: &T::IdtyId) -> bool {
+        pub(super) fn is_member(idty_id: &T::IdtyId) -> bool {
             Membership::<T, I>::contains_key(idty_id)
         }
     }
@@ -446,15 +322,9 @@ pub mod pallet {
 
 // implement traits
 
-impl<T: Config<I>, I: 'static> IsInPendingMemberships<T::IdtyId> for Pallet<T, I> {
-    fn is_in_pending_memberships(idty_id: T::IdtyId) -> bool {
-        PendingMembership::<T, I>::contains_key(idty_id)
-    }
-}
-
 impl<T: Config<I>, I: 'static> sp_runtime::traits::IsMember<T::IdtyId> for Pallet<T, I> {
     fn is_member(idty_id: &T::IdtyId) -> bool {
-        Self::do_is_member(idty_id)
+        Self::is_member(idty_id)
     }
 }
 
diff --git a/pallets/membership/src/mock.rs b/pallets/membership/src/mock.rs
index 74f44e85bf4ba6c1cabbe70808181320dc3901f3..5173ff716833722a3269e9c65bc5a04e721fbaab 100644
--- a/pallets/membership/src/mock.rs
+++ b/pallets/membership/src/mock.rs
@@ -89,7 +89,6 @@ impl pallet_membership::Config for Test {
     type AccountIdOf = ConvertInto;
     type MembershipPeriod = MembershipPeriod;
     type OnEvent = ();
-    type PendingMembershipPeriod = PendingMembershipPeriod;
     type RuntimeEvent = RuntimeEvent;
     type WeightInfo = ();
     #[cfg(feature = "runtime-benchmarks")]
diff --git a/pallets/membership/src/tests.rs b/pallets/membership/src/tests.rs
index dfdd12bc3c7f7b1c73f83c5fbcb5fd0e3154b9e4..d3ea561676c7df75c9037da79ec8b5f2a47b232b 100644
--- a/pallets/membership/src/tests.rs
+++ b/pallets/membership/src/tests.rs
@@ -21,7 +21,6 @@ use frame_support::{assert_noop, assert_ok};
 use maplit::btreemap;
 use sp_membership::traits::*;
 use sp_membership::MembershipData;
-use sp_runtime::traits::IsMember;
 
 // alias
 type RtEvent = RuntimeEvent;
@@ -49,32 +48,8 @@ fn test_genesis_build() {
     });
 }
 
-#[test]
-fn test_membership_already_acquired() {
-    new_test_ext(default_gen_conf()).execute_with(|| {
-        run_to_block(1);
-        // Membership 0 cannot be reclaimed because there is no membership request
-        assert_noop!(
-            DefaultMembership::claim_membership(RuntimeOrigin::signed(0)),
-            Error::<Test, _>::MembershipRequestNotFound
-        );
-    });
-}
-
-#[test]
-fn test_membership_request_not_found() {
-    new_test_ext(default_gen_conf()).execute_with(|| {
-        run_to_block(1);
-        // Membership 0 cannot be reclaimed
-        assert_noop!(
-            DefaultMembership::claim_membership(RuntimeOrigin::signed(1)),
-            Error::<Test, _>::MembershipRequestNotFound
-        );
-    });
-}
-
 /// test membership expiration
-// membership should be moved to pending membership and expire after
+// membership should expire
 #[test]
 fn test_membership_expiration() {
     new_test_ext(default_gen_conf()).execute_with(|| {
@@ -88,11 +63,6 @@ fn test_membership_expiration() {
             member: 0,
             reason: MembershipRemovalReason::Expired,
         }));
-        // it should be added to pending membership and expire on block #6
-        run_to_block(6);
-        System::assert_has_event(RtEvent::DefaultMembership(
-            Event::PendingMembershipExpired { member: 0 },
-        ));
     });
 }
 
@@ -156,64 +126,27 @@ fn test_membership_revocation() {
             member: 0,
             reason: MembershipRemovalReason::Revoked,
         }));
+        assert_eq!(DefaultMembership::membership(0), None);
 
-        // Membership 0 can re-request membership
+        // Membership 0 can re-claim membership
         run_to_block(5);
-        assert_ok!(DefaultMembership::request_membership(
-            RuntimeOrigin::signed(0),
-        ));
-        System::assert_has_event(RtEvent::DefaultMembership(Event::PendingMembershipAdded {
+        assert_ok!(DefaultMembership::claim_membership(RuntimeOrigin::signed(
+            0
+        ),));
+        System::assert_has_event(RtEvent::DefaultMembership(Event::MembershipAdded {
             member: 0,
-            expire_on: 5 + <Test as crate::Config>::PendingMembershipPeriod::get(),
+            expire_on: 5 + <Test as crate::Config>::MembershipPeriod::get(),
         }));
     });
 }
 
-/// test pending membership expiration
-#[test]
-fn test_pending_membership_expiration() {
-    new_test_ext(Default::default()).execute_with(|| {
-        // Idty 0 request membership
-        run_to_block(1);
-        assert_ok!(DefaultMembership::request_membership(
-            RuntimeOrigin::signed(0),
-        ));
-        System::assert_has_event(RtEvent::DefaultMembership(Event::PendingMembershipAdded {
-            member: 0,
-            expire_on: 1 + <Test as crate::Config>::PendingMembershipPeriod::get(),
-        }));
-
-        // Then, idty 0 shold still in pending memberships until PendingMembershipPeriod ended
-        run_to_block(PendingMembershipPeriod::get());
-        assert!(DefaultMembership::is_in_pending_memberships(0));
-
-        // Then, idty 0 request should expire after PendingMembershipPeriod
-        run_to_block(1 + PendingMembershipPeriod::get());
-        assert!(!DefaultMembership::is_in_pending_memberships(0));
-        System::assert_has_event(RtEvent::DefaultMembership(
-            Event::PendingMembershipExpired { member: 0 },
-        ));
-    })
-}
-
 /// test membership workflow
-// - request membership
 // - claim membership
 // - renew membership
 // - membership expiry
 #[test]
 fn test_membership_workflow() {
     new_test_ext(Default::default()).execute_with(|| {
-        // - Idty 0 request membership
-        run_to_block(1);
-        assert_ok!(DefaultMembership::request_membership(
-            RuntimeOrigin::signed(0),
-        ));
-        System::assert_has_event(RtEvent::DefaultMembership(Event::PendingMembershipAdded {
-            member: 0,
-            expire_on: 1 + <Test as crate::Config>::PendingMembershipPeriod::get(),
-        }));
-
         // - Then, idty 0 claim membership
         run_to_block(2);
         assert_ok!(DefaultMembership::claim_membership(RuntimeOrigin::signed(
diff --git a/pallets/membership/src/weights.rs b/pallets/membership/src/weights.rs
index 253c1fc92a11decc1cd133e1df44cde69b740288..e244e83b78b15a04a71ecddd24f6f12797dc549e 100644
--- a/pallets/membership/src/weights.rs
+++ b/pallets/membership/src/weights.rs
@@ -20,75 +20,65 @@ use frame_support::weights::{constants::RocksDbWeight, Weight};
 
 /// Weight functions needed for pallet_universal_dividend.
 pub trait WeightInfo {
-    fn request_membership() -> Weight;
     fn claim_membership() -> Weight;
     fn renew_membership() -> Weight;
     fn revoke_membership() -> Weight;
     fn on_initialize() -> Weight;
-    fn expire_pending_memberships(_i: u32) -> Weight;
     fn expire_memberships(_i: u32) -> Weight;
 }
 
 // Insecure weights implementation, use it for tests only!
 impl WeightInfo for () {
-    // Storage: Identity IdentityIndexOf (r:1 w:0)
-    // Storage: Identity Identities (r:1 w:0)
-    fn request_membership() -> Weight {
-        // Minimum execution time: 48_477 nanoseconds.
-        Weight::from_parts(50_689_000 as u64, 0)
-            .saturating_add(RocksDbWeight::get().reads(2 as u64))
-    }
-    // Storage: Identity IdentityIndexOf (r:1 w:0)
-    // Storage: Membership Membership (r:1 w:1)
-    // Storage: Cert StorageIdtyCertMeta (r:1 w:0)
-    // Storage: Parameters ParametersStorage (r:1 w:0)
-    // Storage: Membership PendingMembership (r:1 w:1)
-    // Storage: Membership CounterForMembership (r:1 w:1)
-    // Storage: Membership MembershipsExpireOn (r:1 w:1)
     fn claim_membership() -> Weight {
-        // Minimum execution time: 144_079 nanoseconds.
-        Weight::from_parts(146_565_000 as u64, 0)
-            .saturating_add(RocksDbWeight::get().reads(7 as u64))
-            .saturating_add(RocksDbWeight::get().writes(4 as u64))
+        // Proof Size summary in bytes:
+        //  Measured:  `1272`
+        //  Estimated: `4737`
+        // Minimum execution time: 1_213_348_000 picoseconds.
+        Weight::from_parts(1_439_442_000, 0)
+            .saturating_add(Weight::from_parts(0, 4737))
+            .saturating_add(RocksDbWeight::get().reads(10))
+            .saturating_add(RocksDbWeight::get().writes(4))
     }
-    // Storage: Identity IdentityIndexOf (r:1 w:0)
-    // Storage: Membership Membership (r:1 w:1)
-    // Storage: Identity Identities (r:1 w:0)
-    // Storage: Parameters ParametersStorage (r:1 w:0)
-    // Storage: Membership MembershipsExpireOn (r:1 w:1)
     fn renew_membership() -> Weight {
-        // Minimum execution time: 120_859 nanoseconds.
-        Weight::from_parts(124_222_000 as u64, 0)
-            .saturating_add(RocksDbWeight::get().reads(5 as u64))
-            .saturating_add(RocksDbWeight::get().writes(2 as u64))
+        // Proof Size summary in bytes:
+        //  Measured:  `988`
+        //  Estimated: `6928`
+        // Minimum execution time: 714_537_000 picoseconds.
+        Weight::from_parts(862_085_000, 0)
+            .saturating_add(Weight::from_parts(0, 6928))
+            .saturating_add(RocksDbWeight::get().reads(7))
+            .saturating_add(RocksDbWeight::get().writes(3))
     }
-    // Storage: Identity IdentityIndexOf (r:1 w:0)
-    // Storage: Membership Membership (r:1 w:1)
-    // Storage: Membership CounterForMembership (r:1 w:1)
-    // Storage: Identity Identities (r:1 w:0)
-    // Storage: UniversalDividend CurrentUdIndex (r:1 w:0)
     fn revoke_membership() -> Weight {
-        // Minimum execution time: 109_486 nanoseconds.
-        Weight::from_parts(113_303_000 as u64, 0)
-            .saturating_add(RocksDbWeight::get().reads(5 as u64))
-            .saturating_add(RocksDbWeight::get().writes(2 as u64))
+        // Proof Size summary in bytes:
+        //  Measured:  `703`
+        //  Estimated: `6643`
+        // Minimum execution time: 847_926_000 picoseconds.
+        Weight::from_parts(1_282_028_000, 0)
+            .saturating_add(Weight::from_parts(0, 6643))
+            .saturating_add(RocksDbWeight::get().reads(8))
+            .saturating_add(RocksDbWeight::get().writes(5))
     }
     fn on_initialize() -> Weight {
-        // Minimum execution time: 109_486 nanoseconds.
-        Weight::from_parts(113_303_000 as u64, 0)
-            .saturating_add(RocksDbWeight::get().reads(5 as u64))
-            .saturating_add(RocksDbWeight::get().writes(2 as u64))
-    }
-    fn expire_pending_memberships(_i: u32) -> Weight {
-        // Minimum execution time: 109_486 nanoseconds.
-        Weight::from_parts(113_303_000 as u64, 0)
-            .saturating_add(RocksDbWeight::get().reads(5 as u64))
-            .saturating_add(RocksDbWeight::get().writes(2 as u64))
+        // Proof Size summary in bytes:
+        //  Measured:  `0`
+        //  Estimated: `0`
+        // Minimum execution time: 4_012_000 picoseconds.
+        Weight::from_parts(4_629_000, 0).saturating_add(Weight::from_parts(0, 0))
     }
-    fn expire_memberships(_i: u32) -> Weight {
-        // Minimum execution time: 109_486 nanoseconds.
-        Weight::from_parts(113_303_000 as u64, 0)
-            .saturating_add(RocksDbWeight::get().reads(5 as u64))
-            .saturating_add(RocksDbWeight::get().writes(2 as u64))
+    fn expire_memberships(i: u32) -> Weight {
+        // Proof Size summary in bytes:
+        //  Measured:  `567 + i * (23 ±0)`
+        //  Estimated: `6583 + i * (2499 ±0)`
+        // Minimum execution time: 86_925_000 picoseconds.
+        Weight::from_parts(89_056_000, 0)
+            .saturating_add(Weight::from_parts(0, 6583))
+            // Standard Error: 2_429_589
+            .saturating_add(Weight::from_parts(295_368_241, 0).saturating_mul(i.into()))
+            .saturating_add(RocksDbWeight::get().reads(3))
+            .saturating_add(RocksDbWeight::get().reads((2_u64).saturating_mul(i.into())))
+            .saturating_add(RocksDbWeight::get().writes(5))
+            .saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(i.into())))
+            .saturating_add(Weight::from_parts(0, 2499).saturating_mul(i.into()))
     }
 }
diff --git a/pallets/quota/src/lib.rs b/pallets/quota/src/lib.rs
index f3a579cb207cd1cefc493f73de460b2deb4b1533..e618281ea9aff42ea7ddb0b6a0ce5e215ce209b0 100644
--- a/pallets/quota/src/lib.rs
+++ b/pallets/quota/src/lib.rs
@@ -354,7 +354,6 @@ impl<T: Config> pallet_identity::traits::OnIdtyChange<T> for Pallet<T> {
             IdtyEvent::Removed { .. } => {
                 IdtyQuota::<T>::remove(idty_id);
             }
-            IdtyEvent::Confirmed | IdtyEvent::Validated | IdtyEvent::ChangedOwnerKey { .. } => {}
         }
     }
 }
diff --git a/pallets/quota/src/mock.rs b/pallets/quota/src/mock.rs
index 266f31a086cb29c8f41e06bca88adbd86ba8e082..d023eebeefd5907e62481cf589bab26a531f8cc4 100644
--- a/pallets/quota/src/mock.rs
+++ b/pallets/quota/src/mock.rs
@@ -136,9 +136,10 @@ impl pallet_balances::Config for Test {
 parameter_types! {
     pub const ChangeOwnerKeyPeriod: u64 = 10;
     pub const ConfirmPeriod: u64 = 2;
+    pub const ValidationPeriod: u64 = 3;
+    pub const AutorevocationPeriod: u64 = 5;
+    pub const DeletionPeriod: u64 = 7;
     pub const IdtyCreationPeriod: u64 = 3;
-    pub const MaxInactivityPeriod: u64 = 5;
-    pub const ValidationPeriod: u64 = 2;
 }
 pub struct IdtyNameValidatorTestImpl;
 impl pallet_identity::traits::IdtyNameValidator for IdtyNameValidatorTestImpl {
@@ -149,17 +150,18 @@ impl pallet_identity::traits::IdtyNameValidator for IdtyNameValidatorTestImpl {
 impl pallet_identity::Config for Test {
     type ChangeOwnerKeyPeriod = ChangeOwnerKeyPeriod;
     type ConfirmPeriod = ConfirmPeriod;
+    type ValidationPeriod = ValidationPeriod;
+    type AutorevocationPeriod = AutorevocationPeriod;
+    type DeletionPeriod = DeletionPeriod;
     type CheckIdtyCallAllowed = ();
     type IdtyCreationPeriod = IdtyCreationPeriod;
     type IdtyData = ();
     type IdtyNameValidator = IdtyNameValidatorTestImpl;
     type IdtyIndex = u64;
     type AccountLinker = ();
-    type IdtyRemovalOtherReason = ();
     type Signer = AccountPublic;
     type Signature = Signature;
     type OnIdtyChange = ();
-    type RemoveIdentityConsumers = ();
     type RuntimeEvent = RuntimeEvent;
     type WeightInfo = ();
     #[cfg(feature = "runtime-benchmarks")]
diff --git a/pallets/universal-dividend/src/benchmarking.rs b/pallets/universal-dividend/src/benchmarking.rs
index 99a3929377c4397289c291d295f0e52e75076e77..5786d2ee0930ddf30ce14f5766aa412c77ecce82 100644
--- a/pallets/universal-dividend/src/benchmarking.rs
+++ b/pallets/universal-dividend/src/benchmarking.rs
@@ -111,7 +111,7 @@ benchmarks! {
     }: {Pallet::<T>::on_removed_member(CurrentUdIndex::<T>::get() - i as u16, &caller);}
     verify {
         if i != 0 {
-            assert_has_event::<T>(Event::<T>::UdsAutoPaidAtRemoval {count: i as u16, total: uds_total, who: caller}.into());
+            assert_has_event::<T>(Event::<T>::UdsAutoPaid {count: i as u16, total: uds_total, who: caller}.into());
         }
     }
 
diff --git a/pallets/universal-dividend/src/lib.rs b/pallets/universal-dividend/src/lib.rs
index 09ba8511dc786cd3f8e534fbec2dc622c144dce1..b41e4b245bc7bc0e3e6ff8c4708ea776064a92de 100644
--- a/pallets/universal-dividend/src/lib.rs
+++ b/pallets/universal-dividend/src/lib.rs
@@ -236,7 +236,7 @@ pub mod pallet {
             members_count: BalanceOf<T>,
         },
         /// DUs were automatically transferred as part of a member removal.
-        UdsAutoPaidAtRemoval {
+        UdsAutoPaid {
             count: UdIndex,
             total: BalanceOf<T>,
             who: T::AccountId,
@@ -442,7 +442,7 @@ pub mod pallet {
                     PastReevals::<T>::get().into_iter(),
                 );
                 T::Currency::deposit_creating(who, uds_total);
-                Self::deposit_event(Event::UdsAutoPaidAtRemoval {
+                Self::deposit_event(Event::UdsAutoPaid {
                     count: uds_count,
                     total: uds_total,
                     who: who.clone(),
diff --git a/primitives/membership/Cargo.toml b/primitives/membership/Cargo.toml
index f1142e3df36282345eed48f28e5ea8f38a89db47..d0f391814ef38ceea3f303546dbe84b5e256cf02 100644
--- a/primitives/membership/Cargo.toml
+++ b/primitives/membership/Cargo.toml
@@ -22,6 +22,9 @@ try-runtime = ['frame-support/try-runtime']
 
 [dependencies]
 
+# crates.io
+impl-trait-for-tuples = "0.2.1"
+
 # substrate
 scale-info = { version = "2.1.1", default-features = false, features = ["derive"] }
 
diff --git a/primitives/membership/src/lib.rs b/primitives/membership/src/lib.rs
index fa5b992f966e939c6d0bc4e5ff198a8b6cfc657d..897bf64ffc81003caef3f02a60aff9251f2b7945 100644
--- a/primitives/membership/src/lib.rs
+++ b/primitives/membership/src/lib.rs
@@ -27,6 +27,7 @@ use scale_info::TypeInfo;
 #[cfg(feature = "std")]
 use serde::{Deserialize, Serialize};
 
+/// membership events
 pub enum Event<IdtyId> {
     /// A membership was acquired.
     MembershipAdded(IdtyId),
@@ -34,10 +35,6 @@ pub enum Event<IdtyId> {
     MembershipRemoved(IdtyId),
     /// A membership was renewed.
     MembershipRenewed(IdtyId),
-    /// A pending membership request was added.
-    PendingMembershipAdded(IdtyId),
-    /// A pending membership request has expired.
-    PendingMembershipExpired(IdtyId),
 }
 
 #[cfg_attr(feature = "std", derive(Deserialize, Serialize))]
@@ -45,3 +42,15 @@ pub enum Event<IdtyId> {
 pub struct MembershipData<BlockNumber: Decode + Encode + TypeInfo> {
     pub expire_on: BlockNumber,
 }
+
+use impl_trait_for_tuples::impl_for_tuples;
+// use sp_std::prelude::*;
+// use frame_support::pallet_prelude::*;
+// use frame_system::pallet_prelude::*;
+
+#[impl_for_tuples(5)]
+impl<IdtyId> traits::OnEvent<IdtyId> for Tuple {
+    fn on_event(event: &Event<IdtyId>) {
+        for_tuples!( #( Tuple::on_event(event); )* );
+    }
+}
diff --git a/primitives/membership/src/traits.rs b/primitives/membership/src/traits.rs
index 28d0c52de235d2da970386928d5f6389a95cf58c..abb5961cd3d7d76cdba4f845a79b458ce03e326e 100644
--- a/primitives/membership/src/traits.rs
+++ b/primitives/membership/src/traits.rs
@@ -19,7 +19,6 @@ use frame_support::pallet_prelude::*;
 pub trait CheckMembershipCallAllowed<IdtyId> {
     fn check_idty_allowed_to_claim_membership(idty_id: &IdtyId) -> Result<(), DispatchError>;
     fn check_idty_allowed_to_renew_membership(idty_id: &IdtyId) -> Result<(), DispatchError>;
-    fn check_idty_allowed_to_request_membership(idty_id: &IdtyId) -> Result<(), DispatchError>;
 }
 
 impl<IdtyId> CheckMembershipCallAllowed<IdtyId> for () {
@@ -29,33 +28,16 @@ impl<IdtyId> CheckMembershipCallAllowed<IdtyId> for () {
     fn check_idty_allowed_to_renew_membership(_: &IdtyId) -> Result<(), DispatchError> {
         Ok(())
     }
-    fn check_idty_allowed_to_request_membership(_: &IdtyId) -> Result<(), DispatchError> {
-        Ok(())
-    }
-}
-
-pub trait IsInPendingMemberships<IdtyId> {
-    fn is_in_pending_memberships(idty_id: IdtyId) -> bool;
 }
 
 pub trait OnEvent<IdtyId> {
     fn on_event(event: &crate::Event<IdtyId>);
 }
 
-impl<IdtyId> OnEvent<IdtyId> for () {
-    fn on_event(_: &crate::Event<IdtyId>) {}
-}
+// impl<IdtyId> OnEvent<IdtyId> for () {
+//     fn on_event(_: &crate::Event<IdtyId>) {}
+// }
 
 pub trait MembersCount {
     fn members_count() -> u32;
 }
-
-pub trait Validate<AccountId> {
-    fn validate(&self, account_id: &AccountId) -> bool;
-}
-
-impl<AccountId> Validate<AccountId> for () {
-    fn validate(&self, _account_id: &AccountId) -> bool {
-        true
-    }
-}
diff --git a/resources/metadata.scale b/resources/metadata.scale
index fb9903cdcd8ab7a3f169487e4becee25afdc7d8c..60cf370fe64aecd0dc9bbdd157c56e90b5653228 100644
Binary files a/resources/metadata.scale and b/resources/metadata.scale differ
diff --git a/runtime/common/src/handlers.rs b/runtime/common/src/handlers.rs
index a0a084988ca7a8440c278027b707fcce8247d6a9..8cb679c6680d6a74ac760d6a4556dc6744fbc4df 100644
--- a/runtime/common/src/handlers.rs
+++ b/runtime/common/src/handlers.rs
@@ -20,8 +20,6 @@ use frame_support::dispatch::UnfilteredDispatchable;
 use frame_support::instances::{Instance1, Instance2};
 use frame_support::pallet_prelude::Weight;
 use frame_support::Parameter;
-use pallet_identity::IdtyEvent;
-use sp_runtime::traits::IsMember;
 
 // new session handler
 pub struct OnNewSessionHandler<Runtime>(core::marker::PhantomData<Runtime>);
@@ -35,37 +33,6 @@ where
     }
 }
 
-// identity change runtime handler
-pub struct OnIdtyChangeHandler<Runtime>(core::marker::PhantomData<Runtime>);
-impl<T> pallet_identity::traits::OnIdtyChange<T> for OnIdtyChangeHandler<T>
-where
-    T: frame_system::Config<AccountId = AccountId>,
-    T: pallet_authority_members::Config<MemberId = IdtyIndex>,
-    T: pallet_identity::Config<IdtyIndex = IdtyIndex, IdtyData = IdtyData>,
-    T: pallet_universal_dividend::Config,
-{
-    fn on_idty_change(idty_index: IdtyIndex, idty_event: &IdtyEvent<T>) {
-        match idty_event {
-            IdtyEvent::Validated => {
-                // when identity is validated, it starts getting right to UD
-                // but this is handeled by membership event handler (MembershipAdded)
-            }
-            IdtyEvent::ChangedOwnerKey { new_owner_key } => {
-                if let Err(e) = pallet_authority_members::Pallet::<T>::change_owner_key(
-                    idty_index,
-                    new_owner_key.clone(),
-                ) {
-                    log::error!(
-                        "on_idty_change: pallet_authority_members.change_owner_key(): {:?}",
-                        e
-                    );
-                }
-            }
-            IdtyEvent::Created { .. } | IdtyEvent::Confirmed | IdtyEvent::Removed { .. } => {}
-        }
-    }
-}
-
 // membership event runtime handler
 pub struct OnMembershipEventHandler<Inner, Runtime>(core::marker::PhantomData<(Inner, Runtime)>);
 impl<
@@ -102,9 +69,7 @@ impl<
                 });
             }
             // in other case, ther is nothing to do
-            sp_membership::Event::MembershipRenewed(_)
-            | sp_membership::Event::PendingMembershipAdded(_)
-            | sp_membership::Event::PendingMembershipExpired(_) => (),
+            sp_membership::Event::MembershipRenewed(_) => (),
         });
         Inner::on_event(membership_event)
     }
@@ -148,6 +113,8 @@ impl<
 }
 
 // authority member removal handler
+// TODO refac smith wot
+// or document the link between smith membership and authority member
 pub struct OnRemovedAuthorityMemberHandler<Runtime>(core::marker::PhantomData<Runtime>);
 impl<Runtime> pallet_authority_members::traits::OnRemovedMember<IdtyIndex>
     for OnRemovedAuthorityMemberHandler<Runtime>
@@ -155,30 +122,10 @@ where
     Runtime: frame_system::Config + pallet_membership::Config<Instance2, IdtyId = IdtyIndex>,
 {
     fn on_removed_member(idty_index: IdtyIndex) {
-        // TODO investigate why we should remove smith membership when removing authority member
-        pallet_membership::Pallet::<Runtime, Instance2>::force_revoke_membership(idty_index);
-    }
-}
-
-// identity removal handler
-pub struct RemoveIdentityConsumersImpl<Runtime>(core::marker::PhantomData<Runtime>);
-impl<Runtime> pallet_identity::traits::RemoveIdentityConsumers<IdtyIndex>
-    for RemoveIdentityConsumersImpl<Runtime>
-where
-    Runtime: pallet_identity::Config<IdtyIndex = IdtyIndex>
-        + pallet_authority_members::Config<MemberId = IdtyIndex>
-        + pallet_membership::Config<Instance1, IdtyId = IdtyIndex>
-        + pallet_membership::Config<Instance2, IdtyId = IdtyIndex>,
-{
-    fn remove_idty_consumers(idty_index: IdtyIndex) -> Weight {
-        // Remove smith member
-        if pallet_membership::Pallet::<Runtime, Instance2>::is_member(&idty_index) {
-            pallet_membership::Pallet::<Runtime, Instance2>::force_revoke_membership(idty_index);
-        }
-        // Remove "classic" member
-        pallet_membership::Pallet::<Runtime, Instance1>::force_revoke_membership(idty_index);
-
-        Weight::zero()
+        pallet_membership::Pallet::<Runtime, Instance2>::do_remove_membership(
+            idty_index,
+            pallet_membership::MembershipRemovalReason::System,
+        );
     }
 }
 
diff --git a/runtime/common/src/pallets_config.rs b/runtime/common/src/pallets_config.rs
index 31bae949b2f7852cf8c37f98dcbcd090ebf97816..471c97672353b4b91bb648a14089a582a7c8e9fa 100644
--- a/runtime/common/src/pallets_config.rs
+++ b/runtime/common/src/pallets_config.rs
@@ -460,20 +460,26 @@ macro_rules! pallets_config {
             type MinCertForCreateIdtyRight = WotMinCertForCreateIdtyRight;
         }
 
+        parameter_types! {
+            pub const ValidationPeriod: BlockNumber = 2 * MONTHS;
+            pub const AutorevocationPeriod: BlockNumber = 1 * YEARS;
+            pub const DeletionPeriod: BlockNumber = 10 * YEARS;
+        }
         impl pallet_identity::Config for Runtime {
 			type ChangeOwnerKeyPeriod = ChangeOwnerKeyPeriod;
             type ConfirmPeriod = ConfirmPeriod;
+            type ValidationPeriod = ValidationPeriod;
+            type AutorevocationPeriod = AutorevocationPeriod;
+            type DeletionPeriod = DeletionPeriod;
             type CheckIdtyCallAllowed = (Wot, SmithSubWot);
             type IdtyCreationPeriod = IdtyCreationPeriod;
 			type IdtyData = IdtyData;
             type IdtyIndex = IdtyIndex;
             type AccountLinker = Account;
             type IdtyNameValidator = IdtyNameValidatorImpl;
-            type IdtyRemovalOtherReason = pallet_duniter_wot::IdtyRemovalWotReason;
             type Signer = <Signature as sp_runtime::traits::Verify>::Signer;
 			type Signature = Signature;
-            type OnIdtyChange = (common_runtime::handlers::OnIdtyChangeHandler<Runtime>, Wot, Quota, Account);
-            type RemoveIdentityConsumers = RemoveIdentityConsumersImpl<Self>;
+            type OnIdtyChange = (Wot, SmithSubWot, Quota, Account);
             type RuntimeEvent = RuntimeEvent;
             type WeightInfo = common_runtime::weights::pallet_identity::WeightInfo<Runtime>;
             #[cfg(feature = "runtime-benchmarks")]
@@ -486,8 +492,7 @@ macro_rules! pallets_config {
             type IdtyIdOf = common_runtime::providers::IdentityIndexOf<Self>;
             type AccountIdOf = common_runtime::providers::IdentityAccountIdProvider<Self>;
             type MembershipPeriod = MembershipPeriod;
-            type OnEvent = OnMembershipEventHandler<Wot, Runtime>;
-            type PendingMembershipPeriod = PendingMembershipPeriod;
+            type OnEvent = (OnMembershipEventHandler<Wot, Runtime>, Wot);
             type RuntimeEvent = RuntimeEvent;
             type WeightInfo = common_runtime::weights::pallet_membership_membership::WeightInfo<Runtime>;
             #[cfg(feature = "runtime-benchmarks")]
@@ -537,7 +542,6 @@ macro_rules! pallets_config {
             type AccountIdOf = common_runtime::providers::IdentityAccountIdProvider<Self>;
             type MembershipPeriod = SmithMembershipPeriod;
             type OnEvent = OnSmithMembershipEventHandler<SmithSubWot, Runtime>;
-            type PendingMembershipPeriod = SmithPendingMembershipPeriod;
             type RuntimeEvent = RuntimeEvent;
             type WeightInfo = common_runtime::weights::pallet_membership_smith_membership::WeightInfo<Runtime>;
             #[cfg(feature = "runtime-benchmarks")]
diff --git a/runtime/common/src/providers.rs b/runtime/common/src/providers.rs
index 1417140622744b6879500cb0ebd5a8962759860d..b9d23572036dd5ae23b1393adea35535e5cb0c4e 100644
--- a/runtime/common/src/providers.rs
+++ b/runtime/common/src/providers.rs
@@ -119,9 +119,12 @@ where
         idty_id: &<T as pallet_identity::Config>::IdtyIndex,
     ) -> Result<(), DispatchError> {
         match pallet_distance::Pallet::<T>::identity_distance_status(idty_id) {
-			Some((_, pallet_distance::DistanceStatus::Valid)) => Ok(()),
-			Some((_, pallet_distance::DistanceStatus::Invalid)) => Err(pallet_duniter_wot::Error::<T, frame_support::instances::Instance1>::DistanceIsInvalid.into()),
-			_ => Err(pallet_duniter_wot::Error::<T, frame_support::instances::Instance1>::DistanceNotEvaluated.into()),
+            Some((_, status)) => match status {
+                pallet_distance::DistanceStatus::Valid => Ok(()),
+                pallet_distance::DistanceStatus::Invalid => Err(pallet_duniter_wot::Error::<T, frame_support::instances::Instance1>::DistanceIsInvalid.into()),
+                pallet_distance::DistanceStatus::Pending => Err(pallet_duniter_wot::Error::<T, frame_support::instances::Instance1>::DistanceEvaluationPending.into()),
+            },
+			None => Err(pallet_duniter_wot::Error::<T, frame_support::instances::Instance1>::DistanceEvaluationNotRequested.into()),
 		}
     }
 }
diff --git a/runtime/common/src/weights/pallet_identity.rs b/runtime/common/src/weights/pallet_identity.rs
index 332be4f48444499deb4ee6c2791968a182149fdc..5664f72ae7a09c34dba4bfa114cf90b6abf37fd1 100644
--- a/runtime/common/src/weights/pallet_identity.rs
+++ b/runtime/common/src/weights/pallet_identity.rs
@@ -1,28 +1,41 @@
+// 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/>.
 
 //! Autogenerated weights for `pallet_identity`
 //!
 //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev
-//! DATE: 2023-11-22, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! DATE: 2023-12-14, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
 //! WORST CASE MAP SIZE: `1000000`
-//! HOSTNAME: `bgallois-ms7d43`, CPU: `12th Gen Intel(R) Core(TM) i3-12100F`
-//! EXECUTION: None, WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024
+//! HOSTNAME: `squirrel`, CPU: `Intel(R) Core(TM) i7-8565U CPU @ 1.80GHz`
+//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024
 
 // Executed Command:
-// ./target/release/duniter
+// ./target/debug/duniter
 // benchmark
 // pallet
-// --chain
-// dev
+// --chain=dev
+// --steps=50
+// --repeat=20
+// --pallet=pallet-identity
+// --extrinsic=*
+// --execution=wasm
 // --wasm-execution=compiled
-// --pallet
-// *
-// --extrinsic
-// *
-// --steps
-// 50
-// --repeat
-// 20
-// --output=runtime/common/src/weights/
+// --heap-pages=4096
+// --header=./file_header.txt
+// --output=./runtime/common/src/weights/
 
 #![cfg_attr(rustfmt, rustfmt_skip)]
 #![allow(unused_parens)]
@@ -47,24 +60,26 @@ impl<T: frame_system::Config> pallet_identity::WeightInfo for WeightInfo<T> {
 	/// Proof: System Account (max_values: None, max_size: Some(126), added: 2601, mode: MaxEncodedLen)
 	/// Storage: Identity NextIdtyIndex (r:1 w:1)
 	/// Proof Skipped: Identity NextIdtyIndex (max_values: Some(1), max_size: None, mode: Measured)
+	/// Storage: Identity IdentityChangeSchedule (r:1 w:1)
+	/// Proof Skipped: Identity IdentityChangeSchedule (max_values: None, max_size: None, mode: Measured)
 	/// Storage: Identity CounterForIdentities (r:1 w:1)
 	/// Proof: Identity CounterForIdentities (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen)
-	/// Storage: Identity IdentitiesRemovableOn (r:1 w:1)
-	/// Proof Skipped: Identity IdentitiesRemovableOn (max_values: None, max_size: None, mode: Measured)
 	/// Storage: Cert StorageCertsRemovableOn (r:1 w:1)
 	/// Proof Skipped: Cert StorageCertsRemovableOn (max_values: None, max_size: None, mode: Measured)
 	/// Storage: Cert CertsByReceiver (r:1 w:1)
 	/// Proof Skipped: Cert CertsByReceiver (max_values: None, max_size: None, mode: Measured)
+	/// Storage: SmithCert StorageIdtyCertMeta (r:1 w:0)
+	/// Proof Skipped: SmithCert StorageIdtyCertMeta (max_values: None, max_size: None, mode: Measured)
 	/// Storage: Quota IdtyQuota (r:0 w:1)
 	/// Proof: Quota IdtyQuota (max_values: None, max_size: Some(24), added: 2499, mode: MaxEncodedLen)
 	fn create_identity() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `982`
-		//  Estimated: `6922`
-		// Minimum execution time: 38_137_000 picoseconds.
-		Weight::from_parts(39_647_000, 0)
-			.saturating_add(Weight::from_parts(0, 6922))
-			.saturating_add(T::DbWeight::get().reads(13))
+		//  Measured:  `1165`
+		//  Estimated: `7105`
+		// Minimum execution time: 1_643_969_000 picoseconds.
+		Weight::from_parts(1_781_521_000, 0)
+			.saturating_add(Weight::from_parts(0, 7105))
+			.saturating_add(T::DbWeight::get().reads(14))
 			.saturating_add(T::DbWeight::get().writes(12))
 	}
 	/// Storage: Identity IdentityIndexOf (r:1 w:0)
@@ -73,52 +88,18 @@ impl<T: frame_system::Config> pallet_identity::WeightInfo for WeightInfo<T> {
 	/// Proof Skipped: Identity Identities (max_values: None, max_size: None, mode: Measured)
 	/// Storage: Identity IdentitiesNames (r:1 w:1)
 	/// Proof Skipped: Identity IdentitiesNames (max_values: None, max_size: None, mode: Measured)
-	/// Storage: Membership PendingMembership (r:1 w:1)
-	/// Proof Skipped: Membership PendingMembership (max_values: None, max_size: None, mode: Measured)
-	/// Storage: Membership Membership (r:1 w:0)
-	/// Proof Skipped: Membership Membership (max_values: None, max_size: None, mode: Measured)
-	/// Storage: Parameters ParametersStorage (r:1 w:0)
-	/// Proof Skipped: Parameters ParametersStorage (max_values: Some(1), max_size: None, mode: Measured)
-	/// Storage: Membership PendingMembershipsExpireOn (r:1 w:1)
-	/// Proof Skipped: Membership PendingMembershipsExpireOn (max_values: None, max_size: None, mode: Measured)
+	/// Storage: Identity IdentityChangeSchedule (r:2 w:2)
+	/// Proof Skipped: Identity IdentityChangeSchedule (max_values: None, max_size: None, mode: Measured)
 	fn confirm_identity() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `955`
-		//  Estimated: `4420`
-		// Minimum execution time: 23_569_000 picoseconds.
-		Weight::from_parts(24_735_000, 0)
-			.saturating_add(Weight::from_parts(0, 4420))
-			.saturating_add(T::DbWeight::get().reads(7))
+		//  Measured:  `661`
+		//  Estimated: `6601`
+		// Minimum execution time: 564_892_000 picoseconds.
+		Weight::from_parts(588_761_000, 0)
+			.saturating_add(Weight::from_parts(0, 6601))
+			.saturating_add(T::DbWeight::get().reads(5))
 			.saturating_add(T::DbWeight::get().writes(4))
 	}
-	/// Storage: Identity Identities (r:1 w:1)
-	/// Proof Skipped: Identity Identities (max_values: None, max_size: None, mode: Measured)
-	/// Storage: Membership PendingMembership (r:1 w:1)
-	/// Proof Skipped: Membership PendingMembership (max_values: None, max_size: None, mode: Measured)
-	/// Storage: Cert StorageIdtyCertMeta (r:1 w:0)
-	/// Proof Skipped: Cert StorageIdtyCertMeta (max_values: None, max_size: None, mode: Measured)
-	/// Storage: Parameters ParametersStorage (r:1 w:0)
-	/// Proof Skipped: Parameters ParametersStorage (max_values: Some(1), max_size: None, mode: Measured)
-	/// Storage: Distance IdentityDistanceStatus (r:1 w:0)
-	/// Proof Skipped: Distance IdentityDistanceStatus (max_values: None, max_size: None, mode: Measured)
-	/// Storage: Membership Membership (r:1 w:1)
-	/// Proof Skipped: Membership Membership (max_values: None, max_size: None, mode: Measured)
-	/// Storage: Membership CounterForMembership (r:1 w:1)
-	/// Proof: Membership CounterForMembership (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen)
-	/// Storage: Membership MembershipsExpireOn (r:1 w:1)
-	/// Proof Skipped: Membership MembershipsExpireOn (max_values: None, max_size: None, mode: Measured)
-	/// Storage: UniversalDividend CurrentUdIndex (r:1 w:0)
-	/// Proof: UniversalDividend CurrentUdIndex (max_values: Some(1), max_size: Some(2), added: 497, mode: MaxEncodedLen)
-	fn validate_identity() -> Weight {
-		// Proof Size summary in bytes:
-		//  Measured:  `1948`
-		//  Estimated: `5413`
-		// Minimum execution time: 39_059_000 picoseconds.
-		Weight::from_parts(42_214_000, 0)
-			.saturating_add(Weight::from_parts(0, 5413))
-			.saturating_add(T::DbWeight::get().reads(9))
-			.saturating_add(T::DbWeight::get().writes(5))
-	}
 	/// Storage: Identity IdentityIndexOf (r:2 w:2)
 	/// Proof Skipped: Identity IdentityIndexOf (max_values: None, max_size: None, mode: Measured)
 	/// Storage: Identity Identities (r:1 w:1)
@@ -129,81 +110,37 @@ impl<T: frame_system::Config> pallet_identity::WeightInfo for WeightInfo<T> {
 	/// Proof: System BlockHash (max_values: None, max_size: Some(44), added: 2519, mode: MaxEncodedLen)
 	/// Storage: System Account (r:2 w:2)
 	/// Proof: System Account (max_values: None, max_size: Some(126), added: 2601, mode: MaxEncodedLen)
-	/// Storage: AuthorityMembers Members (r:1 w:0)
-	/// Proof Skipped: AuthorityMembers Members (max_values: None, max_size: None, mode: Measured)
 	fn change_owner_key() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `1119`
-		//  Estimated: `7059`
-		// Minimum execution time: 76_290_000 picoseconds.
-		Weight::from_parts(79_765_000, 0)
-			.saturating_add(Weight::from_parts(0, 7059))
-			.saturating_add(T::DbWeight::get().reads(8))
+		//  Measured:  `837`
+		//  Estimated: `6777`
+		// Minimum execution time: 991_641_000 picoseconds.
+		Weight::from_parts(1_071_332_000, 0)
+			.saturating_add(Weight::from_parts(0, 6777))
+			.saturating_add(T::DbWeight::get().reads(7))
 			.saturating_add(T::DbWeight::get().writes(5))
 	}
 	/// Storage: Identity Identities (r:1 w:1)
 	/// Proof Skipped: Identity Identities (max_values: None, max_size: None, mode: Measured)
-	/// Storage: SmithMembership Membership (r:1 w:0)
-	/// Proof Skipped: SmithMembership Membership (max_values: None, max_size: None, mode: Measured)
 	/// Storage: System BlockHash (r:1 w:0)
 	/// Proof: System BlockHash (max_values: None, max_size: Some(44), added: 2519, mode: MaxEncodedLen)
+	/// Storage: Identity IdentityChangeSchedule (r:2 w:2)
+	/// Proof Skipped: Identity IdentityChangeSchedule (max_values: None, max_size: None, mode: Measured)
 	/// Storage: Membership Membership (r:1 w:1)
 	/// Proof Skipped: Membership Membership (max_values: None, max_size: None, mode: Measured)
-	/// Storage: Identity CounterForIdentities (r:1 w:1)
-	/// Proof: Identity CounterForIdentities (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen)
-	/// Storage: System Account (r:2 w:2)
-	/// Proof: System Account (max_values: None, max_size: Some(126), added: 2601, mode: MaxEncodedLen)
-	/// Storage: Cert CertsByReceiver (r:1 w:1)
-	/// Proof Skipped: Cert CertsByReceiver (max_values: None, max_size: None, mode: Measured)
-	/// Storage: Cert StorageIdtyCertMeta (r:2 w:2)
-	/// Proof Skipped: Cert StorageIdtyCertMeta (max_values: None, max_size: None, mode: Measured)
-	/// Storage: Parameters ParametersStorage (r:1 w:0)
-	/// Proof Skipped: Parameters ParametersStorage (max_values: Some(1), max_size: None, mode: Measured)
-	/// Storage: Identity IdentityIndexOf (r:0 w:1)
-	/// Proof Skipped: Identity IdentityIndexOf (max_values: None, max_size: None, mode: Measured)
-	/// Storage: Quota IdtyQuota (r:0 w:1)
-	/// Proof: Quota IdtyQuota (max_values: None, max_size: Some(24), added: 2499, mode: MaxEncodedLen)
-	fn revoke_identity() -> Weight {
-		// Proof Size summary in bytes:
-		//  Measured:  `1498`
-		//  Estimated: `7438`
-		// Minimum execution time: 84_313_000 picoseconds.
-		Weight::from_parts(87_192_000, 0)
-			.saturating_add(Weight::from_parts(0, 7438))
-			.saturating_add(T::DbWeight::get().reads(11))
-			.saturating_add(T::DbWeight::get().writes(10))
-	}
-	/// Storage: Identity Identities (r:1 w:1)
-	/// Proof Skipped: Identity Identities (max_values: None, max_size: None, mode: Measured)
-	/// Storage: SmithMembership Membership (r:1 w:0)
+	/// Storage: SmithMembership Membership (r:1 w:1)
 	/// Proof Skipped: SmithMembership Membership (max_values: None, max_size: None, mode: Measured)
-	/// Storage: Membership Membership (r:1 w:1)
-	/// Proof Skipped: Membership Membership (max_values: None, max_size: None, mode: Measured)
-	/// Storage: Identity CounterForIdentities (r:1 w:1)
-	/// Proof: Identity CounterForIdentities (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen)
-	/// Storage: System Account (r:1 w:1)
-	/// Proof: System Account (max_values: None, max_size: Some(126), added: 2601, mode: MaxEncodedLen)
-	/// Storage: Cert CertsByReceiver (r:1 w:1)
-	/// Proof Skipped: Cert CertsByReceiver (max_values: None, max_size: None, mode: Measured)
-	/// Storage: Cert StorageIdtyCertMeta (r:2 w:2)
-	/// Proof Skipped: Cert StorageIdtyCertMeta (max_values: None, max_size: None, mode: Measured)
-	/// Storage: Parameters ParametersStorage (r:1 w:0)
-	/// Proof Skipped: Parameters ParametersStorage (max_values: Some(1), max_size: None, mode: Measured)
-	/// Storage: Identity IdentityIndexOf (r:0 w:1)
-	/// Proof Skipped: Identity IdentityIndexOf (max_values: None, max_size: None, mode: Measured)
-	/// Storage: Identity IdentitiesNames (r:0 w:1)
-	/// Proof Skipped: Identity IdentitiesNames (max_values: None, max_size: None, mode: Measured)
 	/// Storage: Quota IdtyQuota (r:0 w:1)
 	/// Proof: Quota IdtyQuota (max_values: None, max_size: Some(24), added: 2499, mode: MaxEncodedLen)
-	fn force_remove_identity() -> Weight {
+	fn revoke_identity() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `1343`
-		//  Estimated: `7283`
-		// Minimum execution time: 38_696_000 picoseconds.
-		Weight::from_parts(39_816_000, 0)
-			.saturating_add(Weight::from_parts(0, 7283))
-			.saturating_add(T::DbWeight::get().reads(9))
-			.saturating_add(T::DbWeight::get().writes(10))
+		//  Measured:  `778`
+		//  Estimated: `6718`
+		// Minimum execution time: 829_174_000 picoseconds.
+		Weight::from_parts(869_308_000, 0)
+			.saturating_add(Weight::from_parts(0, 6718))
+			.saturating_add(T::DbWeight::get().reads(6))
+			.saturating_add(T::DbWeight::get().writes(6))
 	}
 	/// Storage: Identity IdentitiesNames (r:0 w:998)
 	/// Proof Skipped: Identity IdentitiesNames (max_values: None, max_size: None, mode: Measured)
@@ -212,11 +149,11 @@ impl<T: frame_system::Config> pallet_identity::WeightInfo for WeightInfo<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 804_000 picoseconds.
-		Weight::from_parts(888_000, 0)
+		// Minimum execution time: 51_362_000 picoseconds.
+		Weight::from_parts(80_389_000, 0)
 			.saturating_add(Weight::from_parts(0, 0))
-			// Standard Error: 939
-			.saturating_add(Weight::from_parts(642_823, 0).saturating_mul(i.into()))
+			// Standard Error: 75_232
+			.saturating_add(Weight::from_parts(30_016_649, 0).saturating_mul(i.into()))
 			.saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(i.into())))
 	}
 	/// Storage: System Account (r:1 w:1)
@@ -225,8 +162,8 @@ impl<T: frame_system::Config> pallet_identity::WeightInfo for WeightInfo<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `67`
 		//  Estimated: `3591`
-		// Minimum execution time: 3_775_000 picoseconds.
-		Weight::from_parts(4_240_000, 0)
+		// Minimum execution time: 154_343_000 picoseconds.
+		Weight::from_parts(156_117_000, 0)
 			.saturating_add(Weight::from_parts(0, 3591))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
@@ -241,8 +178,8 @@ impl<T: frame_system::Config> pallet_identity::WeightInfo for WeightInfo<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `307`
 		//  Estimated: `3772`
-		// Minimum execution time: 45_159_000 picoseconds.
-		Weight::from_parts(46_401_000, 0)
+		// Minimum execution time: 538_773_000 picoseconds.
+		Weight::from_parts(591_354_000, 0)
 			.saturating_add(Weight::from_parts(0, 3772))
 			.saturating_add(T::DbWeight::get().reads(3))
 			.saturating_add(T::DbWeight::get().writes(1))
@@ -251,23 +188,33 @@ impl<T: frame_system::Config> pallet_identity::WeightInfo for WeightInfo<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 28_000 picoseconds.
-		Weight::from_parts(31_000, 0)
+		// Minimum execution time: 4_529_000 picoseconds.
+		Weight::from_parts(7_360_000, 0)
 			.saturating_add(Weight::from_parts(0, 0))
 	}
 	/// Storage: Identity Identities (r:1 w:0)
 	/// Proof Skipped: Identity Identities (max_values: None, max_size: None, mode: Measured)
-	fn do_remove_identity_noop() -> Weight {
+	fn do_revoke_identity_noop() -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `269`
 		//  Estimated: `3734`
-		// Minimum execution time: 3_245_000 picoseconds.
-		Weight::from_parts(3_383_000, 0)
+		// Minimum execution time: 103_668_000 picoseconds.
+		Weight::from_parts(107_679_000, 0)
 			.saturating_add(Weight::from_parts(0, 3734))
 			.saturating_add(T::DbWeight::get().reads(1))
 	}
 	/// Storage: Identity Identities (r:1 w:1)
 	/// Proof Skipped: Identity Identities (max_values: None, max_size: None, mode: Measured)
+	/// Storage: Identity IdentityChangeSchedule (r:2 w:1)
+	/// Proof Skipped: Identity IdentityChangeSchedule (max_values: None, max_size: None, mode: Measured)
+	/// Storage: Membership Membership (r:1 w:1)
+	/// Proof Skipped: Membership Membership (max_values: None, max_size: None, mode: Measured)
+	/// Storage: Membership CounterForMembership (r:1 w:1)
+	/// Proof: Membership CounterForMembership (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen)
+	/// Storage: Membership MembershipsExpireOn (r:1 w:1)
+	/// Proof Skipped: Membership MembershipsExpireOn (max_values: None, max_size: None, mode: Measured)
+	/// Storage: UniversalDividend CurrentUdIndex (r:1 w:0)
+	/// Proof: UniversalDividend CurrentUdIndex (max_values: Some(1), max_size: Some(2), added: 497, mode: MaxEncodedLen)
 	/// Storage: SmithMembership Membership (r:1 w:1)
 	/// Proof Skipped: SmithMembership Membership (max_values: None, max_size: None, mode: Measured)
 	/// Storage: SmithMembership CounterForMembership (r:1 w:1)
@@ -286,6 +233,37 @@ impl<T: frame_system::Config> pallet_identity::WeightInfo for WeightInfo<T> {
 	/// Proof Skipped: AuthorityMembers IncomingAuthorities (max_values: Some(1), max_size: None, mode: Measured)
 	/// Storage: Session NextKeys (r:1 w:1)
 	/// Proof Skipped: Session NextKeys (max_values: None, max_size: None, mode: Measured)
+	/// Storage: System Account (r:1 w:1)
+	/// Proof: System Account (max_values: None, max_size: Some(126), added: 2601, mode: MaxEncodedLen)
+	/// Storage: Quota IdtyQuota (r:0 w:1)
+	/// Proof: Quota IdtyQuota (max_values: None, max_size: Some(24), added: 2499, mode: MaxEncodedLen)
+	/// Storage: Session KeyOwner (r:0 w:4)
+	/// Proof Skipped: Session KeyOwner (max_values: None, max_size: None, mode: Measured)
+	fn do_revoke_identity() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `1525`
+		//  Estimated: `7465`
+		// Minimum execution time: 2_204_911_000 picoseconds.
+		Weight::from_parts(2_225_493_000, 0)
+			.saturating_add(Weight::from_parts(0, 7465))
+			.saturating_add(T::DbWeight::get().reads(17))
+			.saturating_add(T::DbWeight::get().writes(20))
+	}
+	/// Storage: Identity Identities (r:1 w:0)
+	/// Proof Skipped: Identity Identities (max_values: None, max_size: None, mode: Measured)
+	fn do_remove_identity_noop() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `269`
+		//  Estimated: `3734`
+		// Minimum execution time: 104_296_000 picoseconds.
+		Weight::from_parts(115_316_000, 0)
+			.saturating_add(Weight::from_parts(0, 3734))
+			.saturating_add(T::DbWeight::get().reads(1))
+	}
+	/// Storage: Identity Identities (r:1 w:1)
+	/// Proof Skipped: Identity Identities (max_values: None, max_size: None, mode: Measured)
+	/// Storage: Identity CounterForIdentities (r:1 w:1)
+	/// Proof: Identity CounterForIdentities (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen)
 	/// Storage: System Account (r:2 w:2)
 	/// Proof: System Account (max_values: None, max_size: Some(126), added: 2601, mode: MaxEncodedLen)
 	/// Storage: Membership Membership (r:1 w:1)
@@ -294,10 +272,24 @@ impl<T: frame_system::Config> pallet_identity::WeightInfo for WeightInfo<T> {
 	/// Proof: Membership CounterForMembership (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen)
 	/// Storage: Membership MembershipsExpireOn (r:1 w:1)
 	/// Proof Skipped: Membership MembershipsExpireOn (max_values: None, max_size: None, mode: Measured)
-	/// Storage: UniversalDividend CurrentUdIndex (r:1 w:0)
-	/// Proof: UniversalDividend CurrentUdIndex (max_values: Some(1), max_size: Some(2), added: 497, mode: MaxEncodedLen)
-	/// Storage: Identity CounterForIdentities (r:1 w:1)
-	/// Proof: Identity CounterForIdentities (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen)
+	/// Storage: SmithMembership Membership (r:1 w:1)
+	/// Proof Skipped: SmithMembership Membership (max_values: None, max_size: None, mode: Measured)
+	/// Storage: SmithMembership CounterForMembership (r:1 w:1)
+	/// Proof: SmithMembership CounterForMembership (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen)
+	/// Storage: SmithMembership MembershipsExpireOn (r:1 w:1)
+	/// Proof Skipped: SmithMembership MembershipsExpireOn (max_values: None, max_size: None, mode: Measured)
+	/// Storage: AuthorityMembers Members (r:1 w:1)
+	/// Proof Skipped: AuthorityMembers Members (max_values: None, max_size: None, mode: Measured)
+	/// Storage: AuthorityMembers OnlineAuthorities (r:1 w:1)
+	/// Proof Skipped: AuthorityMembers OnlineAuthorities (max_values: Some(1), max_size: None, mode: Measured)
+	/// Storage: AuthorityMembers OutgoingAuthorities (r:1 w:1)
+	/// Proof Skipped: AuthorityMembers OutgoingAuthorities (max_values: Some(1), max_size: None, mode: Measured)
+	/// Storage: AuthorityMembers AuthoritiesCounter (r:1 w:1)
+	/// Proof Skipped: AuthorityMembers AuthoritiesCounter (max_values: Some(1), max_size: None, mode: Measured)
+	/// Storage: AuthorityMembers IncomingAuthorities (r:1 w:1)
+	/// Proof Skipped: AuthorityMembers IncomingAuthorities (max_values: Some(1), max_size: None, mode: Measured)
+	/// Storage: Session NextKeys (r:1 w:1)
+	/// Proof Skipped: Session NextKeys (max_values: None, max_size: None, mode: Measured)
 	/// Storage: Identity IdentityIndexOf (r:0 w:1)
 	/// Proof Skipped: Identity IdentityIndexOf (max_values: None, max_size: None, mode: Measured)
 	/// Storage: Quota IdtyQuota (r:0 w:1)
@@ -306,51 +298,67 @@ impl<T: frame_system::Config> pallet_identity::WeightInfo for WeightInfo<T> {
 	/// Proof Skipped: Session KeyOwner (max_values: None, max_size: None, mode: Measured)
 	fn do_remove_identity() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `1525`
+		//  Measured:  `1432`
 		//  Estimated: `6192`
-		// Minimum execution time: 57_854_000 picoseconds.
-		Weight::from_parts(60_976_000, 0)
+		// Minimum execution time: 2_870_497_000 picoseconds.
+		Weight::from_parts(4_159_994_000, 0)
 			.saturating_add(Weight::from_parts(0, 6192))
-			.saturating_add(T::DbWeight::get().reads(17))
+			.saturating_add(T::DbWeight::get().reads(16))
 			.saturating_add(T::DbWeight::get().writes(22))
 	}
-	/// Storage: Identity IdentitiesRemovableOn (r:1 w:0)
-	/// Proof Skipped: Identity IdentitiesRemovableOn (max_values: None, max_size: None, mode: Measured)
+	/// Storage: Identity IdentityChangeSchedule (r:1 w:0)
+	/// Proof Skipped: Identity IdentityChangeSchedule (max_values: None, max_size: None, mode: Measured)
 	fn prune_identities_noop() -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `108`
 		//  Estimated: `3573`
-		// Minimum execution time: 1_249_000 picoseconds.
-		Weight::from_parts(1_330_000, 0)
+		// Minimum execution time: 68_859_000 picoseconds.
+		Weight::from_parts(71_836_000, 0)
 			.saturating_add(Weight::from_parts(0, 3573))
 			.saturating_add(T::DbWeight::get().reads(1))
 	}
-	/// Storage: Identity IdentitiesRemovableOn (r:1 w:1)
-	/// Proof Skipped: Identity IdentitiesRemovableOn (max_values: None, max_size: None, mode: Measured)
+	/// Storage: Identity IdentityChangeSchedule (r:1 w:1)
+	/// Proof Skipped: Identity IdentityChangeSchedule (max_values: None, max_size: None, mode: Measured)
 	/// Storage: Identity Identities (r:1 w:0)
 	/// Proof Skipped: Identity Identities (max_values: None, max_size: None, mode: Measured)
 	fn prune_identities_none() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `293`
-		//  Estimated: `3758`
-		// Minimum execution time: 4_441_000 picoseconds.
-		Weight::from_parts(4_690_000, 0)
-			.saturating_add(Weight::from_parts(0, 3758))
+		//  Measured:  `292`
+		//  Estimated: `3757`
+		// Minimum execution time: 178_332_000 picoseconds.
+		Weight::from_parts(186_982_000, 0)
+			.saturating_add(Weight::from_parts(0, 3757))
 			.saturating_add(T::DbWeight::get().reads(2))
 			.saturating_add(T::DbWeight::get().writes(1))
 	}
-	/// Storage: Identity IdentitiesRemovableOn (r:1 w:1)
-	/// Proof Skipped: Identity IdentitiesRemovableOn (max_values: None, max_size: None, mode: Measured)
-	/// Storage: Identity Identities (r:1 w:0)
+	/// Storage: Identity IdentityChangeSchedule (r:1 w:1)
+	/// Proof Skipped: Identity IdentityChangeSchedule (max_values: None, max_size: None, mode: Measured)
+	/// Storage: Identity Identities (r:1 w:1)
 	/// Proof Skipped: Identity Identities (max_values: None, max_size: None, mode: Measured)
+	/// Storage: Identity CounterForIdentities (r:1 w:1)
+	/// Proof: Identity CounterForIdentities (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen)
+	/// Storage: System Account (r:1 w:1)
+	/// Proof: System Account (max_values: None, max_size: Some(126), added: 2601, mode: MaxEncodedLen)
+	/// Storage: Membership Membership (r:1 w:1)
+	/// Proof Skipped: Membership Membership (max_values: None, max_size: None, mode: Measured)
+	/// Storage: Cert CertsByReceiver (r:1 w:0)
+	/// Proof Skipped: Cert CertsByReceiver (max_values: None, max_size: None, mode: Measured)
+	/// Storage: SmithMembership Membership (r:1 w:1)
+	/// Proof Skipped: SmithMembership Membership (max_values: None, max_size: None, mode: Measured)
+	/// Storage: SmithCert CertsByReceiver (r:1 w:0)
+	/// Proof Skipped: SmithCert CertsByReceiver (max_values: None, max_size: None, mode: Measured)
+	/// Storage: Identity IdentityIndexOf (r:0 w:1)
+	/// Proof Skipped: Identity IdentityIndexOf (max_values: None, max_size: None, mode: Measured)
+	/// Storage: Quota IdtyQuota (r:0 w:1)
+	/// Proof: Quota IdtyQuota (max_values: None, max_size: Some(24), added: 2499, mode: MaxEncodedLen)
 	fn prune_identities_err() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `360`
-		//  Estimated: `3825`
-		// Minimum execution time: 5_680_000 picoseconds.
-		Weight::from_parts(6_083_000, 0)
-			.saturating_add(Weight::from_parts(0, 3825))
-			.saturating_add(T::DbWeight::get().reads(2))
-			.saturating_add(T::DbWeight::get().writes(1))
+		//  Measured:  `1177`
+		//  Estimated: `4642`
+		// Minimum execution time: 1_427_848_000 picoseconds.
+		Weight::from_parts(2_637_229_000, 0)
+			.saturating_add(Weight::from_parts(0, 4642))
+			.saturating_add(T::DbWeight::get().reads(8))
+			.saturating_add(T::DbWeight::get().writes(8))
 	}
 }
diff --git a/runtime/common/src/weights/pallet_membership_membership.rs b/runtime/common/src/weights/pallet_membership_membership.rs
index 64d9bd04f1ebf18aa80210f62410d0089fee66bc..127922e2fb21601acff507954905318d1f900530 100644
--- a/runtime/common/src/weights/pallet_membership_membership.rs
+++ b/runtime/common/src/weights/pallet_membership_membership.rs
@@ -1,28 +1,41 @@
+// 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/>.
 
 //! Autogenerated weights for `pallet_membership`
 //!
 //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev
-//! DATE: 2023-11-22, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! DATE: 2023-12-14, STEPS: `8`, REPEAT: `4`, LOW RANGE: `[]`, HIGH RANGE: `[]`
 //! WORST CASE MAP SIZE: `1000000`
-//! HOSTNAME: `bgallois-ms7d43`, CPU: `12th Gen Intel(R) Core(TM) i3-12100F`
-//! EXECUTION: None, WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024
+//! HOSTNAME: `squirrel`, CPU: `Intel(R) Core(TM) i7-8565U CPU @ 1.80GHz`
+//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024
 
 // Executed Command:
-// ./target/release/duniter
+// ./target/debug/duniter
 // benchmark
 // pallet
-// --chain
-// dev
+// --chain=dev
+// --steps=8
+// --repeat=4
+// --pallet=pallet-membership
+// --extrinsic=*
+// --execution=wasm
 // --wasm-execution=compiled
-// --pallet
-// *
-// --extrinsic
-// *
-// --steps
-// 50
-// --repeat
-// 20
-// --output=runtime/common/src/weights/
+// --heap-pages=4096
+// --header=./file_header.txt
+// --output=./runtime/common/src/weights/
 
 #![cfg_attr(rustfmt, rustfmt_skip)]
 #![allow(unused_parens)]
@@ -37,21 +50,6 @@ pub struct WeightInfo<T>(PhantomData<T>);
 impl<T: frame_system::Config> pallet_membership::WeightInfo for WeightInfo<T> {
 	/// Storage: Identity IdentityIndexOf (r:1 w:0)
 	/// Proof Skipped: Identity IdentityIndexOf (max_values: None, max_size: None, mode: Measured)
-	/// Storage: Identity Identities (r:1 w:0)
-	/// Proof Skipped: Identity Identities (max_values: None, max_size: None, mode: Measured)
-	fn request_membership() -> Weight {
-		// Proof Size summary in bytes:
-		//  Measured:  `429`
-		//  Estimated: `3894`
-		// Minimum execution time: 6_310_000 picoseconds.
-		Weight::from_parts(6_733_000, 0)
-			.saturating_add(Weight::from_parts(0, 3894))
-			.saturating_add(T::DbWeight::get().reads(2))
-	}
-	/// Storage: Identity IdentityIndexOf (r:1 w:0)
-	/// Proof Skipped: Identity IdentityIndexOf (max_values: None, max_size: None, mode: Measured)
-	/// Storage: Membership PendingMembership (r:1 w:1)
-	/// Proof Skipped: Membership PendingMembership (max_values: None, max_size: None, mode: Measured)
 	/// Storage: Cert StorageIdtyCertMeta (r:1 w:0)
 	/// Proof Skipped: Cert StorageIdtyCertMeta (max_values: None, max_size: None, mode: Measured)
 	/// Storage: Parameters ParametersStorage (r:1 w:0)
@@ -68,15 +66,17 @@ impl<T: frame_system::Config> pallet_membership::WeightInfo for WeightInfo<T> {
 	/// Proof Skipped: Identity Identities (max_values: None, max_size: None, mode: Measured)
 	/// Storage: UniversalDividend CurrentUdIndex (r:1 w:0)
 	/// Proof: UniversalDividend CurrentUdIndex (max_values: Some(1), max_size: Some(2), added: 497, mode: MaxEncodedLen)
+	/// Storage: Identity IdentityChangeSchedule (r:1 w:0)
+	/// Proof Skipped: Identity IdentityChangeSchedule (max_values: None, max_size: None, mode: Measured)
 	fn claim_membership() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `1302`
-		//  Estimated: `4767`
-		// Minimum execution time: 27_879_000 picoseconds.
-		Weight::from_parts(30_454_000, 0)
-			.saturating_add(Weight::from_parts(0, 4767))
+		//  Measured:  `1272`
+		//  Estimated: `4737`
+		// Minimum execution time: 1_213_348_000 picoseconds.
+		Weight::from_parts(1_439_442_000, 0)
+			.saturating_add(Weight::from_parts(0, 4737))
 			.saturating_add(T::DbWeight::get().reads(10))
-			.saturating_add(T::DbWeight::get().writes(5))
+			.saturating_add(T::DbWeight::get().writes(4))
 	}
 	/// Storage: Identity IdentityIndexOf (r:1 w:0)
 	/// Proof Skipped: Identity IdentityIndexOf (max_values: None, max_size: None, mode: Measured)
@@ -94,8 +94,8 @@ impl<T: frame_system::Config> pallet_membership::WeightInfo for WeightInfo<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `988`
 		//  Estimated: `6928`
-		// Minimum execution time: 20_913_000 picoseconds.
-		Weight::from_parts(22_331_000, 0)
+		// Minimum execution time: 714_537_000 picoseconds.
+		Weight::from_parts(862_085_000, 0)
 			.saturating_add(Weight::from_parts(0, 6928))
 			.saturating_add(T::DbWeight::get().reads(7))
 			.saturating_add(T::DbWeight::get().writes(3))
@@ -108,118 +108,57 @@ impl<T: frame_system::Config> pallet_membership::WeightInfo for WeightInfo<T> {
 	/// Proof: Membership CounterForMembership (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen)
 	/// Storage: Membership MembershipsExpireOn (r:1 w:1)
 	/// Proof Skipped: Membership MembershipsExpireOn (max_values: None, max_size: None, mode: Measured)
-	/// Storage: Identity Identities (r:1 w:0)
+	/// Storage: Identity Identities (r:1 w:1)
 	/// Proof Skipped: Identity Identities (max_values: None, max_size: None, mode: Measured)
 	/// Storage: UniversalDividend CurrentUdIndex (r:1 w:0)
 	/// Proof: UniversalDividend CurrentUdIndex (max_values: Some(1), max_size: Some(2), added: 497, mode: MaxEncodedLen)
+	/// Storage: Identity IdentityChangeSchedule (r:2 w:1)
+	/// Proof Skipped: Identity IdentityChangeSchedule (max_values: None, max_size: None, mode: Measured)
 	fn revoke_membership() -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `703`
-		//  Estimated: `4168`
-		// Minimum execution time: 16_631_000 picoseconds.
-		Weight::from_parts(18_080_000, 0)
-			.saturating_add(Weight::from_parts(0, 4168))
-			.saturating_add(T::DbWeight::get().reads(6))
-			.saturating_add(T::DbWeight::get().writes(3))
+		//  Estimated: `6643`
+		// Minimum execution time: 847_926_000 picoseconds.
+		Weight::from_parts(1_282_028_000, 0)
+			.saturating_add(Weight::from_parts(0, 6643))
+			.saturating_add(T::DbWeight::get().reads(8))
+			.saturating_add(T::DbWeight::get().writes(5))
 	}
 	fn on_initialize() -> Weight {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 26_000 picoseconds.
-		Weight::from_parts(27_000, 0)
+		// Minimum execution time: 4_012_000 picoseconds.
+		Weight::from_parts(4_629_000, 0)
 			.saturating_add(Weight::from_parts(0, 0))
 	}
-	/// Storage: Membership PendingMembershipsExpireOn (r:1 w:1)
-	/// Proof Skipped: Membership PendingMembershipsExpireOn (max_values: None, max_size: None, mode: Measured)
-	/// Storage: Membership PendingMembership (r:1024 w:1024)
-	/// Proof Skipped: Membership PendingMembership (max_values: None, max_size: None, mode: Measured)
-	/// Storage: Identity Identities (r:1024 w:4)
-	/// Proof Skipped: Identity Identities (max_values: None, max_size: None, mode: Measured)
-	/// Storage: SmithMembership Membership (r:4 w:3)
-	/// Proof Skipped: SmithMembership Membership (max_values: None, max_size: None, mode: Measured)
-	/// Storage: SmithMembership CounterForMembership (r:1 w:1)
-	/// Proof: SmithMembership CounterForMembership (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen)
-	/// Storage: SmithMembership MembershipsExpireOn (r:1 w:1)
-	/// Proof Skipped: SmithMembership MembershipsExpireOn (max_values: None, max_size: None, mode: Measured)
-	/// Storage: AuthorityMembers Members (r:3 w:3)
-	/// Proof Skipped: AuthorityMembers Members (max_values: None, max_size: None, mode: Measured)
-	/// Storage: AuthorityMembers OnlineAuthorities (r:1 w:1)
-	/// Proof Skipped: AuthorityMembers OnlineAuthorities (max_values: Some(1), max_size: None, mode: Measured)
-	/// Storage: AuthorityMembers OutgoingAuthorities (r:1 w:1)
-	/// Proof Skipped: AuthorityMembers OutgoingAuthorities (max_values: Some(1), max_size: None, mode: Measured)
-	/// Storage: AuthorityMembers AuthoritiesCounter (r:1 w:1)
-	/// Proof Skipped: AuthorityMembers AuthoritiesCounter (max_values: Some(1), max_size: None, mode: Measured)
-	/// Storage: AuthorityMembers IncomingAuthorities (r:1 w:1)
-	/// Proof Skipped: AuthorityMembers IncomingAuthorities (max_values: Some(1), max_size: None, mode: Measured)
-	/// Storage: Session NextKeys (r:3 w:3)
-	/// Proof Skipped: Session NextKeys (max_values: None, max_size: None, mode: Measured)
-	/// Storage: System Account (r:4 w:4)
-	/// Proof: System Account (max_values: None, max_size: Some(126), added: 2601, mode: MaxEncodedLen)
-	/// Storage: Membership Membership (r:4 w:4)
-	/// Proof Skipped: Membership Membership (max_values: None, max_size: None, mode: Measured)
-	/// Storage: Membership CounterForMembership (r:1 w:1)
-	/// Proof: Membership CounterForMembership (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen)
-	/// Storage: Membership MembershipsExpireOn (r:1 w:1)
-	/// Proof Skipped: Membership MembershipsExpireOn (max_values: None, max_size: None, mode: Measured)
-	/// Storage: UniversalDividend CurrentUdIndex (r:1 w:0)
-	/// Proof: UniversalDividend CurrentUdIndex (max_values: Some(1), max_size: Some(2), added: 497, mode: MaxEncodedLen)
-	/// Storage: Identity CounterForIdentities (r:1 w:1)
-	/// Proof: Identity CounterForIdentities (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen)
-	/// Storage: Identity IdentityIndexOf (r:0 w:4)
-	/// Proof Skipped: Identity IdentityIndexOf (max_values: None, max_size: None, mode: Measured)
-	/// Storage: Quota IdtyQuota (r:0 w:4)
-	/// Proof: Quota IdtyQuota (max_values: None, max_size: Some(24), added: 2499, mode: MaxEncodedLen)
-	/// Storage: Session KeyOwner (r:0 w:12)
-	/// Proof Skipped: Session KeyOwner (max_values: None, max_size: None, mode: Measured)
-	/// The range of component `i` is `[0, 1024]`.
-	/// The range of component `i` is `[0, 1024]`.
-	fn expire_pending_memberships(i: u32, ) -> Weight {
-		// Proof Size summary in bytes:
-		//  Measured:  `2214 + i * (19 ±0)`
-		//  Estimated: `13117 + i * (2495 ±0)`
-		// Minimum execution time: 2_147_000 picoseconds.
-		Weight::from_parts(104_974_304, 0)
-			.saturating_add(Weight::from_parts(0, 13117))
-			// Standard Error: 3_603
-			.saturating_add(Weight::from_parts(3_246_507, 0).saturating_mul(i.into()))
-			.saturating_add(T::DbWeight::get().reads(27))
-			.saturating_add(T::DbWeight::get().reads((2_u64).saturating_mul(i.into())))
-			.saturating_add(T::DbWeight::get().writes(47))
-			.saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(i.into())))
-			.saturating_add(Weight::from_parts(0, 2495).saturating_mul(i.into()))
-	}
-	/// Storage: Parameters ParametersStorage (r:1 w:0)
-	/// Proof Skipped: Parameters ParametersStorage (max_values: Some(1), max_size: None, mode: Measured)
 	/// Storage: Membership MembershipsExpireOn (r:1 w:1)
 	/// Proof Skipped: Membership MembershipsExpireOn (max_values: None, max_size: None, mode: Measured)
 	/// Storage: Membership Membership (r:1024 w:1024)
 	/// Proof Skipped: Membership Membership (max_values: None, max_size: None, mode: Measured)
 	/// Storage: Membership CounterForMembership (r:1 w:1)
 	/// Proof: Membership CounterForMembership (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen)
-	/// Storage: Membership PendingMembershipsExpireOn (r:1 w:1)
-	/// Proof Skipped: Membership PendingMembershipsExpireOn (max_values: None, max_size: None, mode: Measured)
-	/// Storage: Identity Identities (r:1024 w:0)
+	/// Storage: Identity Identities (r:1024 w:4)
 	/// Proof Skipped: Identity Identities (max_values: None, max_size: None, mode: Measured)
 	/// Storage: UniversalDividend CurrentUdIndex (r:1 w:0)
 	/// Proof: UniversalDividend CurrentUdIndex (max_values: Some(1), max_size: Some(2), added: 497, mode: MaxEncodedLen)
-	/// Storage: Membership PendingMembership (r:0 w:1024)
-	/// Proof Skipped: Membership PendingMembership (max_values: None, max_size: None, mode: Measured)
+	/// Storage: Identity IdentityChangeSchedule (r:2 w:1)
+	/// Proof Skipped: Identity IdentityChangeSchedule (max_values: None, max_size: None, mode: Measured)
 	/// The range of component `i` is `[0, 1024]`.
 	/// The range of component `i` is `[0, 1024]`.
 	fn expire_memberships(i: u32, ) -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `714 + i * (23 ±0)`
-		//  Estimated: `4199 + i * (2499 ±0)`
-		// Minimum execution time: 4_828_000 picoseconds.
-		Weight::from_parts(5_150_000, 0)
-			.saturating_add(Weight::from_parts(0, 4199))
-			// Standard Error: 885
-			.saturating_add(Weight::from_parts(3_785_083, 0).saturating_mul(i.into()))
-			.saturating_add(T::DbWeight::get().reads(5))
+		//  Measured:  `567 + i * (23 ±0)`
+		//  Estimated: `6583 + i * (2499 ±0)`
+		// Minimum execution time: 86_925_000 picoseconds.
+		Weight::from_parts(89_056_000, 0)
+			.saturating_add(Weight::from_parts(0, 6583))
+			// Standard Error: 2_429_589
+			.saturating_add(Weight::from_parts(295_368_241, 0).saturating_mul(i.into()))
+			.saturating_add(T::DbWeight::get().reads(3))
 			.saturating_add(T::DbWeight::get().reads((2_u64).saturating_mul(i.into())))
-			.saturating_add(T::DbWeight::get().writes(3))
-			.saturating_add(T::DbWeight::get().writes((2_u64).saturating_mul(i.into())))
+			.saturating_add(T::DbWeight::get().writes(5))
+			.saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(i.into())))
 			.saturating_add(Weight::from_parts(0, 2499).saturating_mul(i.into()))
 	}
 }
diff --git a/runtime/common/src/weights/pallet_membership_smith_membership.rs b/runtime/common/src/weights/pallet_membership_smith_membership.rs
index be9d722ae75852bc23a1477ffc95f5f4138d5d26..d7008fec48c84920bacb37236a257c56fb851ef8 100644
--- a/runtime/common/src/weights/pallet_membership_smith_membership.rs
+++ b/runtime/common/src/weights/pallet_membership_smith_membership.rs
@@ -1,28 +1,41 @@
+// 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/>.
 
 //! Autogenerated weights for `pallet_membership`
 //!
 //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev
-//! DATE: 2023-11-22, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! DATE: 2023-12-14, STEPS: `8`, REPEAT: `4`, LOW RANGE: `[]`, HIGH RANGE: `[]`
 //! WORST CASE MAP SIZE: `1000000`
-//! HOSTNAME: `bgallois-ms7d43`, CPU: `12th Gen Intel(R) Core(TM) i3-12100F`
-//! EXECUTION: None, WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024
+//! HOSTNAME: `squirrel`, CPU: `Intel(R) Core(TM) i7-8565U CPU @ 1.80GHz`
+//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024
 
 // Executed Command:
-// ./target/release/duniter
+// ./target/debug/duniter
 // benchmark
 // pallet
-// --chain
-// dev
+// --chain=dev
+// --steps=8
+// --repeat=4
+// --pallet=pallet-membership
+// --extrinsic=*
+// --execution=wasm
 // --wasm-execution=compiled
-// --pallet
-// *
-// --extrinsic
-// *
-// --steps
-// 50
-// --repeat
-// 20
-// --output=runtime/common/src/weights/
+// --heap-pages=4096
+// --header=./file_header.txt
+// --output=./runtime/common/src/weights/
 
 #![cfg_attr(rustfmt, rustfmt_skip)]
 #![allow(unused_parens)]
@@ -37,30 +50,6 @@ pub struct WeightInfo<T>(PhantomData<T>);
 impl<T: frame_system::Config> pallet_membership::WeightInfo for WeightInfo<T> {
 	/// Storage: Identity IdentityIndexOf (r:1 w:0)
 	/// Proof Skipped: Identity IdentityIndexOf (max_values: None, max_size: None, mode: Measured)
-	/// Storage: Identity Identities (r:1 w:0)
-	/// Proof Skipped: Identity Identities (max_values: None, max_size: None, mode: Measured)
-	/// Storage: SmithMembership PendingMembership (r:1 w:1)
-	/// Proof Skipped: SmithMembership PendingMembership (max_values: None, max_size: None, mode: Measured)
-	/// Storage: SmithMembership Membership (r:1 w:0)
-	/// Proof Skipped: SmithMembership Membership (max_values: None, max_size: None, mode: Measured)
-	/// Storage: Parameters ParametersStorage (r:1 w:0)
-	/// Proof Skipped: Parameters ParametersStorage (max_values: Some(1), max_size: None, mode: Measured)
-	/// Storage: SmithMembership PendingMembershipsExpireOn (r:1 w:1)
-	/// Proof Skipped: SmithMembership PendingMembershipsExpireOn (max_values: None, max_size: None, mode: Measured)
-	fn request_membership() -> Weight {
-		// Proof Size summary in bytes:
-		//  Measured:  `706`
-		//  Estimated: `4171`
-		// Minimum execution time: 14_737_000 picoseconds.
-		Weight::from_parts(15_859_000, 0)
-			.saturating_add(Weight::from_parts(0, 4171))
-			.saturating_add(T::DbWeight::get().reads(6))
-			.saturating_add(T::DbWeight::get().writes(2))
-	}
-	/// Storage: Identity IdentityIndexOf (r:1 w:0)
-	/// Proof Skipped: Identity IdentityIndexOf (max_values: None, max_size: None, mode: Measured)
-	/// Storage: SmithMembership PendingMembership (r:1 w:1)
-	/// Proof Skipped: SmithMembership PendingMembership (max_values: None, max_size: None, mode: Measured)
 	/// Storage: SmithCert StorageIdtyCertMeta (r:1 w:0)
 	/// Proof Skipped: SmithCert StorageIdtyCertMeta (max_values: None, max_size: None, mode: Measured)
 	/// Storage: Parameters ParametersStorage (r:1 w:0)
@@ -73,13 +62,13 @@ impl<T: frame_system::Config> pallet_membership::WeightInfo for WeightInfo<T> {
 	/// Proof Skipped: SmithMembership MembershipsExpireOn (max_values: None, max_size: None, mode: Measured)
 	fn claim_membership() -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `734`
-		//  Estimated: `4199`
-		// Minimum execution time: 19_034_000 picoseconds.
-		Weight::from_parts(20_081_000, 0)
-			.saturating_add(Weight::from_parts(0, 4199))
-			.saturating_add(T::DbWeight::get().reads(7))
-			.saturating_add(T::DbWeight::get().writes(4))
+		//  Measured:  `704`
+		//  Estimated: `4169`
+		// Minimum execution time: 667_020_000 picoseconds.
+		Weight::from_parts(729_140_000, 0)
+			.saturating_add(Weight::from_parts(0, 4169))
+			.saturating_add(T::DbWeight::get().reads(6))
+			.saturating_add(T::DbWeight::get().writes(3))
 	}
 	/// Storage: Identity IdentityIndexOf (r:1 w:0)
 	/// Proof Skipped: Identity IdentityIndexOf (max_values: None, max_size: None, mode: Measured)
@@ -95,8 +84,8 @@ impl<T: frame_system::Config> pallet_membership::WeightInfo for WeightInfo<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `717`
 		//  Estimated: `6657`
-		// Minimum execution time: 16_561_000 picoseconds.
-		Weight::from_parts(17_959_000, 0)
+		// Minimum execution time: 794_915_000 picoseconds.
+		Weight::from_parts(930_094_000, 0)
 			.saturating_add(Weight::from_parts(0, 6657))
 			.saturating_add(T::DbWeight::get().reads(6))
 			.saturating_add(T::DbWeight::get().writes(3))
@@ -127,8 +116,8 @@ impl<T: frame_system::Config> pallet_membership::WeightInfo for WeightInfo<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `1183`
 		//  Estimated: `4648`
-		// Minimum execution time: 34_770_000 picoseconds.
-		Weight::from_parts(38_431_000, 0)
+		// Minimum execution time: 1_199_726_000 picoseconds.
+		Weight::from_parts(1_499_376_000, 0)
 			.saturating_add(Weight::from_parts(0, 4648))
 			.saturating_add(T::DbWeight::get().reads(10))
 			.saturating_add(T::DbWeight::get().writes(13))
@@ -137,58 +126,47 @@ impl<T: frame_system::Config> pallet_membership::WeightInfo for WeightInfo<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `0`
-		// Minimum execution time: 25_000 picoseconds.
-		Weight::from_parts(27_000, 0)
+		// Minimum execution time: 3_972_000 picoseconds.
+		Weight::from_parts(4_845_000, 0)
 			.saturating_add(Weight::from_parts(0, 0))
 	}
-	/// Storage: SmithMembership PendingMembershipsExpireOn (r:1 w:1)
-	/// Proof Skipped: SmithMembership PendingMembershipsExpireOn (max_values: None, max_size: None, mode: Measured)
-	/// Storage: SmithMembership PendingMembership (r:1024 w:1024)
-	/// Proof Skipped: SmithMembership PendingMembership (max_values: None, max_size: None, mode: Measured)
-	/// The range of component `i` is `[0, 1024]`.
-	/// The range of component `i` is `[0, 1024]`.
-	fn expire_pending_memberships(i: u32, ) -> Weight {
-		// Proof Size summary in bytes:
-		//  Measured:  `179 + i * (19 ±0)`
-		//  Estimated: `3649 + i * (2495 ±0)`
-		// Minimum execution time: 2_213_000 picoseconds.
-		Weight::from_parts(2_309_000, 0)
-			.saturating_add(Weight::from_parts(0, 3649))
-			// Standard Error: 981
-			.saturating_add(Weight::from_parts(2_257_315, 0).saturating_mul(i.into()))
-			.saturating_add(T::DbWeight::get().reads(1))
-			.saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(i.into())))
-			.saturating_add(T::DbWeight::get().writes(1))
-			.saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(i.into())))
-			.saturating_add(Weight::from_parts(0, 2495).saturating_mul(i.into()))
-	}
-	/// Storage: Parameters ParametersStorage (r:1 w:0)
-	/// Proof Skipped: Parameters ParametersStorage (max_values: Some(1), max_size: None, mode: Measured)
 	/// Storage: SmithMembership MembershipsExpireOn (r:1 w:1)
 	/// Proof Skipped: SmithMembership MembershipsExpireOn (max_values: None, max_size: None, mode: Measured)
 	/// Storage: SmithMembership Membership (r:1024 w:1024)
 	/// Proof Skipped: SmithMembership Membership (max_values: None, max_size: None, mode: Measured)
 	/// Storage: SmithMembership CounterForMembership (r:1 w:1)
 	/// Proof: SmithMembership CounterForMembership (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen)
-	/// Storage: SmithMembership PendingMembershipsExpireOn (r:1 w:1)
-	/// Proof Skipped: SmithMembership PendingMembershipsExpireOn (max_values: None, max_size: None, mode: Measured)
-	/// Storage: SmithMembership PendingMembership (r:0 w:1024)
-	/// Proof Skipped: SmithMembership PendingMembership (max_values: None, max_size: None, mode: Measured)
+	/// Storage: AuthorityMembers Members (r:1024 w:3)
+	/// Proof Skipped: AuthorityMembers Members (max_values: None, max_size: None, mode: Measured)
+	/// Storage: AuthorityMembers OnlineAuthorities (r:1 w:1)
+	/// Proof Skipped: AuthorityMembers OnlineAuthorities (max_values: Some(1), max_size: None, mode: Measured)
+	/// Storage: AuthorityMembers OutgoingAuthorities (r:1 w:1)
+	/// Proof Skipped: AuthorityMembers OutgoingAuthorities (max_values: Some(1), max_size: None, mode: Measured)
+	/// Storage: AuthorityMembers AuthoritiesCounter (r:1 w:1)
+	/// Proof Skipped: AuthorityMembers AuthoritiesCounter (max_values: Some(1), max_size: None, mode: Measured)
+	/// Storage: AuthorityMembers IncomingAuthorities (r:1 w:1)
+	/// Proof Skipped: AuthorityMembers IncomingAuthorities (max_values: Some(1), max_size: None, mode: Measured)
+	/// Storage: Session NextKeys (r:3 w:3)
+	/// Proof Skipped: Session NextKeys (max_values: None, max_size: None, mode: Measured)
+	/// Storage: System Account (r:3 w:3)
+	/// Proof: System Account (max_values: None, max_size: Some(126), added: 2601, mode: MaxEncodedLen)
+	/// Storage: Session KeyOwner (r:0 w:12)
+	/// Proof Skipped: Session KeyOwner (max_values: None, max_size: None, mode: Measured)
 	/// The range of component `i` is `[0, 1024]`.
 	/// The range of component `i` is `[0, 1024]`.
 	fn expire_memberships(i: u32, ) -> Weight {
 		// Proof Size summary in bytes:
-		//  Measured:  `251 + i * (23 ±0)`
-		//  Estimated: `3735 + i * (2499 ±0)`
-		// Minimum execution time: 4_948_000 picoseconds.
-		Weight::from_parts(5_162_000, 0)
-			.saturating_add(Weight::from_parts(0, 3735))
-			// Standard Error: 953
-			.saturating_add(Weight::from_parts(3_313_144, 0).saturating_mul(i.into()))
-			.saturating_add(T::DbWeight::get().reads(4))
-			.saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(i.into())))
-			.saturating_add(T::DbWeight::get().writes(3))
-			.saturating_add(T::DbWeight::get().writes((2_u64).saturating_mul(i.into())))
+		//  Measured:  `1339 + i * (23 ±0)`
+		//  Estimated: `9830 + i * (2499 ±0)`
+		// Minimum execution time: 81_859_000 picoseconds.
+		Weight::from_parts(90_890_000, 0)
+			.saturating_add(Weight::from_parts(0, 9830))
+			// Standard Error: 1_930_380
+			.saturating_add(Weight::from_parts(304_822_479, 0).saturating_mul(i.into()))
+			.saturating_add(T::DbWeight::get().reads(7))
+			.saturating_add(T::DbWeight::get().reads((2_u64).saturating_mul(i.into())))
+			.saturating_add(T::DbWeight::get().writes(16))
+			.saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(i.into())))
 			.saturating_add(Weight::from_parts(0, 2499).saturating_mul(i.into()))
 	}
 }
diff --git a/runtime/gdev/src/lib.rs b/runtime/gdev/src/lib.rs
index f3b9ec5aa947d83ea4d16161717684bc6b6730c2..5b13dec4398a09ea8847f73c876dc4892c8d5c39 100644
--- a/runtime/gdev/src/lib.rs
+++ b/runtime/gdev/src/lib.rs
@@ -28,8 +28,6 @@ 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,
@@ -135,7 +133,6 @@ pub type Executive = frame_executive::Executive<
     frame_system::ChainContext<Runtime>,
     Runtime,
     AllPalletsWithSystem,
-    migrations_v400::MigrationsV400,
 >;
 
 pub type TechnicalCommitteeInstance = Instance2;
@@ -182,10 +179,8 @@ impl Contains<RuntimeCall> for BaseCallFilter {
             call,
             // in main web of trust, membership request and revoke are handeled through identity pallet
             // the user can not call them directly
-            RuntimeCall::Membership(
-                pallet_membership::Call::request_membership { .. }
-                    | pallet_membership::Call::revoke_membership { .. }
-            ) | RuntimeCall::Session(_)
+            RuntimeCall::Membership(pallet_membership::Call::revoke_membership { .. })
+                | RuntimeCall::Session(_)
         )
     }
 }
@@ -260,7 +255,6 @@ common_runtime::pallets_config! {
     pub type ConfirmPeriod = pallet_duniter_test_parameters::IdtyConfirmPeriod<Runtime>;
     pub type IdtyCreationPeriod = pallet_duniter_test_parameters::IdtyCreationPeriod<Runtime>;
     pub type MembershipPeriod = pallet_duniter_test_parameters::MembershipPeriod<Runtime>;
-    pub type PendingMembershipPeriod = pallet_duniter_test_parameters::PendingMembershipPeriod<Runtime>;
     pub type UdCreationPeriod = pallet_duniter_test_parameters::UdCreationPeriod<Runtime>;
     pub type UdReevalPeriod = pallet_duniter_test_parameters::UdReevalPeriod<Runtime>;
     pub type WotFirstCertIssuableOn = pallet_duniter_test_parameters::WotFirstCertIssuableOn<Runtime>;
@@ -273,8 +267,6 @@ common_runtime::pallets_config! {
         pallet_duniter_test_parameters::SmithCertMinReceivedCertToIssueCert<Runtime>;
     pub type SmithValidityPeriod = pallet_duniter_test_parameters::SmithCertValidityPeriod<Runtime>;
     pub type SmithMembershipPeriod = pallet_duniter_test_parameters::SmithMembershipPeriod<Runtime>;
-    pub type SmithPendingMembershipPeriod =
-        pallet_duniter_test_parameters::SmithPendingMembershipPeriod<Runtime>;
     pub type SmithWotFirstCertIssuableOn =
         pallet_duniter_test_parameters::SmithWotFirstCertIssuableOn<Runtime>;
     pub type SmithWotMinCertForMembership =
diff --git a/runtime/gdev/src/migrations_v400.rs b/runtime/gdev/src/migrations_v400.rs
deleted file mode 100644
index e58e69cb9925985a337336508ae4f99c4d9a9280..0000000000000000000000000000000000000000
--- a/runtime/gdev/src/migrations_v400.rs
+++ /dev/null
@@ -1,45 +0,0 @@
-// 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 = Weight::from_parts(1_000_000_000, 0); // Safety margin
-
-        type OldvalueType = AccountId;
-
-        pallet_membership::PendingMembership::<Runtime, Instance1>::translate_values(
-            |_: OldvalueType| {
-                *weight.ref_time_mut() += <Runtime as frame_system::Config>::DbWeight::get().write;
-                Some(())
-            },
-        );
-
-        weight
-    }
-
-    #[cfg(feature = "try-runtime")]
-    fn pre_upgrade() -> Result<frame_benchmarking::Vec<u8>, &'static str> {
-        Ok(Vec::new())
-    }
-
-    #[cfg(feature = "try-runtime")]
-    fn post_upgrade(_state: frame_benchmarking::Vec<u8>) -> Result<(), &'static str> {
-        Ok(())
-    }
-}
diff --git a/runtime/gdev/tests/common/mod.rs b/runtime/gdev/tests/common/mod.rs
index 673a02252b3a90ce92af5d91e6c16940a5666c00..5c20cd6ab0b337c6989ae8eb1640c836b5424c27 100644
--- a/runtime/gdev/tests/common/mod.rs
+++ b/runtime/gdev/tests/common/mod.rs
@@ -232,8 +232,8 @@ impl ExtBuilder {
                         next_creatable_identity_on: Default::default(),
                         owner_key: owner_key.clone(),
                         old_owner_key: None,
-                        removable_on: 0,
-                        status: IdtyStatus::Validated,
+                        next_scheduled: 0,
+                        status: IdtyStatus::Member,
                     },
                 })
                 .collect(),
diff --git a/runtime/gdev/tests/fixme_tests.rs b/runtime/gdev/tests/fixme_tests.rs
index 2f4d55aac328ba531cd8e8861592a786b54e54c5..028f23600ccebc7d1258815fb514717706143eaf 100644
--- a/runtime/gdev/tests/fixme_tests.rs
+++ b/runtime/gdev/tests/fixme_tests.rs
@@ -20,7 +20,8 @@
 mod common;
 
 use common::*;
-use frame_support::assert_ok;
+// use frame_support::assert_ok;
+use frame_support::assert_noop;
 use gdev_runtime::*;
 use pallet_membership::MembershipRemovalReason;
 use sp_keyring::AccountKeyring;
@@ -30,18 +31,7 @@ use sp_keyring::AccountKeyring;
 /// identity who has no smith membership or pending membership
 #[test]
 fn can_add_smith_cert_without_pending_membership_or_membership() {
-    // 3 smith (1. Alice, 2. Bob, 3. Charlie)
-    // 4 identities (4. Dave)
-    ExtBuilder::new(1, 3, 4).build().execute_with(|| {
-        run_to_block(1);
-
-        // FIXME Bob can add new smith cert to to dave even he did not requested smith membership
-        assert_ok!(SmithCert::add_cert(
-            frame_system::RawOrigin::Signed(AccountKeyring::Bob.to_account_id()).into(),
-            2, // bob
-            4  // dave
-        ));
-    });
+    // this is fixed because membership request has been removed
 }
 
 /// issue #136
@@ -52,28 +42,32 @@ fn can_still_issue_cert_when_membership_lost() {
     ExtBuilder::new(1, 3, 4).build().execute_with(|| {
         run_to_block(1);
 
-        // expire Bob membership (could happen for negative distance evaluation for example)
-        assert_ok!(Membership::force_expire_membership(
-            2, // Bob
-        ));
+        // expire Bob membership
+        Membership::do_remove_membership(
+            2,
+            MembershipRemovalReason::System
+        );
         System::assert_has_event(RuntimeEvent::Membership(
             pallet_membership::Event::MembershipRemoved {
                 member: 2,
-                reason: MembershipRemovalReason::Expired,
+                reason: MembershipRemovalReason::System,
             },
         ));
 
-        // FIXME this should not be possible
-        assert_ok!(Cert::add_cert(
+        // fixed :)
+        assert_noop!(Cert::add_cert(
             frame_system::RawOrigin::Signed(AccountKeyring::Bob.to_account_id()).into(),
-            2, // Bob
-            3, // Charlie
-        ));
-        System::assert_has_event(RuntimeEvent::Cert(
-            pallet_certification::Event::CertRenewed {
-                issuer: 2,
-                receiver: 3,
-            },
-        ));
+                2, // Bob
+                3, // Charlie
+            ),
+            pallet_duniter_wot::Error::<gdev_runtime::Runtime, pallet_certification::Instance1>::IssuerNotMember
+        );
+        // // not anymore
+        // System::assert_has_event(RuntimeEvent::Cert(
+        //     pallet_certification::Event::CertRenewed {
+        //         issuer: 2,
+        //         receiver: 3,
+        //     },
+        // ));
     });
 }
diff --git a/runtime/gdev/tests/integration_tests.rs b/runtime/gdev/tests/integration_tests.rs
index cb3819c843f27b3065ee258f63ec68d030b4cf48..fa700844761e49eaa732756378ea805f4f2d9c0e 100644
--- a/runtime/gdev/tests/integration_tests.rs
+++ b/runtime/gdev/tests/integration_tests.rs
@@ -23,7 +23,6 @@ use frame_support::traits::{Get, PalletInfo, StorageInfo, StorageInfoTrait};
 use frame_support::{assert_noop, assert_ok};
 use frame_support::{StorageHasher, Twox128};
 use gdev_runtime::*;
-use pallet_duniter_wot::IdtyRemovalWotReason;
 use pallet_membership::MembershipRemovalReason;
 use sp_core::Encode;
 use sp_keyring::AccountKeyring;
@@ -284,28 +283,24 @@ fn test_session_change() {
     })
 }
 
-/// test calling force_remove_identity
+/// test calling do_remove_identity
 #[test]
-fn test_force_remove_identity() {
+fn test_remove_identity() {
     ExtBuilder::new(1, 3, 4).build().execute_with(|| {
         run_to_block(2);
         // remove the identity
-        assert_ok!(Identity::force_remove_identity(
-            frame_system::RawOrigin::Root.into(),
-            4,
-            None,
-            pallet_identity::IdtyRemovalReason::Manual
-        ));
-        System::assert_has_event(RuntimeEvent::Membership(
-            pallet_membership::Event::MembershipRemoved {
-                member: 4,
-                reason: MembershipRemovalReason::Revoked,
-            },
-        ));
+        Identity::do_remove_identity(4, pallet_identity::RemovalReason::Root);
+        // // membership removal is no more automatic
+        // System::assert_has_event(RuntimeEvent::Membership(
+        //     pallet_membership::Event::MembershipRemoved {
+        //         member: 4,
+        //         reason: MembershipRemovalReason::System,
+        //     },
+        // ));
         System::assert_has_event(RuntimeEvent::Identity(
             pallet_identity::Event::IdtyRemoved {
                 idty_index: 4,
-                reason: pallet_identity::IdtyRemovalReason::Manual,
+                reason: pallet_identity::RemovalReason::Root,
             },
         ));
         // since Dave does not have ED, his account is killed
@@ -377,15 +372,7 @@ fn test_validate_identity_when_claim() {
                         ),
                 },
             ));
-
-            // ferdie can not validate eve identity because already validated
-            assert_noop!(
-                Identity::validate_identity(
-                    frame_system::RawOrigin::Signed(AccountKeyring::Ferdie.to_account_id()).into(),
-                    5,
-                ),
-                pallet_identity::Error::<Runtime>::IdtyAlreadyValidated
-            );
+            // not possible anymore to validate identity of someone else
         });
 }
 
@@ -401,15 +388,12 @@ fn test_membership_expiry() {
             },
         ));
         // membership expiry should not trigger identity removal
-        assert!(!System::events().iter().any(|record| record.event
-            == RuntimeEvent::Identity(pallet_identity::Event::IdtyRemoved {
-                idty_index: 1,
-                reason: pallet_identity::IdtyRemovalReason::Expired
-            })));
+        assert!(Identity::identity(1).is_some());
     });
 }
 
 #[test]
+#[ignore = "long to go to autorevocation period"]
 fn test_membership_expiry_with_identity_removal() {
     ExtBuilder::new(1, 3, 4).build().execute_with(|| {
         run_to_block(100);
@@ -422,16 +406,12 @@ fn test_membership_expiry_with_identity_removal() {
         ));
 
         // Trigger pending membership expiry
-        run_to_block(
-            100 + <Runtime as pallet_membership::Config<Instance1>>::PendingMembershipPeriod::get(),
-        );
+        run_to_block(100 + <Runtime as pallet_identity::Config>::AutorevocationPeriod::get());
 
         System::assert_has_event(RuntimeEvent::Identity(
-            pallet_identity::Event::IdtyRemoved {
+            pallet_identity::Event::IdtyRevoked {
                 idty_index: 4,
-                reason: pallet_identity::IdtyRemovalReason::Other(
-                    IdtyRemovalWotReason::MembershipExpired,
-                ),
+                reason: pallet_identity::RevocationReason::Expired,
             },
         ));
     });
@@ -496,9 +476,9 @@ fn test_membership_renewal() {
         });
 }
 
-// test that UD are auto claimed when identity is removed
+// test that UD are auto claimed when identity is revoked
 #[test]
-fn test_remove_identity_after_one_ud() {
+fn test_revoke_identity_after_one_ud() {
     ExtBuilder::new(1, 3, 4).build().execute_with(|| {
         //println!("UdCreationPeriod={}", <Runtime as pallet_universal_dividend::Config>::UdCreationPeriod::get());
         run_to_block(
@@ -520,18 +500,13 @@ fn test_remove_identity_after_one_ud() {
                 / <Runtime as pallet_babe::Config>::ExpectedBlockTime::get()
                 + 1) as u32,
         );
-        // remove identity
-        assert_ok!(Identity::force_remove_identity(
-            frame_system::RawOrigin::Root.into(),
-            4,
-            None,
-            pallet_identity::IdtyRemovalReason::Manual
-        ));
+        // revoke identity
+        Identity::do_revoke_identity(4, pallet_identity::RevocationReason::Root);
 
         // Verify events
         // universal dividend was automatically paid to dave
         System::assert_has_event(RuntimeEvent::UniversalDividend(
-            pallet_universal_dividend::Event::UdsAutoPaidAtRemoval {
+            pallet_universal_dividend::Event::UdsAutoPaid {
                 count: 1,
                 total: 1_000,
                 who: AccountKeyring::Dave.to_account_id(),
@@ -550,14 +525,13 @@ fn test_remove_identity_after_one_ud() {
             },
         ));
         System::assert_has_event(RuntimeEvent::Identity(
-            pallet_identity::Event::IdtyRemoved {
+            pallet_identity::Event::IdtyRevoked {
                 idty_index: 4,
-                reason: pallet_identity::IdtyRemovalReason::Manual,
+                reason: pallet_identity::RevocationReason::Root,
             },
         ));
 
-        // thanks to the new UD, Dave has existential deposit and is not killed
-        assert!(Identity::identity(4).is_none());
+        assert!(Identity::identity(4).is_some()); // identity still exists, but its status is revoked
         assert_eq!(
             Balances::free_balance(AccountKeyring::Dave.to_account_id()),
             1_000
@@ -588,9 +562,9 @@ fn test_ud_claimed_membership_on_and_off() {
 
         run_to_block(13);
         // alice identity expires
-        assert_ok!(Membership::force_expire_membership(1));
+        Membership::do_remove_membership(1, MembershipRemovalReason::System);
         System::assert_has_event(RuntimeEvent::UniversalDividend(
-            pallet_universal_dividend::Event::UdsAutoPaidAtRemoval {
+            pallet_universal_dividend::Event::UdsAutoPaid {
                 count: 1,
                 total: 1_000,
                 who: AccountKeyring::Alice.to_account_id(),
@@ -665,18 +639,13 @@ fn test_ud_claimed_membership_on_and_off() {
     });
 }
 
-/// test when root removes and identity, all consumers should be deleted
+/// test when root revokes and identity, all membership should be deleted
 #[test]
-fn test_remove_smith_identity() {
+fn test_revoke_smith_identity() {
     ExtBuilder::new(1, 3, 4).build().execute_with(|| {
         run_to_block(2);
 
-        assert_ok!(Identity::force_remove_identity(
-            frame_system::RawOrigin::Root.into(),
-            3,
-            None,
-            pallet_identity::IdtyRemovalReason::Manual
-        ));
+        Identity::do_revoke_identity(3, pallet_identity::RevocationReason::Root);
         // Verify events
         System::assert_has_event(RuntimeEvent::SmithMembership(
             pallet_membership::Event::MembershipRemoved {
@@ -694,9 +663,9 @@ fn test_remove_smith_identity() {
             },
         ));
         System::assert_has_event(RuntimeEvent::Identity(
-            pallet_identity::Event::IdtyRemoved {
+            pallet_identity::Event::IdtyRevoked {
                 idty_index: 3,
-                reason: pallet_identity::IdtyRemovalReason::Manual,
+                reason: pallet_identity::RevocationReason::Root,
             },
         ));
     });
@@ -733,59 +702,68 @@ fn test_smith_certification() {
 /// test the full process to join smith from main wot member to authority member
 #[test]
 fn test_smith_process() {
-    ExtBuilder::new(1, 3, 4).with_initial_balances(vec![(AccountKeyring::Dave.to_account_id(), 1_000)])
-    .build().execute_with(|| {
-        run_to_block(1);
-
-        let alice = AccountKeyring::Alice.to_account_id();
-        let bob = AccountKeyring::Bob.to_account_id();
-        let charlie = AccountKeyring::Charlie.to_account_id();
+    ExtBuilder::new(1, 3, 4)
+        .with_initial_balances(vec![(AccountKeyring::Dave.to_account_id(), 1_000)])
+        .build()
+        .execute_with(|| {
+            run_to_block(1);
 
-        // Eve can not request smith membership because not member of the smith wot
-        assert_noop!(SmithMembership::request_membership(
-            frame_system::RawOrigin::Signed(AccountKeyring::Eve.to_account_id()).into()),
-            pallet_membership::Error::<gdev_runtime::Runtime, pallet_membership::Instance2>::IdtyIdNotFound,
-        );
+            let alice = AccountKeyring::Alice.to_account_id();
+            let bob = AccountKeyring::Bob.to_account_id();
+            let charlie = AccountKeyring::Charlie.to_account_id();
 
-        // Dave can request smith membership (currently optional)
-        assert_ok!(SmithMembership::request_membership(
-            frame_system::RawOrigin::Signed(AccountKeyring::Dave.to_account_id()).into(),
-        ));
+            // Eve can not request smith membership because not member of the smith wot
+            // no more membership request
 
-        assert_eq!(SmithMembership::pending_membership(5), None); // none for Eve
-        assert_eq!(SmithMembership::pending_membership(4), Some(())); // Dave
+            // Dave can request smith membership (currently optional)
+            // no more membership request
 
-        // then Alice Bob and Charlie can certify Dave
-        assert_ok!(SmithCert::add_cert(frame_system::RawOrigin::Signed(alice).into(), 1, 4));
-        assert_ok!(SmithCert::add_cert(frame_system::RawOrigin::Signed(bob).into(), 2, 4));
-        assert_ok!(SmithCert::add_cert(frame_system::RawOrigin::Signed(charlie).into(), 3, 4));
+            // Alice Bob and Charlie can certify Dave
+            assert_ok!(SmithCert::add_cert(
+                frame_system::RawOrigin::Signed(alice).into(),
+                1,
+                4
+            ));
+            assert_ok!(SmithCert::add_cert(
+                frame_system::RawOrigin::Signed(bob).into(),
+                2,
+                4
+            ));
+            assert_ok!(SmithCert::add_cert(
+                frame_system::RawOrigin::Signed(charlie).into(),
+                3,
+                4
+            ));
 
-        // with these three smith certs, Dave can claim membership
-        assert_ok!(SmithMembership::claim_membership(
-            frame_system::RawOrigin::Signed(AccountKeyring::Dave.to_account_id()).into(),
-        ));
+            // with these three smith certs, Dave can claim membership
+            assert_ok!(SmithMembership::claim_membership(
+                frame_system::RawOrigin::Signed(AccountKeyring::Dave.to_account_id()).into(),
+            ));
 
-        // Dave is then member of the smith wot
-        assert_eq!(SmithMembership::membership(4), Some(sp_membership::MembershipData {
-            expire_on: 1001, // 1 + 1000
-        }));
+            // Dave is then member of the smith wot
+            assert_eq!(
+                SmithMembership::membership(4),
+                Some(sp_membership::MembershipData {
+                    expire_on: 1001, // 1 + 1000
+                })
+            );
 
-        // Dave can set his (dummy) session keys
-        assert_ok!(AuthorityMembers::set_session_keys(
-            frame_system::RawOrigin::Signed(AccountKeyring::Dave.to_account_id()).into(),
-            gdev_runtime::opaque::SessionKeys{
-                grandpa: sp_core::ed25519::Public([0u8; 32]).into(),
-                babe: sp_core::sr25519::Public([0u8; 32]).into(),
-                im_online: sp_core::sr25519::Public([0u8; 32]).into(),
-                authority_discovery: sp_core::sr25519::Public([0u8; 32]).into(),
-            }
-        ));
+            // Dave can set his (dummy) session keys
+            assert_ok!(AuthorityMembers::set_session_keys(
+                frame_system::RawOrigin::Signed(AccountKeyring::Dave.to_account_id()).into(),
+                gdev_runtime::opaque::SessionKeys {
+                    grandpa: sp_core::ed25519::Public([0u8; 32]).into(),
+                    babe: sp_core::sr25519::Public([0u8; 32]).into(),
+                    im_online: sp_core::sr25519::Public([0u8; 32]).into(),
+                    authority_discovery: sp_core::sr25519::Public([0u8; 32]).into(),
+                }
+            ));
 
-        // Dave can go online
-        assert_ok!(AuthorityMembers::go_online(
-            frame_system::RawOrigin::Signed(AccountKeyring::Dave.to_account_id()).into(),
-        ));
-    })
+            // Dave can go online
+            assert_ok!(AuthorityMembers::go_online(
+                frame_system::RawOrigin::Signed(AccountKeyring::Dave.to_account_id()).into(),
+            ));
+        })
 }
 
 /// test create new account with balance lower than existential deposit
@@ -1060,9 +1038,8 @@ fn test_validate_new_idty_after_few_uds() {
                     pallet_distance::DistanceStatus::Valid
                 ))
             ));
-            assert_ok!(Identity::validate_identity(
-                frame_system::RawOrigin::Signed(AccountKeyring::Bob.to_account_id()).into(),
-                5,
+            assert_ok!(Membership::claim_membership(
+                frame_system::RawOrigin::Signed(AccountKeyring::Eve.to_account_id()).into(),
             ));
 
             // The new member should have first_eligible_ud equal to three
diff --git a/runtime/gtest/src/lib.rs b/runtime/gtest/src/lib.rs
index 841a039fc499a0584647ae9cd6a2539aaa8e3750..88fbd282f83728cf10ee03e282715b7ec34ebf67 100644
--- a/runtime/gtest/src/lib.rs
+++ b/runtime/gtest/src/lib.rs
@@ -171,17 +171,10 @@ mod benches {
 pub struct BaseCallFilter;
 
 // implement filter
+// session pallet calls are filtered in order to use authority member instead
 impl Contains<RuntimeCall> for BaseCallFilter {
     fn contains(call: &RuntimeCall) -> bool {
-        !matches!(
-            call,
-            // in main web of trust, membership request and revoke are handeled through identity pallet
-            // the user can not call them directly
-            RuntimeCall::Membership(
-                pallet_membership::Call::request_membership { .. }
-                    | pallet_membership::Call::revoke_membership { .. }
-            ) | RuntimeCall::Session(_)
-        )
+        !matches!(call, RuntimeCall::Session(_))
     }
 }
 
diff --git a/runtime/gtest/src/parameters.rs b/runtime/gtest/src/parameters.rs
index 9f29ce90f9b78334989dccd6c2ffefaed8293672..443e8cffa589424a5ed1fb69d40121c312e356ea 100644
--- a/runtime/gtest/src/parameters.rs
+++ b/runtime/gtest/src/parameters.rs
@@ -71,7 +71,7 @@ parameter_types! {
 /*********/
 
 // Balances
-frame_support::parameter_types! {
+parameter_types! {
     // we take 100 of existential deposit to mimic duniter v1
     // and avoid loosing too many accounts during the migration
     pub const ExistentialDeposit: Balance = 100;
@@ -98,7 +98,7 @@ parameter_types! {
 }
 
 // Identity
-frame_support::parameter_types! {
+parameter_types! {
     pub const ChangeOwnerKeyPeriod: BlockNumber = MONTHS;
     pub const ConfirmPeriod: BlockNumber = DAYS;
     pub const IdtyCreationPeriod: BlockNumber = DAYS;
diff --git a/xtask/src/gen_doc.rs b/xtask/src/gen_doc.rs
index 5822b5bea930a4134f30bf224c35ae3356d75b32..9f077659c73de0d17606231665d2a068f92615d6 100644
--- a/xtask/src/gen_doc.rs
+++ b/xtask/src/gen_doc.rs
@@ -203,7 +203,6 @@ impl CallCategory {
                 "Identity",
                 "remove_identity" | "prune_item_identities_names" | "prune_item_identity_index_of",
             ) => Self::Root,
-            ("Membership", "request_membership" | "revoke_membership") => Self::Disabled,
             ("Cert", "del_cert" | "remove_all_certs_received_by") => Self::Root,
             ("SmithCert", "del_cert" | "remove_all_certs_received_by") => Self::Root,
             ("TechnicalCommittee", "set_members" | "disapprove_proposal") => Self::Root,