diff --git a/src/app/block/block.page.html b/src/app/block/block.page.html
index 276435bbcdda23becc810a52d5df52a900e1590c..a162a5832890bfcc735bf037085dc8089fa17a25 100644
--- a/src/app/block/block.page.html
+++ b/src/app/block/block.page.html
@@ -15,7 +15,7 @@
   <ion-header collapse="condense">
     <ion-toolbar>
       <ion-title size="large">
-        {{ 'BLOCKCHAIN.VIEW.TITLE' | translate: { number: height$ | push | numberFormat } }}
+        {{ 'BLOCKCHAIN.VIEW.TITLE' | translate: { number: height$ | push | blockNumber } }}
       </ion-title>
     </ion-toolbar>
   </ion-header>
@@ -37,13 +37,13 @@
         @if (mobile) {
           <ion-label>
             <h2 translate>BLOCKCHAIN.VIEW.HASH</h2>
-            <p class="ion-text-wrap">{{ block.height }}-{{ block.hash }}</p>
+            <p class="ion-text-wrap">{{ block.height | blockNumber: { allowSuffix: false, useGrouping: false } }}-{{ block.hash }}</p>
           </ion-label>
         } @else {
           <ion-label>
             <h2 translate>BLOCKCHAIN.VIEW.HASH</h2>
+            <p class="ion-text-wrap">{{ block.height | blockNumber: { allowSuffix: false, useGrouping: false } }}-{{ block.hash }}</p>
           </ion-label>
-          <ion-note slot="end" class="ion-text-wrap">{{ block.height }}-{{ block.hash }}</ion-note>
         }
       </ion-item>
     </ion-list>
diff --git a/src/app/certification/history/cert-history.page.html b/src/app/certification/history/cert-history.page.html
index 1130238d4be2f92062ce5ce0a9562e1cbb15908a..1d6c0f413f868b2b2ea7133bae5b426cd2ece451 100644
--- a/src/app/certification/history/cert-history.page.html
+++ b/src/app/certification/history/cert-history.page.html
@@ -62,7 +62,10 @@
           <ion-icon name="key"></ion-icon>
           {{ item.account.address | addressToPubkeyV1 | pubkeyFormat: true }} |
           <a [routerLink]="['/block', item.createdOn]" routerDirection="forward" (click)="$event.preventDefault()" class="tx-timestamp">
-            {{ item.updatedOn | blockTime | dateFormat }} | {{ 'COMMON.BLOCK' | translate }} #{{ item.updatedOn | blockNumber }}
+            @if (item.updatedOn | blockTime | dateFormat; as blockTime) {
+              {{ blockTime }} |
+            }
+            {{ 'COMMON.BLOCK' | translate }} #{{ item.updatedOn | blockNumber }}
           </a>
         </p>
       </ion-label>
diff --git a/src/app/currency/currency.page.html b/src/app/currency/currency.page.html
index 458158a3db41bb823cf1d9c1b430dc244796986f..94f24c4650eece85ad54270889cfc32551bdb165 100644
--- a/src/app/currency/currency.page.html
+++ b/src/app/currency/currency.page.html
@@ -18,7 +18,7 @@
     <ion-grid class="ion-no-padding">
       <ion-row>
         <ion-col size="0" size-md="2" size-lg="3"></ion-col>
-        <ion-col>
+        <ion-col size="12" size-md="8" size-lg="6">
           <ion-list *rxIf="loaded$; else listSkeleton" lines="none">
             <ion-item-divider translate>CURRENCY.VIEW.TITLE</ion-item-divider>
 
@@ -60,7 +60,7 @@
               <ion-icon slot="start" name="reload"></ion-icon>
               <ion-label color="dark" translate>CURRENCY.VIEW.UD</ion-label>
               <ion-badge color="tertiary">
-                {{ params.unitsPerUd }}
+                {{ params.currentUd }}
                 <span [innerHtml]="params.currencySymbol"></span>
                 /
                 {{ params.udCreationPeriodMs | duration: 'ms' }}
diff --git a/src/app/currency/currency.page.ts b/src/app/currency/currency.page.ts
index 74434ad3374b71ad6e4c72ac58d8bd1b573db25a..31743500a95f0b22ba5260d5f7f9801d83b43dac 100644
--- a/src/app/currency/currency.page.ts
+++ b/src/app/currency/currency.page.ts
@@ -3,13 +3,12 @@ import { DomSanitizer, SafeHtml } from '@angular/platform-browser';
 import { NetworkService } from '@app/network/network.service';
 import { AppPage, AppPageState } from '@app/shared/pages/base-page.class';
 import { TranslateService } from '@ngx-translate/core';
-import { u32, u64 } from '@polkadot/types';
 import { RxState } from '@rx-angular/state';
 import { RxStateProperty } from '@app/shared/decorator/state.decorator';
 import { SettingsService } from '@app/settings/settings.service';
 import { CurrencyDisplayUnit } from '@app/settings/settings.model';
 import { map } from 'rxjs/operators';
-import { toBoolean } from '@app/shared/functions';
+import { toBoolean, toNumber } from '@app/shared/functions';
 
 export interface CurrencyParameters {
   currencyName: string;
@@ -17,7 +16,8 @@ export interface CurrencyParameters {
   currencySymbol: SafeHtml;
   members: number;
   monetaryMass: number;
-  unitsPerUd: number;
+  currentUd: number;
+  ud0: number;
   udCreationPeriodMs: number;
   udReevalPeriodMs: number;
   growthRate: number;
@@ -69,34 +69,38 @@ export class CurrencyPage extends AppPage<CurrencyPageState> {
     const network = await this.networkService.ready();
     const api = network.api;
     const currency = network.currency;
-    const fractionsPerUnit = Math.pow(10, currency.decimals);
-    const [monetaryMassFractions, members] = await Promise.all([
+    const powBase = Math.pow(10, currency.decimals);
+    const [monetaryMassFractions, currentUd, members] = await Promise.all([
       api.query.universalDividend.monetaryMass(),
+      api.query.universalDividend.currentUd(),
       api.query.membership.counterForMembership(),
     ]);
-    const duValue = (api.consts.universalDividend.unitsPerUd as u64).toNumber() / fractionsPerUnit;
-    const growthRate = Math.sqrt((api.consts.universalDividend.squareMoneyGrowthRate as u64).toNumber());
+    const ud0 = toNumber(api.consts.universalDividend.unitsPerUd) / powBase;
+    const ud = toNumber(currentUd) / powBase;
+    const growthRate = Math.sqrt(toNumber(api.consts.universalDividend.squareMoneyGrowthRate));
     const paramsByUnit = new Map<CurrencyDisplayUnit, CurrencyParameters>();
     paramsByUnit.set('base', {
       currencyName: currency.displayName,
       currencySymbol: currency.symbol,
       currencyNetwork: currency.network,
-      monetaryMass: (monetaryMassFractions as u64).toNumber() / fractionsPerUnit,
-      members: (members as u32).toNumber(),
-      unitsPerUd: duValue,
-      udCreationPeriodMs: (api.consts.universalDividend.udCreationPeriod as u64).toNumber(),
-      udReevalPeriodMs: (api.consts.universalDividend.udReevalPeriod as u64).toNumber(),
+      monetaryMass: toNumber(monetaryMassFractions) / powBase,
+      members: toNumber(members),
+      currentUd: ud,
+      ud0,
+      udCreationPeriodMs: toNumber(api.consts.universalDividend.udCreationPeriod),
+      udReevalPeriodMs: toNumber(api.consts.universalDividend.udReevalPeriod),
       growthRate,
     });
     paramsByUnit.set('du', {
       currencyName: currency.displayName,
       currencySymbol: this.sanitizer.bypassSecurityTrustHtml(`${this.translate.instant('COMMON.UD')}<sub>${currency.symbol}</sub>`),
       currencyNetwork: currency.network,
-      monetaryMass: (monetaryMassFractions as u64).toNumber() / fractionsPerUnit / duValue,
-      members: (members as u32).toNumber(),
-      unitsPerUd: 1,
-      udCreationPeriodMs: (api.consts.universalDividend.udCreationPeriod as u64).toNumber(),
-      udReevalPeriodMs: (api.consts.universalDividend.udReevalPeriod as u64).toNumber(),
+      monetaryMass: toNumber(monetaryMassFractions) / powBase / ud,
+      members: toNumber(members),
+      currentUd: 1,
+      ud0,
+      udCreationPeriodMs: toNumber(api.consts.universalDividend.udCreationPeriod),
+      udReevalPeriodMs: toNumber(api.consts.universalDividend.udReevalPeriod),
       growthRate,
     });
 
diff --git a/src/app/network/network.service.ts b/src/app/network/network.service.ts
index 57be88c1e7db80a203f2f54d2d4dcdaa6bce924d..1b026570f9fe2b6869a6c117e8de859094795f29 100644
--- a/src/app/network/network.service.ts
+++ b/src/app/network/network.service.ts
@@ -6,9 +6,9 @@ import { abbreviate, WELL_KNOWN_CURRENCIES } from '@app/shared/currencies';
 import { Currency } from '../currency/currency.model';
 import { RxStartableService } from '@app/shared/services/rx-startable-service.class';
 import { RxStateProperty, RxStateSelect } from '@app/shared/decorator/state.decorator';
-import { Observable } from 'rxjs';
+import { mergeMap, Observable, tap } from 'rxjs';
 import { filter, map } from 'rxjs/operators';
-import { arrayRandomPick, isNotNilOrBlank } from '@app/shared/functions';
+import { arrayRandomPick, isNotNilOrBlank, toNumber } from '@app/shared/functions';
 import { IndexerService } from './indexer.service';
 import { fromDateISOString } from '@app/shared/dates';
 import { ContextService } from '@app/shared/services/storage/context.service';
@@ -17,6 +17,7 @@ export interface NetworkState {
   peer: Peer;
   currency: Currency;
   currencySymbol: string;
+  currentUd?: number;
   api: ApiPromise;
 }
 
@@ -27,10 +28,12 @@ export class NetworkService extends RxStartableService<NetworkState> {
   @RxStateProperty() peer: Peer;
   @RxStateProperty() currency: Currency;
   @RxStateProperty() currencySymbol: string;
+  @RxStateProperty() currentUd: number;
   @RxStateProperty() api: ApiPromise;
 
   @RxStateSelect() peer$: Observable<Peer>;
   @RxStateSelect() currency$: Observable<Currency>;
+  @RxStateSelect() currentUd$: Observable<number>;
 
   constructor(
     private settings: SettingsService,
@@ -53,6 +56,17 @@ export class NetworkService extends RxStartableService<NetworkState> {
     );
 
     this.hold(this.currency$, (currency) => (this.context.currency = currency));
+
+    this.connect(
+      'currentUd',
+      this.select('currency').pipe(
+        mergeMap(async (currency) => {
+          const ud = await this.api.query.universalDividend.currentUd();
+          return toNumber(ud) / currency.powBase;
+        }),
+        tap((currentUd) => console.info(`${this._logPrefix}Current UD: ${currentUd}`))
+      )
+    );
   }
 
   protected async ngOnStart(): Promise<NetworkState> {
@@ -131,14 +145,17 @@ export class NetworkService extends RxStartableService<NetworkState> {
     const lastHeader = await api.rpc.chain.getHeader();
     console.info(`${this._logPrefix}Last block: #${lastHeader.number} - hash ${lastHeader.hash}`);
 
+    const ud0 = toNumber(api.consts.universalDividend.unitsPerUd) / currency.powBase;
+
     this.indexer.currency = currency;
     await this.indexer.start();
 
     return {
+      api,
       peer,
       currency,
       currencySymbol: currency?.symbol,
-      api,
+      currentUd: ud0,
     };
   }
 
diff --git a/src/app/settings/settings.service.ts b/src/app/settings/settings.service.ts
index 0afe7c674456df332ed53aff92394a38637fb8cc..ae9578bacdeaf9fbad1fc6c761ce1950519e6f81 100644
--- a/src/app/settings/settings.service.ts
+++ b/src/app/settings/settings.service.ts
@@ -2,29 +2,39 @@ import { Inject, Injectable, Optional } from '@angular/core';
 import { CurrencyDisplayUnit, Settings } from './settings.model';
 import { environment } from '@environments/environment';
 import { Platform } from '@ionic/angular';
-import { Observable, Subject } from 'rxjs';
+import { debounceTime, Observable, Subject } from 'rxjs';
 import { APP_STORAGE, IStorage } from '@app/shared/services/storage/storage.utils';
 import { RxStartableService } from '@app/shared/services/rx-startable-service.class';
 import { setTimeout } from '@rx-angular/cdk/zone-less/browser';
 import { arrayDistinct } from '@app/shared/functions';
 import { RxStateProperty, RxStateSelect } from '@app/shared/decorator/state.decorator';
 import { isMobile } from '@app/shared/platforms';
+import { distinctUntilChanged, map } from 'rxjs/operators';
 
 const SETTINGS_STORAGE_KEY = 'settings';
 
+export interface SettingsState extends Settings {
+  localesArgument?: Intl.LocalesArgument;
+  numberFormatOptions?: Intl.NumberFormatOptions;
+}
+
 @Injectable({ providedIn: 'root' })
-export class SettingsService extends RxStartableService<Settings> {
-  changes = new Subject<Settings>();
+export class SettingsService extends RxStartableService<SettingsState> {
+  changes = new Subject<SettingsState>();
 
   get mobile() {
     return this.get('mobile');
   }
 
+  @RxStateSelect() locale$: Observable<string>;
   @RxStateSelect() darkMode$: Observable<boolean>;
   @RxStateSelect() peer$: Observable<string>;
   @RxStateSelect() indexer$: Observable<string>;
   @RxStateSelect() displayUnit$: Observable<CurrencyDisplayUnit>;
 
+  @RxStateProperty() locale: string;
+  @RxStateProperty() localesArgument: Intl.LocalesArgument;
+  @RxStateProperty() numberFormatOptions: Intl.NumberFormatOptions;
   @RxStateProperty() darkMode: boolean;
   @RxStateProperty() peer: string;
   @RxStateProperty() indexer: string;
@@ -43,7 +53,13 @@ export class SettingsService extends RxStartableService<Settings> {
     });
 
     // Emit changes event
-    this.hold(this.$, (value) => this.changes.next(value));
+    this.hold(this.$.pipe(debounceTime(100), distinctUntilChanged()), (value) => this.changes.next(value));
+
+    // Compute number options
+    this.connect('numberFormatOptions', this.locale$.pipe(map((locale) => this.getNumberFormatOptions(locale))));
+
+    // Compute number options
+    //this.connect('localesArgument', this.locale$.pipe(map((locale) => this.getLocalesArgument(locale))));
   }
 
   protected async ngOnStart(): Promise<Settings> {
@@ -100,4 +116,15 @@ export class SettingsService extends RxStartableService<Settings> {
     const data = this.clone();
     await this.storage.set('settings', data);
   }
+
+  private getNumberFormatOptions(locale: string): Intl.NumberFormatOptions {
+    const defaultOptions: Intl.NumberFormatOptions = { useGrouping: true, maximumFractionDigits: 3 };
+    switch (locale) {
+      case 'fr-FR':
+        return <Intl.NumberFormatOptions>{ ...defaultOptions };
+      case 'en-US':
+      case 'en-GB':
+        return defaultOptions;
+    }
+  }
 }
diff --git a/src/app/shared/functions.ts b/src/app/shared/functions.ts
index ae7956658e0c6ab7aaa5543b240a83d849d282e4..a61324f76a7dbc08940986ea3b4589a8abbb4eeb 100644
--- a/src/app/shared/functions.ts
+++ b/src/app/shared/functions.ts
@@ -1,5 +1,7 @@
 import { KeysEnum, KeyValueType } from '@app/shared/types';
 import { setTimeout } from '@rx-angular/cdk/zone-less/browser';
+import { u32, u64 } from '@polkadot/types-codec';
+import { Codec } from '@polkadot/types-codec/types';
 
 export function isNil<T>(obj: T | null | undefined): boolean {
   return obj === undefined || obj === null;
@@ -77,7 +79,9 @@ export function trimEmptyToNull(str: string | null | undefined): string | null {
 export function toBoolean(obj: boolean | null | undefined | string, defaultValue?: boolean): boolean {
   return obj !== undefined && obj !== null ? (obj !== 'false' ? !!obj : false) : defaultValue;
 }
-export function toNumber(obj: number | null | undefined, defaultValue?: number): number {
+export function toNumber(obj: number | u32 | u64 | Codec | null | undefined, defaultValue?: number): number {
+  if (obj instanceof u32) return obj.toNumber();
+  if (obj instanceof u64) return obj.toNumber();
   return obj !== undefined && obj !== null ? +obj : defaultValue;
 }
 export function toFloat(obj: string | null | undefined, defaultValue?: number): number | null {
diff --git a/src/app/shared/pipes/amount.pipe.ts b/src/app/shared/pipes/amount.pipe.ts
index d91c857f23c156f4f5d0410e9e464e039457f771..a32905ee4703736c0ed4595c0ecc332bc1b90de6 100644
--- a/src/app/shared/pipes/amount.pipe.ts
+++ b/src/app/shared/pipes/amount.pipe.ts
@@ -1,10 +1,9 @@
 import { Pipe, PipeTransform } from '@angular/core';
 import { NumberFormatPipe } from '@app/shared/pipes/number-format.pipe';
 import { NetworkService } from '@app/network/network.service';
-import { isNil } from '@app/shared/functions';
+import { isNilOrNaN } from '@app/shared/functions';
 import { DomSanitizer, SafeHtml } from '@angular/platform-browser';
 import { SettingsService } from '@app/settings/settings.service';
-import { u64 } from '@polkadot/types';
 import { TranslateService } from '@ngx-translate/core';
 
 @Pipe({
@@ -14,7 +13,7 @@ export class AmountFormatPipe extends NumberFormatPipe implements PipeTransform
   private currencySymbol = this.networkService.currency?.symbol;
   private powBase = this.networkService.currency?.powBase;
   private decimals = this.networkService.currency?.decimals;
-  private udValue: number;
+  private currentUd: number = this.networkService.currentUd;
   constructor(
     private networkService: NetworkService,
     private settings: SettingsService,
@@ -22,26 +21,25 @@ export class AmountFormatPipe extends NumberFormatPipe implements PipeTransform
     private sanitizer: DomSanitizer
   ) {
     super();
-    this.udValue = (networkService.api.consts.universalDividend.unitsPerUd as u64).toNumber();
   }
 
-  transform(val: number, opts?: Intl.NumberFormatOptions & { fixedDecimals?: number; html?: boolean }): SafeHtml {
-    if (isNil(val)) return '';
+  transform(amount: number, opts?: Intl.NumberFormatOptions & { fixedDecimals?: number; html?: boolean }): SafeHtml {
+    if (isNilOrNaN(amount)) return '';
     switch (this.settings.displayUnit) {
       case 'du': {
         if (opts?.html === false) {
           return (
-            super.transform(val / this.udValue / this.powBase, { fixedDecimals: this.decimals, ...opts }) +
+            super.transform((amount / this.powBase) | this.currentUd, { fixedDecimals: this.decimals + 1, ...opts }) +
             ` ${this.translate.instant('COMMON.UD')}(${this.currencySymbol})`
           );
         }
         return this.sanitizer.bypassSecurityTrustHtml(
-          super.transform(val / this.udValue / this.powBase, { fixedDecimals: this.decimals, ...opts }) +
+          super.transform(amount / this.powBase / this.currentUd, { fixedDecimals: this.decimals + 1, ...opts }) +
             ` ${this.translate.instant('COMMON.UD')}<sub>${this.currencySymbol}</sub>`
         );
       }
       default:
-        return super.transform(val / this.powBase, { fixedDecimals: this.decimals, ...opts }) + (' ' + this.currencySymbol);
+        return super.transform(amount / this.powBase, { fixedDecimals: this.decimals, ...opts }) + (' ' + this.currencySymbol);
     }
   }
 }
diff --git a/src/app/shared/pipes/block-number.pipe.ts b/src/app/shared/pipes/block-number.pipe.ts
index e2a910482bf7432c73e48ecbe857c45d8b96b7ad..6d6cd1f40fa10e6f6ebf1649528dab965513c696 100644
--- a/src/app/shared/pipes/block-number.pipe.ts
+++ b/src/app/shared/pipes/block-number.pipe.ts
@@ -1,24 +1,28 @@
 import { Pipe, PipeTransform } from '@angular/core';
 import { IndexerService } from '@app/network/indexer.service';
 import { isNil } from '@app/shared/functions';
+import { SettingsService } from '@app/settings/settings.service';
 
 @Pipe({
   name: 'blockNumber',
 })
 export class BlockNumberPipe implements PipeTransform {
-  constructor(private indexer: IndexerService) {}
+  constructor(
+    private indexer: IndexerService,
+    private settings: SettingsService
+  ) {}
 
-  transform(blockNumber: number, suffixV1 = true): string {
+  transform(blockNumber: number, opts?: { allowSuffix: boolean } & Intl.NumberFormatOptions): string {
     if (isNil(blockNumber)) return null;
 
     // Convert V1 block number (cf CRR https://pad.p2p.legal/Visio_2024-04-29)
     if (blockNumber < 0 && this.indexer.minBlockHeight) {
       blockNumber = -1 * this.indexer.minBlockHeight + blockNumber;
-      if (suffixV1) {
-        return `${blockNumber.toString()} (v1)`;
+      if (opts?.allowSuffix !== false) {
+        return `${blockNumber.toLocaleString(this.settings.locale, { ...this.settings.numberFormatOptions, ...opts })} (v1)`;
       }
     }
 
-    return blockNumber.toString();
+    return blockNumber.toLocaleString(this.settings.locale, { ...this.settings.numberFormatOptions, ...opts });
   }
 }
diff --git a/src/app/shared/pipes/block-timestamp.pipe.ts b/src/app/shared/pipes/block-timestamp.pipe.ts
index 0465eba94461b52072d9f94f22867a2872e40330..5b4009245e537e6709400a30302301a372d31f86 100644
--- a/src/app/shared/pipes/block-timestamp.pipe.ts
+++ b/src/app/shared/pipes/block-timestamp.pipe.ts
@@ -14,8 +14,8 @@ export class BlockTimePipe implements PipeTransform {
     private indexer: IndexerService
   ) {}
 
-  transform(blockNumber: number): Moment {
-    if (isNil(blockNumber)) return null;
+  transform(blockNumber: number, defaultValue?: Moment): Moment {
+    if (isNil(blockNumber)) return defaultValue;
 
     const startTime = DateUtils.fromDateISOString(this.networkService.currency.startTime);
 
@@ -30,6 +30,8 @@ export class BlockTimePipe implements PipeTransform {
 
       return null;
     } else {
+      // TODO: estimate only for future date
+
       // TODO: get from network service
       const blockDuration = 6;
       const duration = DateUtils.toDuration(blockNumber * blockDuration, 'seconds');