diff --git a/db/migrations/1705641339864-Data.js b/db/migrations/1705877992505-Data.js
similarity index 86%
rename from db/migrations/1705641339864-Data.js
rename to db/migrations/1705877992505-Data.js
index f998aee6aaae018df1b27002fe1e38910865b810..d6d2c1b7a83100742001d6bdace1af37be8e3b1d 100644
--- a/db/migrations/1705641339864-Data.js
+++ b/db/migrations/1705877992505-Data.js
@@ -1,5 +1,5 @@
-module.exports = class Data1705641339864 {
-    name = 'Data1705641339864'
+module.exports = class Data1705877992505 {
+    name = 'Data1705877992505'
 
     async up(db) {
         await db.query(`CREATE TABLE "event" ("id" character varying NOT NULL, "index" integer NOT NULL, "phase" text NOT NULL, "pallet" text NOT NULL, "name" text NOT NULL, "args" jsonb, "args_str" text array, "block_id" character varying, "extrinsic_id" character varying, "call_id" character varying, CONSTRAINT "PK_30c2f3bbaf6d34a55f8ae6e4614" PRIMARY KEY ("id"))`)
@@ -54,19 +54,21 @@ module.exports = class Data1705641339864 {
         await db.query(`CREATE INDEX "IDX_af577baa612d86d98a1ae58343" ON "change_owner_key" ("identity_id") `)
         await db.query(`CREATE INDEX "IDX_e09547f07faef3256f7f0381e9" ON "change_owner_key" ("previous_id") `)
         await db.query(`CREATE INDEX "IDX_9a9f8cdcae54d8b4375d70fe8b" ON "change_owner_key" ("next_id") `)
-        await db.query(`CREATE TABLE "identity" ("id" character varying NOT NULL, "index" integer NOT NULL, "name" text NOT NULL, "status" character varying(11) NOT NULL, "account_id" character varying, CONSTRAINT "REL_bafa9e6c71c3f69cef6602a809" UNIQUE ("account_id"), CONSTRAINT "PK_ff16a44186b286d5e626178f726" PRIMARY KEY ("id"))`)
+        await db.query(`CREATE TABLE "identity" ("id" character varying NOT NULL, "index" integer NOT NULL, "name" text NOT NULL, "status" character varying(11) NOT NULL, "smith_status" character varying(8), "account_id" character varying, CONSTRAINT "REL_bafa9e6c71c3f69cef6602a809" UNIQUE ("account_id"), CONSTRAINT "PK_ff16a44186b286d5e626178f726" PRIMARY KEY ("id"))`)
         await db.query(`CREATE UNIQUE INDEX "IDX_6f883c7979ea8dff46327f67cc" ON "identity" ("index") `)
         await db.query(`CREATE UNIQUE INDEX "IDX_bafa9e6c71c3f69cef6602a809" ON "identity" ("account_id") `)
         await db.query(`CREATE INDEX "IDX_883ba5be237fba47f2a2f39145" ON "identity" ("name") `)
         await db.query(`CREATE INDEX "IDX_ee232f862b258f533e70bbb24d" ON "identity" ("status") `)
         await db.query(`CREATE TABLE "account" ("id" character varying NOT NULL, "linked_identity_id" character varying, CONSTRAINT "PK_54115ee388cdb6d86bb4bf5b2ea" PRIMARY KEY ("id"))`)
         await db.query(`CREATE INDEX "IDX_73d14d249a6dcf9abe42eaa657" ON "account" ("linked_identity_id") `)
-        await db.query(`CREATE TABLE "membership" ("id" character varying NOT NULL, "expire_on" integer NOT NULL, "identity_id" character varying, CONSTRAINT "REL_efc905420f5f6bfded16c4eb97" UNIQUE ("identity_id"), CONSTRAINT "PK_83c1afebef3059472e7c37e8de8" PRIMARY KEY ("id"))`)
+        await db.query(`CREATE TABLE "membership_creation" ("id" character varying NOT NULL, "block_number" integer NOT NULL, "membership_id" character varying, CONSTRAINT "REL_e5d3930684fbf95b33e3c0b0a2" UNIQUE ("membership_id"), CONSTRAINT "PK_83b52baf73acff2c5fee412c759" PRIMARY KEY ("id"))`)
+        await db.query(`CREATE UNIQUE INDEX "IDX_e5d3930684fbf95b33e3c0b0a2" ON "membership_creation" ("membership_id") `)
+        await db.query(`CREATE TABLE "membership_renewal" ("id" character varying NOT NULL, "block_number" integer NOT NULL, "membership_id" character varying, CONSTRAINT "REL_5014c63f1d833f455417f80e82" UNIQUE ("membership_id"), CONSTRAINT "PK_dba26e0ad129ff43927cb431857" PRIMARY KEY ("id"))`)
+        await db.query(`CREATE UNIQUE INDEX "IDX_5014c63f1d833f455417f80e82" ON "membership_renewal" ("membership_id") `)
+        await db.query(`CREATE TABLE "membership_removal" ("id" character varying NOT NULL, "block_number" integer NOT NULL, "membership_id" character varying, CONSTRAINT "REL_8437e2d6c78482e62d19e92272" UNIQUE ("membership_id"), CONSTRAINT "PK_9b9bf7018f5d8e6061050805499" PRIMARY KEY ("id"))`)
+        await db.query(`CREATE UNIQUE INDEX "IDX_8437e2d6c78482e62d19e92272" ON "membership_removal" ("membership_id") `)
+        await db.query(`CREATE TABLE "membership" ("id" character varying NOT NULL, "active" boolean NOT NULL, "created_on" integer NOT NULL, "expire_on" integer NOT NULL, "identity_id" character varying, CONSTRAINT "REL_efc905420f5f6bfded16c4eb97" UNIQUE ("identity_id"), CONSTRAINT "PK_83c1afebef3059472e7c37e8de8" PRIMARY KEY ("id"))`)
         await db.query(`CREATE UNIQUE INDEX "IDX_efc905420f5f6bfded16c4eb97" ON "membership" ("identity_id") `)
-        await db.query(`CREATE INDEX "IDX_a3f3d8dc21447800f72c0a27b2" ON "membership" ("expire_on") `)
-        await db.query(`CREATE TABLE "smith_membership" ("id" character varying NOT NULL, "status" character varying(8) NOT NULL, "identity_id" character varying, CONSTRAINT "REL_8645aa09a4cfa921be42f1bdc1" UNIQUE ("identity_id"), CONSTRAINT "PK_ec71fc36eab1a7cb666eb11f60a" PRIMARY KEY ("id"))`)
-        await db.query(`CREATE UNIQUE INDEX "IDX_8645aa09a4cfa921be42f1bdc1" ON "smith_membership" ("identity_id") `)
-        await db.query(`CREATE INDEX "IDX_553a87a08bf4e7909831e6b03b" ON "smith_membership" ("status") `)
         await db.query(`ALTER TABLE "event" ADD CONSTRAINT "FK_2b0d35d675c4f99751855c45021" FOREIGN KEY ("block_id") REFERENCES "block"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`)
         await db.query(`ALTER TABLE "event" ADD CONSTRAINT "FK_129efedcb305c80256db2d57a59" FOREIGN KEY ("extrinsic_id") REFERENCES "extrinsic"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`)
         await db.query(`ALTER TABLE "event" ADD CONSTRAINT "FK_83cf1bd59aa4521ed882fa51452" FOREIGN KEY ("call_id") REFERENCES "call"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`)
@@ -89,8 +91,10 @@ module.exports = class Data1705641339864 {
         await db.query(`ALTER TABLE "change_owner_key" ADD CONSTRAINT "FK_9a9f8cdcae54d8b4375d70fe8be" FOREIGN KEY ("next_id") REFERENCES "account"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`)
         await db.query(`ALTER TABLE "identity" ADD CONSTRAINT "FK_bafa9e6c71c3f69cef6602a8095" FOREIGN KEY ("account_id") REFERENCES "account"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`)
         await db.query(`ALTER TABLE "account" ADD CONSTRAINT "FK_73d14d249a6dcf9abe42eaa6573" FOREIGN KEY ("linked_identity_id") REFERENCES "identity"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`)
+        await db.query(`ALTER TABLE "membership_creation" ADD CONSTRAINT "FK_e5d3930684fbf95b33e3c0b0a27" FOREIGN KEY ("membership_id") REFERENCES "membership"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`)
+        await db.query(`ALTER TABLE "membership_renewal" ADD CONSTRAINT "FK_5014c63f1d833f455417f80e825" FOREIGN KEY ("membership_id") REFERENCES "membership"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`)
+        await db.query(`ALTER TABLE "membership_removal" ADD CONSTRAINT "FK_8437e2d6c78482e62d19e922720" FOREIGN KEY ("membership_id") REFERENCES "membership"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`)
         await db.query(`ALTER TABLE "membership" ADD CONSTRAINT "FK_efc905420f5f6bfded16c4eb978" FOREIGN KEY ("identity_id") REFERENCES "identity"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`)
-        await db.query(`ALTER TABLE "smith_membership" ADD CONSTRAINT "FK_8645aa09a4cfa921be42f1bdc1b" FOREIGN KEY ("identity_id") REFERENCES "identity"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`)
     }
 
     async down(db) {
@@ -153,12 +157,14 @@ module.exports = class Data1705641339864 {
         await db.query(`DROP INDEX "public"."IDX_ee232f862b258f533e70bbb24d"`)
         await db.query(`DROP TABLE "account"`)
         await db.query(`DROP INDEX "public"."IDX_73d14d249a6dcf9abe42eaa657"`)
+        await db.query(`DROP TABLE "membership_creation"`)
+        await db.query(`DROP INDEX "public"."IDX_e5d3930684fbf95b33e3c0b0a2"`)
+        await db.query(`DROP TABLE "membership_renewal"`)
+        await db.query(`DROP INDEX "public"."IDX_5014c63f1d833f455417f80e82"`)
+        await db.query(`DROP TABLE "membership_removal"`)
+        await db.query(`DROP INDEX "public"."IDX_8437e2d6c78482e62d19e92272"`)
         await db.query(`DROP TABLE "membership"`)
         await db.query(`DROP INDEX "public"."IDX_efc905420f5f6bfded16c4eb97"`)
-        await db.query(`DROP INDEX "public"."IDX_a3f3d8dc21447800f72c0a27b2"`)
-        await db.query(`DROP TABLE "smith_membership"`)
-        await db.query(`DROP INDEX "public"."IDX_8645aa09a4cfa921be42f1bdc1"`)
-        await db.query(`DROP INDEX "public"."IDX_553a87a08bf4e7909831e6b03b"`)
         await db.query(`ALTER TABLE "event" DROP CONSTRAINT "FK_2b0d35d675c4f99751855c45021"`)
         await db.query(`ALTER TABLE "event" DROP CONSTRAINT "FK_129efedcb305c80256db2d57a59"`)
         await db.query(`ALTER TABLE "event" DROP CONSTRAINT "FK_83cf1bd59aa4521ed882fa51452"`)
@@ -181,7 +187,9 @@ module.exports = class Data1705641339864 {
         await db.query(`ALTER TABLE "change_owner_key" DROP CONSTRAINT "FK_9a9f8cdcae54d8b4375d70fe8be"`)
         await db.query(`ALTER TABLE "identity" DROP CONSTRAINT "FK_bafa9e6c71c3f69cef6602a8095"`)
         await db.query(`ALTER TABLE "account" DROP CONSTRAINT "FK_73d14d249a6dcf9abe42eaa6573"`)
+        await db.query(`ALTER TABLE "membership_creation" DROP CONSTRAINT "FK_e5d3930684fbf95b33e3c0b0a27"`)
+        await db.query(`ALTER TABLE "membership_renewal" DROP CONSTRAINT "FK_5014c63f1d833f455417f80e825"`)
+        await db.query(`ALTER TABLE "membership_removal" DROP CONSTRAINT "FK_8437e2d6c78482e62d19e922720"`)
         await db.query(`ALTER TABLE "membership" DROP CONSTRAINT "FK_efc905420f5f6bfded16c4eb978"`)
-        await db.query(`ALTER TABLE "smith_membership" DROP CONSTRAINT "FK_8645aa09a4cfa921be42f1bdc1b"`)
     }
 }
diff --git a/schema.graphql b/schema.graphql
index 0cbef69ae81da4ff66299a317b3c0c8aced06c05..590825b9b0bd17a48c118087638fd9473ab87f00 100644
--- a/schema.graphql
+++ b/schema.graphql
@@ -147,8 +147,14 @@ type Identity @entity {
   account: Account! @unique
   "Name"
   name: String! @index
-  "Status"
+  "Status of the identity"
+  # mixes identity pallet status (Unconfirmed, Unvalidated, Revoked)
+  # and membership pallet status (Member, WasMember)
   status: IdentityStatus! @index
+  "Smith status of the identity"
+  # no need for smith membership history for this one
+  # nullable field defaulting to null because most identity are not smith
+  smithStatus: SmithStatus
   "Certifications issued"
   certIssued: [Cert!] @derivedFrom(field: "issuer")
   "Certifications received"
@@ -158,9 +164,8 @@ type Identity @entity {
   "Smith certifications received"
   smithCertReceived: [SmithCert!] @derivedFrom(field: "receiver")
   "Membership of the identity"
+  # this is here that you get all info about the membership history of the identiy
   membership: Membership @derivedFrom(field: "identity")
-  "Smith Membership of the identity"
-  smithMembership: SmithMembership @derivedFrom(field: "identity")
   "Owner key changes"
   ownerKeyChange: [ChangeOwnerKey!] @derivedFrom(field: "identity")
   "linked accounts"
@@ -215,13 +220,36 @@ type SmithCert @entity {
 "Membership"
 type Membership @entity {
   identity: Identity! @unique @index
-  expireOn: Int! @index
+  "whether the membership is active"
+  # useful for indexation
+  active: Boolean!
+  "the last createdOn value"
+  # even if active is false
+  # updated when membership is created or renewed
+  createdOn: Int!
+  "the current expireOn value"
+  # can be in the future if membership is active
+  # or in the past if membership is removed
+  expireOn: Int!
+  # history of the membership
+  creation: [MembershipCreation!] @derivedFrom(field: "membership")
+  renewal: [MembershipRenewal!] @derivedFrom(field: "membership")
+  removal: [MembershipRemoval!] @derivedFrom(field: "membership")
 }
-
-"Smith membership"
-type SmithMembership @entity {
-  identity: Identity! @unique @index
-  status: SmithStatus! @index
+"Membership creation"
+type MembershipCreation @entity {
+  membership: Membership! @unique @index
+  blockNumber: Int!
+}
+"Membership renewal"
+type MembershipRenewal @entity {
+  membership: Membership! @unique @index
+  blockNumber: Int!
+}
+"Membership removal"
+type MembershipRemoval @entity {
+  membership: Membership! @unique @index
+  blockNumber: Int!
 }
 
 enum IdentityStatus {
diff --git a/src/data_handler.ts b/src/data_handler.ts
index f0eb981b60a6b1539eee8d831a54af9b3fe40215..1d4d4ac6470cbc2a3aa04669933ec5b52ff4fab0 100644
--- a/src/data_handler.ts
+++ b/src/data_handler.ts
@@ -9,9 +9,11 @@ import {
   Identity,
   Transfer,
   IdentityStatus,
-  SmithMembership,
   SmithStatus,
   Membership,
+  MembershipRemoval,
+  MembershipCreation,
+  MembershipRenewal,
 } from "./model";
 import { In } from "typeorm";
 import { Address, Ctx, Data, IdtyIndex, NewData } from "./types_custom";
@@ -25,6 +27,9 @@ export class DataHandler {
       accounts: new Map(),
       identities: new Map(),
       memberships: new Map(),
+      membershipCreation: [],
+      membershipRenewal: [],
+      membershipRemoval: [],
       changeOwnerKey: [],
       transfers: [],
       certification: new Map(),
@@ -32,7 +37,6 @@ export class DataHandler {
       certRenewal: [],
       certRemoval: [],
       smithCert: new Map(),
-      smithMemberships: new Map(),
     };
   }
 
@@ -151,38 +155,49 @@ export class DataHandler {
 
     // Process membership added
     for (const membershipAdded of newData.membershipAdded) {
-      const identity = await this.getIdtyByIndexOrFail(ctx, membershipAdded.index);
-      const id = identity.id;
+      const { id, index, expire_on, blockNumber } = membershipAdded;
+      const identity = await this.getIdtyByIndexOrFail(ctx, index);
       // membership should not exist before creation
-      const membership = new Membership({ id, identity, expireOn: membershipAdded.expire_on });
+      const membership = new Membership({ id, identity, expireOn: expire_on, active: true });
       identity.status = IdentityStatus.Member
 
-      this.data.memberships.set(membershipAdded.index, membership);
+      this.data.membershipCreation.push(new MembershipCreation({ id: id, membership, blockNumber: blockNumber }));
+      this.data.memberships.set(index, membership);
       this.data.identities.set(identity.index, identity);
-
     }
 
     // Process membership renewed
     for (const membershipRenewed of newData.membershipRenewed) {
-      const identity = await this.getIdtyByIndexOrFail(ctx, membershipRenewed.index);
-      const id = identity.id;
-      // membership should exist for renew
-      const membership = await ctx.store.findOneByOrFail(Membership, { id })
-
+      const { id, index, expire_on, blockNumber } = membershipRenewed;
+      const identity = await this.getIdtyByIndexOrFail(ctx, index);
+      const membership = await ctx.store.findOneOrFail(Membership, {
+        relations: { identity: true },
+        where: { identity: { index: index } },
+      });
       // Set new expiration time
-      membership.expireOn = membershipRenewed.expire_on;
+      membership.expireOn = expire_on;
+      membership.active = true;
+      identity.status = IdentityStatus.Member
 
-      this.data.memberships.set(membershipRenewed.index, membership);
+      this.data.membershipRenewal.push(new MembershipRenewal({ id: id, membership, blockNumber: blockNumber }));
+      this.data.memberships.set(index, membership);
+      this.data.identities.set(identity.index, identity);
     }
 
     // Process membership removed
     for (const membershipRemoved of newData.membershipRemoved) {
-      const identity = await this.getIdtyByIndexOrFail(ctx, membershipRemoved.index);
-      const id = identity.id;
+      const { id, index, blockNumber } = membershipRemoved;
+      const identity = await this.getIdtyByIndexOrFail(ctx, index);
+      const membership = await ctx.store.findOneOrFail(Membership, {
+        relations: { identity: true },
+        where: { identity: { index: index } },
+      });
+
       identity.status = IdentityStatus.NotMember;
+      membership.active = false;
 
-      // membership should exist for remove
-      await ctx.store.remove(Membership, id);
+      this.data.membershipRemoval.push(new MembershipRemoval({ id: id, membership, blockNumber: blockNumber }));
+      this.data.memberships.set(index, membership);
       this.data.identities.set(identity.index, identity);
     }
 
@@ -295,10 +310,9 @@ export class DataHandler {
     for (const invitedSmith of newData.smithInvited) {
       const { idtyIndex } = invitedSmith;
       const identity = await this.getIdtyByIndexOrFail(ctx, idtyIndex);
-      const id = identity.id;
-      // smith should not exist before invitation
-      const smith = new SmithMembership({ id, identity, status: SmithStatus.Invited });
-      this.data.smithMemberships.set(idtyIndex, smith);
+      identity.smithStatus = SmithStatus.Invited;
+
+      this.data.identities.set(idtyIndex, identity);
     }
 
     // Process Smith invitation accepted
@@ -306,15 +320,8 @@ export class DataHandler {
       const { idtyIndex } = acceptedSmithInvitations;
 
       const identity = await this.getIdtyByIndexOrFail(ctx, idtyIndex);
-      const id = identity.id;
-      // should never fail because smith has been invited before
-      const smith = await ctx.store.findOneByOrFail(SmithMembership, { id })
-      // const smith = await ctx.store.findOneOrFail(SmithMembership, {
-      //   relations: { identity: true },
-      //   where: { identity: { index: idtyIndex } },
-      // });
-      smith.status = SmithStatus.Pending;
-      this.data.smithMemberships.set(idtyIndex, smith);
+      identity.smithStatus = SmithStatus.Pending;
+      this.data.identities.set(idtyIndex, identity);
     }
 
     // Process Smith promotion
@@ -322,15 +329,8 @@ export class DataHandler {
       const { idtyIndex } = promotedSmith;
 
       const identity = await this.getIdtyByIndexOrFail(ctx, idtyIndex);
-      const id = identity.id;
-      // should never fail because smith has been invited before
-      const smith = await ctx.store.findOneByOrFail(SmithMembership, { id })
-      // const smith = await ctx.store.findOneOrFail(SmithMembership, {
-      //   relations: { identity: true },
-      //   where: { identity: { index: idtyIndex } },
-      // });
-      smith.status = SmithStatus.Smith;
-      this.data.smithMemberships.set(idtyIndex, smith);
+      identity.smithStatus = SmithStatus.Smith;
+      this.data.identities.set(idtyIndex, identity);
     }
 
     // Process Smith exlusion
@@ -338,12 +338,9 @@ export class DataHandler {
       const { idtyIndex } = excludedSmith;
 
       const identity = await this.getIdtyByIndexOrFail(ctx, idtyIndex);
-      const id = identity.id;
-      // should never fail because smith has been invited before
-      const smith = await ctx.store.findOneByOrFail(SmithMembership, { id })
 
-      smith.status = SmithStatus.Excluded;
-      this.data.smithMemberships.set(idtyIndex, smith);
+      identity.smithStatus = SmithStatus.Excluded;
+      this.data.identities.set(idtyIndex, identity);
     }
 
     // Process account links
@@ -437,8 +434,6 @@ export class DataHandler {
     await ctx.store.upsert([...this.data.identities.values()]);
     // memberships can have been changed (renewed, removed...) or added (added)
     await ctx.store.upsert([...this.data.memberships.values()]);
-    // smiths can have been changed (invited, pending...) or added (invited)
-    await ctx.store.upsert([...this.data.smithMemberships.values()]);
     // certs can have been changed (renewed, removed...)
     await ctx.store.upsert([...this.data.certification.values()]);
     await ctx.store.upsert([...this.data.smithCert.values()]);
@@ -449,6 +444,9 @@ export class DataHandler {
     await ctx.store.insert(this.data.certCreation);
     await ctx.store.insert(this.data.certRenewal);
     await ctx.store.insert(this.data.certRemoval);
+    await ctx.store.insert(this.data.membershipCreation);
+    await ctx.store.insert(this.data.membershipRenewal);
+    await ctx.store.insert(this.data.membershipRemoval);
 
     // Apply changes in database
     await ctx.store.commit();
diff --git a/src/genesis.ts b/src/genesis.ts
index 5223d139b230544449ba1817c7af75808109758e..ab584dba23602fb76e4f09e8d8eacf520f6c359a 100644
--- a/src/genesis.ts
+++ b/src/genesis.ts
@@ -1,6 +1,6 @@
 import type { Address, IdtyIndex, Ctx, Genesis, TransactionHistory, Tx } from "./types_custom";
 import { readFileSync } from "fs";
-import { Account, Cert, SmithCert, Identity, Membership, SmithMembership, Transfer, ChangeOwnerKey, IdentityStatus, SmithStatus } from "./model";
+import { Account, Cert, SmithCert, Identity, Membership, Transfer, ChangeOwnerKey, SmithStatus, MembershipCreation } from "./model";
 import path from "path/posix";
 
 export async function saveGenesis(ctx: Ctx) {
@@ -18,7 +18,7 @@ export async function saveGenesis(ctx: Ctx) {
   const certs: Cert[] = [];
   const smithCerts: SmithCert[] = [];
   const memberships: Membership[] = [];
-  const smithMemberships: SmithMembership[] = [];
+  const membershipsCreation: MembershipCreation[] = [];
 
   // collect accounts
   for (const [address] of Object.entries(genesis.account.accounts)) {
@@ -82,13 +82,10 @@ export async function saveGenesis(ctx: Ctx) {
   // collect smith memberships
   for (const [idtyIdex, smithCertsData] of Object.entries(genesis.smithMembers.initialSmiths)) {
     const [isOnline, certs] = smithCertsData as [boolean, number[]];
-    smithMemberships.push(
-      new SmithMembership({
-        id: `genesis-${idtyIdex}`,
-        identity: identities.get(parseInt(idtyIdex)),
-        status: SmithStatus.Smith,
-      })
-    );
+    const identity = identities.get(parseInt(idtyIdex))!;
+    identity.smithStatus = SmithStatus.Smith;
+    identities.set(identity.index, identity);
+
     for (const issuer_index of certs) {
       smithCerts.push(
         new SmithCert({
@@ -103,13 +100,16 @@ export async function saveGenesis(ctx: Ctx) {
 
   // collect memberships
   for (const [idtyId, mshipInfo] of Object.entries(genesis.membership.memberships)) {
-    memberships.push(
-      new Membership({
-        id: `genesis-${idtyId}`,
-        identity: identities.get(parseInt(idtyId)),
-        expireOn: mshipInfo.expire_on,
-      })
-    );
+    const membership = new Membership({
+      id: `genesis-${idtyId}`,
+      identity: identities.get(parseInt(idtyId)),
+      createdOn: 0,
+      expireOn: mshipInfo.expire_on,
+      active: true,
+    });
+
+    memberships.push(membership);
+    membershipsCreation.push(new MembershipCreation({ id: `genesis-${idtyId}`, membership: membership, blockNumber: 0 }));
   }
 
   ctx.log.info("Saving genesis");
@@ -121,7 +121,7 @@ export async function saveGenesis(ctx: Ctx) {
   await ctx.store.insert(chok);
   await ctx.store.insert(smithCerts);
   await ctx.store.insert(memberships);
-  await ctx.store.insert(smithMemberships);
+  await ctx.store.insert(membershipsCreation);
   // await ctx.store.flush(); // do not flush otherwise we lose cache
 
   ctx.log.info("Genesis saved");
diff --git a/src/main.ts b/src/main.ts
index d6940e0d66988f87d6c1f34b43e1a905299bf608..7228002720f5a55e96efb4d8dc865470615a06b8 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -205,6 +205,7 @@ function collectDataFromEvents(ctx: Ctx, newData: NewData) {
             id: event.id,
             index: membershipAdded.member,
             expire_on: membershipAdded.expireOn,
+            blockNumber: block.header.height,
           });
           break;
         }
@@ -215,6 +216,7 @@ function collectDataFromEvents(ctx: Ctx, newData: NewData) {
             id: event.id,
             index: membershipRemoved.member,
             reason: membershipRemoved.reason,
+            blockNumber: block.header.height,
           });
           break;
         }
@@ -225,6 +227,7 @@ function collectDataFromEvents(ctx: Ctx, newData: NewData) {
             id: event.id,
             index: membershipRenewed.member,
             expire_on: membershipRenewed.expireOn,
+            blockNumber: block.header.height,
           });
           break;
         }
diff --git a/src/model/generated/identity.model.ts b/src/model/generated/identity.model.ts
index 779a6e90f727d52e713ba25432282d3af883a1e1..8360566b22ff0eba3d30ee106e28040ae99d51eb 100644
--- a/src/model/generated/identity.model.ts
+++ b/src/model/generated/identity.model.ts
@@ -1,10 +1,10 @@
 import {Entity as Entity_, Column as Column_, PrimaryColumn as PrimaryColumn_, Index as Index_, OneToOne as OneToOne_, JoinColumn as JoinColumn_, OneToMany as OneToMany_} from "typeorm"
 import {Account} from "./account.model"
 import {IdentityStatus} from "./_identityStatus"
+import {SmithStatus} from "./_smithStatus"
 import {Cert} from "./cert.model"
 import {SmithCert} from "./smithCert.model"
 import {Membership} from "./membership.model"
-import {SmithMembership} from "./smithMembership.model"
 import {ChangeOwnerKey} from "./changeOwnerKey.model"
 
 /**
@@ -42,12 +42,18 @@ export class Identity {
     name!: string
 
     /**
-     * Status
+     * Status of the identity
      */
     @Index_()
     @Column_("varchar", {length: 11, nullable: false})
     status!: IdentityStatus
 
+    /**
+     * Smith status of the identity
+     */
+    @Column_("varchar", {length: 8, nullable: true})
+    smithStatus!: SmithStatus | undefined | null
+
     /**
      * Certifications issued
      */
@@ -76,10 +82,6 @@ export class Identity {
      * Membership of the identity
      */
 
-    /**
-     * Smith Membership of the identity
-     */
-
     /**
      * Owner key changes
      */
diff --git a/src/model/generated/index.ts b/src/model/generated/index.ts
index a4c06db7570869a7f7b9a7fc49ece023d0e44f33..aceafa281d671b8907aafebec94ea44a2df6756a 100644
--- a/src/model/generated/index.ts
+++ b/src/model/generated/index.ts
@@ -10,6 +10,7 @@ export * from "./account.model"
 export * from "./transfer.model"
 export * from "./identity.model"
 export * from "./_identityStatus"
+export * from "./_smithStatus"
 export * from "./changeOwnerKey.model"
 export * from "./cert.model"
 export * from "./certCreation.model"
@@ -17,5 +18,6 @@ export * from "./certRenewal.model"
 export * from "./certRemoval.model"
 export * from "./smithCert.model"
 export * from "./membership.model"
-export * from "./smithMembership.model"
-export * from "./_smithStatus"
+export * from "./membershipCreation.model"
+export * from "./membershipRenewal.model"
+export * from "./membershipRemoval.model"
diff --git a/src/model/generated/membership.model.ts b/src/model/generated/membership.model.ts
index 9bec4caaa0173de55369181c0a1d53d8fc089453..d4a473e720ea66b9733f1dcad4b93aa510345801 100644
--- a/src/model/generated/membership.model.ts
+++ b/src/model/generated/membership.model.ts
@@ -1,5 +1,8 @@
-import {Entity as Entity_, Column as Column_, PrimaryColumn as PrimaryColumn_, OneToOne as OneToOne_, Index as Index_, JoinColumn as JoinColumn_} from "typeorm"
+import {Entity as Entity_, Column as Column_, PrimaryColumn as PrimaryColumn_, OneToOne as OneToOne_, Index as Index_, JoinColumn as JoinColumn_, OneToMany as OneToMany_} from "typeorm"
 import {Identity} from "./identity.model"
+import {MembershipCreation} from "./membershipCreation.model"
+import {MembershipRenewal} from "./membershipRenewal.model"
+import {MembershipRemoval} from "./membershipRemoval.model"
 
 /**
  * Membership
@@ -18,7 +21,30 @@ export class Membership {
     @JoinColumn_()
     identity!: Identity
 
-    @Index_()
+    /**
+     * whether the membership is active
+     */
+    @Column_("bool", {nullable: false})
+    active!: boolean
+
+    /**
+     * the last createdOn value
+     */
+    @Column_("int4", {nullable: false})
+    createdOn!: number
+
+    /**
+     * the current expireOn value
+     */
     @Column_("int4", {nullable: false})
     expireOn!: number
+
+    @OneToMany_(() => MembershipCreation, e => e.membership)
+    creation!: MembershipCreation[]
+
+    @OneToMany_(() => MembershipRenewal, e => e.membership)
+    renewal!: MembershipRenewal[]
+
+    @OneToMany_(() => MembershipRemoval, e => e.membership)
+    removal!: MembershipRemoval[]
 }
diff --git a/src/model/generated/membershipCreation.model.ts b/src/model/generated/membershipCreation.model.ts
new file mode 100644
index 0000000000000000000000000000000000000000..813ab355d03c173456ac87995c81be16cd9ced20
--- /dev/null
+++ b/src/model/generated/membershipCreation.model.ts
@@ -0,0 +1,23 @@
+import {Entity as Entity_, Column as Column_, PrimaryColumn as PrimaryColumn_, OneToOne as OneToOne_, Index as Index_, JoinColumn as JoinColumn_} from "typeorm"
+import {Membership} from "./membership.model"
+
+/**
+ * Membership creation
+ */
+@Entity_()
+export class MembershipCreation {
+    constructor(props?: Partial<MembershipCreation>) {
+        Object.assign(this, props)
+    }
+
+    @PrimaryColumn_()
+    id!: string
+
+    @Index_({unique: true})
+    @OneToOne_(() => Membership, {nullable: true})
+    @JoinColumn_()
+    membership!: Membership
+
+    @Column_("int4", {nullable: false})
+    blockNumber!: number
+}
diff --git a/src/model/generated/membershipRemoval.model.ts b/src/model/generated/membershipRemoval.model.ts
new file mode 100644
index 0000000000000000000000000000000000000000..baed4d9f553e025ca54688d70c4a2528a69169a8
--- /dev/null
+++ b/src/model/generated/membershipRemoval.model.ts
@@ -0,0 +1,23 @@
+import { Entity as Entity_, Column as Column_, PrimaryColumn as PrimaryColumn_, OneToOne as OneToOne_, Index as Index_, JoinColumn as JoinColumn_ } from "typeorm"
+import { Membership } from "./membership.model"
+
+/**
+ * Membership removal
+ */
+@Entity_()
+export class MembershipRemoval {
+    constructor(props?: Partial<MembershipRemoval>) {
+        Object.assign(this, props)
+    }
+
+    @PrimaryColumn_()
+    id!: string
+
+    @Index_({ unique: true })
+    @OneToOne_(() => Membership, { nullable: true })
+    @JoinColumn_()
+    membership!: Membership
+
+    @Column_("int4", { nullable: false })
+    blockNumber!: number
+}
diff --git a/src/model/generated/membershipRenewal.model.ts b/src/model/generated/membershipRenewal.model.ts
new file mode 100644
index 0000000000000000000000000000000000000000..6b633e6c6fe930f80db49a76412d19ac1acbcda6
--- /dev/null
+++ b/src/model/generated/membershipRenewal.model.ts
@@ -0,0 +1,23 @@
+import {Entity as Entity_, Column as Column_, PrimaryColumn as PrimaryColumn_, OneToOne as OneToOne_, Index as Index_, JoinColumn as JoinColumn_} from "typeorm"
+import {Membership} from "./membership.model"
+
+/**
+ * Membership renewal
+ */
+@Entity_()
+export class MembershipRenewal {
+    constructor(props?: Partial<MembershipRenewal>) {
+        Object.assign(this, props)
+    }
+
+    @PrimaryColumn_()
+    id!: string
+
+    @Index_({unique: true})
+    @OneToOne_(() => Membership, {nullable: true})
+    @JoinColumn_()
+    membership!: Membership
+
+    @Column_("int4", {nullable: false})
+    blockNumber!: number
+}
diff --git a/src/model/generated/smithMembership.model.ts b/src/model/generated/smithMembership.model.ts
deleted file mode 100644
index 44dd305beeeb9628abef0f9a0cf25fb09493555c..0000000000000000000000000000000000000000
--- a/src/model/generated/smithMembership.model.ts
+++ /dev/null
@@ -1,25 +0,0 @@
-import {Entity as Entity_, Column as Column_, PrimaryColumn as PrimaryColumn_, OneToOne as OneToOne_, Index as Index_, JoinColumn as JoinColumn_} from "typeorm"
-import {Identity} from "./identity.model"
-import {SmithStatus} from "./_smithStatus"
-
-/**
- * Smith membership
- */
-@Entity_()
-export class SmithMembership {
-    constructor(props?: Partial<SmithMembership>) {
-        Object.assign(this, props)
-    }
-
-    @PrimaryColumn_()
-    id!: string
-
-    @Index_({unique: true})
-    @OneToOne_(() => Identity, {nullable: true})
-    @JoinColumn_()
-    identity!: Identity
-
-    @Index_()
-    @Column_("varchar", {length: 8, nullable: false})
-    status!: SmithStatus
-}
diff --git a/src/types_custom.ts b/src/types_custom.ts
index dcab2c2a5e1c16457423f02572f0896e9223f5da..aa1ee9f6c81887e6ec868ac339db5f6eab69c353 100644
--- a/src/types_custom.ts
+++ b/src/types_custom.ts
@@ -8,8 +8,10 @@ import {
   Identity,
   IdentityStatus,
   Membership,
+  MembershipCreation,
+  MembershipRemoval,
+  MembershipRenewal,
   SmithCert,
-  SmithMembership,
   Transfer,
 } from "./model";
 import { ProcessorContext } from "./processor";
@@ -79,7 +81,7 @@ interface GenIdtyData {
 }
 
 interface GenMemberships {
-  memberships: Map<number, GenMembership>;
+  memberships: Map<IdtyIndex, GenMembership>;
 }
 
 interface GenMembership {
@@ -117,6 +119,9 @@ export interface Data {
   accounts: Map<Address, Account>;
   identities: Map<IdtyIndex, Identity>;
   memberships: Map<IdtyIndex, Membership>;
+  membershipCreation: MembershipCreation[];
+  membershipRenewal: MembershipRenewal[];
+  membershipRemoval: MembershipRemoval[];
   changeOwnerKey: ChangeOwnerKey[];
   transfers: Transfer[];
   certification: Map<[IdtyIndex, IdtyIndex], Cert>;
@@ -124,7 +129,6 @@ export interface Data {
   certRenewal: CertRenewal[];
   certRemoval: CertRemoval[];
   smithCert: Map<[IdtyIndex, IdtyIndex], SmithCert>;
-  smithMemberships: Map<IdtyIndex, SmithMembership>;
 }
 
 // =========================== Events =========================== //
@@ -262,18 +266,21 @@ interface MembershipAddedEvent {
   id: string;
   index: IdtyIndex;
   expire_on: number;
+  blockNumber: BlockNumber;
 }
 
 interface MembershipRemovedEvent {
   id: string;
   index: IdtyIndex;
   reason: MembershipRemovalReason;
+  blockNumber: BlockNumber;
 }
 
 interface MembershipRenewedEvent {
   id: string;
   index: IdtyIndex;
   expire_on: number;
+  blockNumber: BlockNumber;
 }
 
 interface AccountLinkEvent {