diff --git a/package.json b/package.json
index 36dfc618bf7114793e8064d36b649e977f75a1b7..8a0e1a8dae14e9d86d9918ebe3d86ed7c53dfe04 100644
--- a/package.json
+++ b/package.json
@@ -2,7 +2,7 @@
   "name": "squid",
   "author": "Hugo Trentesaux <hugo@trentesaux.fr>",
   "license": "AGPL-3.0",
-  "version": "0.2.8",
+  "version": "0.2.9",
   "private": true,
   "engines": {
     "node": ">=20"
diff --git a/schema.graphql b/schema.graphql
index 60e1aa33a8dc0e83c327548ae9007602fbdd8094..821f9ef05b6e08304501ba8991ebd1617c54cdfc 100644
--- a/schema.graphql
+++ b/schema.graphql
@@ -276,11 +276,14 @@ type ChangeOwnerKey @entity {
 
 "Certification"
 type Cert @entity {
+  "certification source"
   issuer: Identity! @index
+  "certification target"
   receiver: Identity! @index
-  "whether the certification is currently active or not" # helper to avoid compare expireOn to current block number
+  "whether the certification is currently active or not"
   isActive: Boolean!
-  "the first block number of the certification creation" # helper field to avoid looking for all CertCreation
+  "the first block number of the certification creation"
+  # (helper field to avoid looking for all CertCreation and choose the first)
   createdOn: Int!
   "the event corresponding to the first certification creation"
   createdIn: Event!
@@ -288,8 +291,12 @@ type Cert @entity {
   updatedOn: Int!
   "the event corresponding to the last certification renewal"
   updatedIn: Event!
-  "the current expireOn value" # helper field to avoid looking for all CertRenewal and search for the last one
+  "the current expireOn value"
+  # usually this is updatedOn + certDuration *but*:
+  # - certs can be removed prematurely for unconfirmed or unvalidated identity
+  # - update can be before genesis, in this case we still need expire block after genesis
   expireOn: Int!
+  "list all events of this cert"
   certHistory: [CertEvent!] @derivedFrom(field: "cert")
 }
 
diff --git a/src/data_handler.ts b/src/data_handler.ts
index 101453bc68cd9f7d927e59dba0caa17ed6ba4947..ae2ddbd1ab87f108a9260b8b4b8eb667e5b9cce6 100644
--- a/src/data_handler.ts
+++ b/src/data_handler.ts
@@ -114,14 +114,14 @@ export class DataHandler {
       const remarkRaw = Buffer.from(remarkHex.substring(2), "hex") // convert it back to bytes
       const [commentType, remarkString] = getCommentType(remarkRaw)
       const txcomment = new TxComment({
-        blockNumber: commentEvt.blockNumber,
         id: commentEvt.event.id,
         author: sender,
-        event: await ctx.store.getOrFail(Event, commentEvt.event!.id),
         remarkBytes: remarkRaw,
         remark: remarkString,
         hash: commentEvt.hash, // raw hex hash (temporary)
         type: commentType,
+        event: await ctx.store.getOrFail(Event, commentEvt.event!.id),
+        blockNumber: commentEvt.blockNumber,
       })
       this.data.comments.push(txcomment)
 
@@ -303,14 +303,14 @@ export class DataHandler {
 
     // Process certifications creations
     for (const c of newData.certCreation) {
-      const { issuerId, receiverId, createdOn, expireOn, event } = c;
+      const { issuerId, receiverId, blockNumber, expireOn, event } = c;
       // first creation of the cert
       let cert = await ctx.store.findOne(Cert, {
         relations: { issuer: true, receiver: true },
         where: { issuer: { index: issuerId }, receiver: { index: receiverId } },
       });
 
-      const createdIn = await ctx.store.getOrFail(Event, event.id);
+      const eventObj = await ctx.store.getOrFail(Event, event.id);
       if (cert == null) {
         const issuer = await this.getIdtyByIndexOrFail(ctx, issuerId);
         const receiver = await this.getIdtyByIndexOrFail(ctx, receiverId);
@@ -319,18 +319,18 @@ export class DataHandler {
           isActive: true,
           issuer,
           receiver,
-          createdOn,
-          createdIn,
-          updatedOn: createdOn,
-          updatedIn: createdIn,
-          expireOn,
+          createdOn: blockNumber,
+          createdIn: eventObj,
+          updatedOn: blockNumber,
+          updatedIn: eventObj,
+          expireOn
         });
         // the cert has already existed, expired, and is created again
         // we update it accordingly
       } else {
         cert.isActive = true;
-        cert.updatedOn = createdOn;
-        cert.updatedIn = createdIn;
+        cert.updatedOn = blockNumber;
+        cert.updatedIn = eventObj;
         cert.expireOn = expireOn;
       }
 
@@ -340,9 +340,9 @@ export class DataHandler {
         new CertEvent({
           id: event.id,
           cert,
-          blockNumber: createdOn,
           eventType: EventType.Creation,
-          event: await ctx.store.getOrFail(Event, event.id),
+          event: eventObj,
+          blockNumber,
         })
       );
     }
@@ -356,19 +356,19 @@ export class DataHandler {
         relations: { issuer: true, receiver: true },
         where: { issuer: { index: issuerId }, receiver: { index: receiverId } },
       });
-      const createdIn = await ctx.store.getOrFail(Event, event.id);
+      const eventObj = await ctx.store.getOrFail(Event, event.id);
       // update expiration date
       cert.expireOn = expireOn;
       cert.updatedOn = blockNumber;
-      cert.updatedIn = createdIn;
+      cert.updatedIn = eventObj;
       this.data.certification.set([issuerId, receiverId], cert);
       this.data.certEvent.push(
         new CertEvent({
           id: event.id,
           cert,
-          blockNumber,
           eventType: EventType.Renewal,
-          event: await ctx.store.getOrFail(Event, event.id),
+          event: eventObj,
+          blockNumber,
         })
       );
     }
@@ -389,23 +389,20 @@ export class DataHandler {
       const { issuerId, receiverId, blockNumber, event } = c;
       // should never fail because cert removal can only happen on existing cert
       // and cert should not be removed at their creation block
-      const createdIn = await ctx.store.getOrFail(Event, event.id);
       const cert = await ctx.store.findOneOrFail(Cert, {
         relations: { issuer: true, receiver: true },
         where: { issuer: { index: issuerId }, receiver: { index: receiverId } },
       });
       // update cert
       cert.isActive = false;
-      cert.expireOn = blockNumber;
       this.data.certification.set([issuerId, receiverId], cert);
-
       this.data.certEvent.push(
         new CertEvent({
           id: event.id,
           cert,
-          blockNumber,
           eventType: EventType.Removal,
           event: await ctx.store.getOrFail(Event, event.id),
+          blockNumber,
         })
       );
     }
@@ -544,15 +541,14 @@ export class DataHandler {
     // Process universal dividend
     for (const ud of newData.universalDividend) {
       const { blockNumber, amount, monetaryMass, membersCount, event, timestamp } = ud;
-      const createdIn = await ctx.store.getOrFail(Event, event.id);
       this.data.universalDividend.push(new UniversalDividend({
         id: event.id,
-        blockNumber,
         timestamp: timestamp,
         amount: BigInt(amount),
         monetaryMass,
         membersCount: Number(membersCount),
-        event: createdIn,
+        event: await ctx.store.getOrFail(Event, event.id),
+        blockNumber,
       }));
     }
 
@@ -560,15 +556,14 @@ export class DataHandler {
     for (const udReeval of newData.udReeval) {
       const { blockNumber, newUdAmount, monetaryMass, membersCount, event, timestamp } =
         udReeval;
-      const createdIn = await ctx.store.getOrFail(Event, event.id);
       this.data.udReeval.push(new UdReeval({
         id: event.id,
-        blockNumber,
         timestamp: timestamp,
         newUdAmount: BigInt(newUdAmount),
         monetaryMass,
         membersCount: Number(membersCount),
-        event: createdIn,
+        event: await ctx.store.getOrFail(Event, event.id),
+        blockNumber,
       }));
     }
   }
diff --git a/src/genesis/genesis.ts b/src/genesis/genesis.ts
index 4bf77bfb2d62bc6476446448cb5b9bb63a1d5a95..426a8ae7221d84edd40870ed686db48fb027e9fe 100644
--- a/src/genesis/genesis.ts
+++ b/src/genesis/genesis.ts
@@ -20,11 +20,11 @@ export async function saveGenesis(ctx: Ctx, block: Block) {
   const v1_to_v2 = (n: number) => v1_to_v2_height(n, last_v1_block) // converter
   const NOTIF_INTERVAL = 100000
   // cert validity in number of v2 blocks
-  // const CERTVALIDITYv2 = 5259600 // 2 years in blocks = 365.25 * 24 * 60 * 60 / 6
+  // const CERTVALIDITYv2 = 10519200 // 2 years in blocks = 2 * 365.25 * 24 * 60 * 60 / 6
   // cert validity in number of v1 blocks
   // time interval of v1 blocks measured between block 0 and 729313
   // 311.17641533 seconds unix2datetime(1715932132) - unix2datetime(1488987127) / 729313
-  const CERTVALIDITYv1 = 101413 // 2 years in blocks = 365.25 * 24 * 60 * 60 / 311.17641533
+  const CERTVALIDITYv1 = 202828 // 2 years in blocks = 2 * 365.25 * 24 * 60 * 60 / 311.17641533
   // with 5 min block time (300 seconds) validity would be 105192
 
   // negative block number to history blocks
@@ -321,9 +321,6 @@ export async function saveGenesis(ctx: Ctx, block: Block) {
       });
       certs.set(certstr, cert)
     } else {
-      // update cert
-      cert.updatedOn = negHeight
-      cert.updatedIn = fakeBlockEvents.get(negHeight)!
       switch (c.type) {
         case EventType.Creation:
           // TODO decide what should be the value of createdOn
@@ -332,15 +329,23 @@ export async function saveGenesis(ctx: Ctx, block: Block) {
             cert.createdOn = negHeight
             cert.createdIn = fakeBlockEvents.get(negHeight)!
           }
+          // update cert in any case
+          cert.updatedOn = negHeight
+          cert.updatedIn = fakeBlockEvents.get(negHeight)!
           break
         case EventType.Renewal:
           // only update expiration block if it is before genesis
+          // otherwise, it will be known at genesis
           if (negExpire < 0) {
             cert.expireOn = negExpire
           }
+          // update cert
+          cert.updatedOn = negHeight
+          cert.updatedIn = fakeBlockEvents.get(negHeight)!
           break
         case EventType.Removal:
           // do not touch isActive since the genesis value is already known
+          // cert removal does not touch cert "updatedOn"
           break
       }
     }
diff --git a/src/main.ts b/src/main.ts
index c72a13386d17b0c48ccdbe1b8346ad66ab0ae6d4..ac45b8b1ba30fafc1b081c80909b167012c0ae41 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -273,6 +273,9 @@ function collectDataFromEvents(ctx: Ctx, newData: NewData) {
             index: evt.member,
             // after membership added, there is a given time to renew
             expireOn: evt.expireOn,
+            // should be equal to:
+            //   block.header.height +
+            //   constants.membership.membershipPeriod.v800.get(event.block),
             event: event,
           });
           acc.memberCount += 1;
@@ -302,6 +305,9 @@ function collectDataFromEvents(ctx: Ctx, newData: NewData) {
             index: evt.member,
             // after membership renewed, there is a given time to renew again
             expireOn: evt.expireOn,
+            // should be equal to:
+            //   block.header.height +
+            //   constants.membership.membershipPeriod.v800.get(event.block),
             event: event,
           });
           break;
@@ -312,7 +318,7 @@ function collectDataFromEvents(ctx: Ctx, newData: NewData) {
           newData.certCreation.push({
             issuerId: evt.issuer,
             receiverId: evt.receiver,
-            createdOn: block.header.height,
+            blockNumber: block.header.height,
             expireOn:
               block.header.height +
               constants.certification.validityPeriod.v800.get(event.block),
diff --git a/src/model/generated/cert.model.ts b/src/model/generated/cert.model.ts
index 807f46dd6a3eac6a2a6f12bf832e42b6e15dfa72..805862edf7e148591b5c391a0bbe0597dca26e78 100644
--- a/src/model/generated/cert.model.ts
+++ b/src/model/generated/cert.model.ts
@@ -15,10 +15,16 @@ export class Cert {
     @PrimaryColumn_()
     id!: string
 
+    /**
+     * certification source
+     */
     @Index_()
     @ManyToOne_(() => Identity, {nullable: true})
     issuer!: Identity
 
+    /**
+     * certification target
+     */
     @Index_()
     @ManyToOne_(() => Identity, {nullable: true})
     receiver!: Identity
@@ -61,6 +67,9 @@ export class Cert {
     @IntColumn_({nullable: false})
     expireOn!: number
 
+    /**
+     * list all events of this cert
+     */
     @OneToMany_(() => CertEvent, e => e.cert)
     certHistory!: CertEvent[]
 }
diff --git a/src/types_custom.ts b/src/types_custom.ts
index 27bfefa21e41171bdd99c654bfd0abccdc47529e..af079ac5c2e2902a0f84f2c8b35de8030c639695 100644
--- a/src/types_custom.ts
+++ b/src/types_custom.ts
@@ -259,16 +259,16 @@ interface CommentEvents {
 interface CertCreationEvent {
   issuerId: IdtyIndex;
   receiverId: IdtyIndex;
-  createdOn: BlockNumber;
   expireOn: BlockNumber;
+  blockNumber: BlockNumber;
   event: Event;
 }
 
 interface CertRenewalEvent {
   issuerId: IdtyIndex;
   receiverId: IdtyIndex;
-  blockNumber: BlockNumber;
   expireOn: BlockNumber;
+  blockNumber: BlockNumber;
   event: Event;
 }