diff --git a/src/lib/components/BudgetConnexionModal.svelte b/src/lib/components/BudgetConnexionModal.svelte
index 9db434374cad01d28d98be2e6963c372dd87a967..24c1995a7e8fccf3497c35b2d79eb797d1dcff1b 100644
--- a/src/lib/components/BudgetConnexionModal.svelte
+++ b/src/lib/components/BudgetConnexionModal.svelte
@@ -6,23 +6,14 @@
     Transition,
     TransitionChild,
   } from "@rgossiaux/svelte-headlessui"
-  import { getContext } from "svelte"
-  import type { Writable } from "svelte/types/runtime/store"
 
   import { browser } from "$app/environment"
   import { page } from "$app/stores"
-  import CopyClipboard from "$lib/components/CopyClipboard.svelte"
-  import type { ParametricReform } from "$lib/reforms"
+  import type { CachedSimulation } from "$lib/simulations"
 
   export let isOpen = false
 
-  let cachedSimulations = []
-  let clipboardElement: HTMLElement
-  let isSimulationShared = false
-  const parametricReform = getContext(
-    "parametricReform",
-  ) as Writable<ParametricReform>
-  let url = ""
+  let cachedSimulations: CachedSimulation[] = []
 
   $: if (browser) {
     fetchCachedSimulations()
@@ -40,44 +31,6 @@
     cachedSimulations = index
   }
 
-  function copyLink() {
-    const copyClipboard = new CopyClipboard({
-      target: clipboardElement,
-      props: { value: url },
-    })
-    copyClipboard.$destroy()
-  }
-
-  async function onChange({ target }: Event) {
-    if ((target as HTMLInputElement).checked) {
-      const urlString = "/simulations_budget"
-      const res = await fetch(urlString, {
-        body: JSON.stringify({
-          parametricReform: $parametricReform,
-        }),
-        headers: {
-          Accept: "application/json",
-          "Content-Type": "application/json; charset=utf-8",
-        },
-        method: "POST",
-      })
-      if (!res.ok) {
-        console.error(
-          `Error ${
-            res.status
-          } while creating a share link at ${urlString}\n\n${await res.text()}`,
-        )
-        return
-      }
-      const { token } = await res.json()
-      url = new URL(
-        `/simulations_budget/${token}`,
-        $page.data.baseUrl,
-      ).toString()
-      console.log(url)
-    }
-  }
-
   function onClose() {
     isOpen = false
   }
diff --git a/src/lib/components/BudgetSimulationSharingModal.svelte b/src/lib/components/BudgetSimulationSharingModal.svelte
index aeb58977e66515a2356ea4186f76a46ee02edeae..c247fa95c16c012da27ea97f0d3b506d9f948d8c 100644
--- a/src/lib/components/BudgetSimulationSharingModal.svelte
+++ b/src/lib/components/BudgetSimulationSharingModal.svelte
@@ -14,6 +14,7 @@
   import type { DisplayMode } from "$lib/displays"
   import CopyClipboard from "$lib/components/CopyClipboard.svelte"
   import type { ParametricReform } from "$lib/reforms"
+  import { budgetEditableParametersName } from "$lib/variables"
 
   export let displayMode: DisplayMode
   export let isOpen = false
@@ -22,18 +23,42 @@
     BudgetSimulation | undefined
   >
   let clipboardElement: HTMLElement
+  let hasClickedCopy = false
   let isSimulationShared = false
   const parametricReform = getContext(
     "parametricReform",
   ) as Writable<ParametricReform>
+  let shareButtons = [
+    {
+      icon: "ri-twitter-fill",
+      title: "Partager sur Twitter",
+      link: "https://twitter.com/intent/tweet?text=",
+    },
+    {
+      icon: "ri-linkedin-fill",
+      title: "Partager sur LinkedIn",
+      link: "https://www.linkedin.com/sharing/share-offsite/?url=",
+    },
+    {
+      icon: "ri-mail-fill",
+      title: "Partager par e-mail",
+      link: "mailto:?body=",
+    },
+  ]
   let url = ""
 
   function copyLink() {
+    if (hasClickedCopy) {
+      return
+    }
+
     const copyClipboard = new CopyClipboard({
       target: clipboardElement,
       props: { value: url },
     })
     copyClipboard.$destroy()
+    hasClickedCopy = true
+    setTimeout(() => (hasClickedCopy = false), 2500)
   }
 
   async function onChange({ target }: Event) {
@@ -43,7 +68,15 @@
         body: JSON.stringify({
           budgetSimulation: $budgetSimulation?.result,
           displayMode,
-          parametricReform: $parametricReform,
+          parametricReform: Object.entries($parametricReform).reduce(
+            (filtered, [parameterName, value]) => {
+              if (budgetEditableParametersName.has(parameterName)) {
+                filtered[parameterName] = value
+              }
+              return filtered
+            },
+            {},
+          ),
         }),
         headers: {
           Accept: "application/json",
@@ -69,6 +102,7 @@
 
   function onClose() {
     isOpen = false
+    isSimulationShared = false
   }
 </script>
 
@@ -163,16 +197,45 @@
                   /> La simulation est publiƩe :
                 </span>
               {/if}
-              <div class="flex justify-center">
+              <div class="flex justify-center gap-4">
                 <div bind:this={clipboardElement} />
                 <button
-                  class="flex items-center gap-2 py-2 px-7 shadow-lg bg-le-bleu disabled:bg-gray-200 disabled:text-gray-400 disabled:shadow-none hover:opacity-90 active:opacity-80 rounded text-white text-sm font-bold tracking-[0.085em] uppercase"
+                  class="relative shadow-lg bg-le-bleu disabled:bg-gray-200 disabled:text-gray-400 disabled:shadow-none hover:opacity-90 active:opacity-80 rounded text-white text-sm font-bold tracking-[0.085em] uppercase"
                   disabled={!isSimulationShared}
                   on:click={copyLink}
+                  title="Copier le lien de la simulation"
                 >
-                  Copier le lien
-                  <iconify-icon class="text-lg rotate-45" icon="ri-link" />
+                  <span
+                    class="flex justify-center items-center gap-2 py-2 px-7"
+                    class:invisible={hasClickedCopy}
+                  >
+                    Copier le lien
+                    <iconify-icon class="text-lg rotate-45" icon="ri-link" />
+                  </span>
+                  <span
+                    class="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-full h-full flex justify-center items-center gap-2"
+                    class:invisible={!hasClickedCopy}
+                  >
+                    Lien copiƩ
+                    <iconify-icon class="text-lg" icon="ri-check-line" />
+                  </span>
                 </button>
+
+                {#each shareButtons as shareButton}
+                  <a
+                    class="w-9 h-9 flex justify-center items-center shadow-lg bg-le-bleu hover:opacity-90 active:opacity-80 rounded text-white text-sm font-bold tracking-[0.085em] uppercase"
+                    class:!bg-gray-200={!isSimulationShared}
+                    class:!text-gray-400={!isSimulationShared}
+                    class:!shadow-none={!isSimulationShared}
+                    href={isSimulationShared
+                      ? `${shareButton.link}${url}`
+                      : undefined}
+                    target="_blank"
+                    title={shareButton.title}
+                  >
+                    <iconify-icon class="text-lg" icon={shareButton.icon} />
+                  </a>
+                {/each}
               </div>
             </div>
           </DialogDescription>
diff --git a/src/lib/components/IntroWarningBillModale.svelte b/src/lib/components/IntroWarningBillModale.svelte
index 6fe4eea5dd7692930fc18e65e557c211ce026962..13b1183542731d9ffa70397bbe9aa758e928c48f 100644
--- a/src/lib/components/IntroWarningBillModale.svelte
+++ b/src/lib/components/IntroWarningBillModale.svelte
@@ -6,61 +6,11 @@
     Transition,
     TransitionChild,
   } from "@rgossiaux/svelte-headlessui"
-  import { getContext } from "svelte"
-  import type { Writable } from "svelte/types/runtime/store"
 
-  import { page } from "$app/stores"
-  import CopyClipboard from "$lib/components/CopyClipboard.svelte"
-  import type { ParametricReform } from "$lib/reforms"
   import { browser } from "$app/environment"
 
   export let isOpen = false
 
-  let clipboardElement: HTMLElement
-
-  const parametricReform = getContext(
-    "parametricReform",
-  ) as Writable<ParametricReform>
-  let url = ""
-
-  function copyLink() {
-    const copyClipboard = new CopyClipboard({
-      target: clipboardElement,
-      props: { value: url },
-    })
-    copyClipboard.$destroy()
-  }
-
-  async function onChange({ target }: Event) {
-    if ((target as HTMLInputElement).checked) {
-      const urlString = "/simulations_budget"
-      const res = await fetch(urlString, {
-        body: JSON.stringify({
-          parametricReform: $parametricReform,
-        }),
-        headers: {
-          Accept: "application/json",
-          "Content-Type": "application/json; charset=utf-8",
-        },
-        method: "POST",
-      })
-      if (!res.ok) {
-        console.error(
-          `Error ${
-            res.status
-          } while creating a share link at ${urlString}\n\n${await res.text()}`,
-        )
-        return
-      }
-      const { token } = await res.json()
-      url = new URL(
-        `/simulations_budget/${token}`,
-        $page.data.baseUrl,
-      ).toString()
-      console.log(url)
-    }
-  }
-
   function onClose() {
     isOpen = false
   }
diff --git a/src/lib/components/ReformsChanges.svelte b/src/lib/components/ReformsChanges.svelte
index 81ea83b969065f6ead6aadf518bb88c63ca9d4aa..5188ce25bb4288d8f2de41250b32b7f5e5fedf04 100644
--- a/src/lib/components/ReformsChanges.svelte
+++ b/src/lib/components/ReformsChanges.svelte
@@ -69,7 +69,8 @@
     <ul class="bg-gray-200 text-xs leading-relaxed text-gray-600">
       <li class="my-1">
         <Tooltip
-          arrowClass="bg-le-rouge-bill border-transparent"
+          arrowClass="bg-white border-le-rouge-bill"
+          arrowBorderWidth="2px"
           widthClass="w-60"
           initialPlacement="right"
         >
@@ -95,7 +96,8 @@
       </li>
       <li class="my-1">
         <Tooltip
-          arrowClass="bg-le-rouge-bill border-transparent"
+          arrowClass="bg-white border-le-rouge-bill"
+          arrowBorderWidth="2px"
           widthClass="w-60"
           initialPlacement="right"
         >
@@ -121,7 +123,8 @@
       </li>
       <li class="my-1">
         <Tooltip
-          arrowClass="bg-le-rouge-bill border-transparent"
+          arrowClass="bg-white border-le-rouge-bill"
+          arrowBorderWidth="2px"
           widthClass="w-60"
           initialPlacement="right"
         >
@@ -147,7 +150,8 @@
       </li>
       <li class="my-1">
         <Tooltip
-          arrowClass="bg-le-rouge-bill border-transparent"
+          arrowClass="bg-white border-le-rouge-bill"
+          arrowBorderWidth="2px"
           widthClass="w-60"
           initialPlacement="right"
         >
@@ -231,6 +235,7 @@
           >
             <Tooltip
               arrowClass="bg-white border-le-jaune-light"
+              arrowBorderWidth="2px"
               widthClass="w-60"
               initialPlacement="right"
             >
@@ -283,6 +288,7 @@
           <li class="my-1 py-2 text-xs leading-relaxed text-gray-600">
             <Tooltip
               arrowClass="bg-white border-le-jaune-light"
+              arrowBorderWidth="2px"
               widthClass="w-60"
               initialPlacement="right"
             >
diff --git a/src/lib/components/Tooltip.svelte b/src/lib/components/Tooltip.svelte
index 1469d19251071ae12f9cd67de9d52912f7f5f0ea..7408d167a882ba30302453a8cd9030b3064c7f41 100644
--- a/src/lib/components/Tooltip.svelte
+++ b/src/lib/components/Tooltip.svelte
@@ -9,6 +9,7 @@
 
   export let allowFlip = true
   export let arrowClass = ""
+  export let arrowBorderWidth = "1px"
   export let initialPlacement: Placement = "bottom"
   export let role = "presentation"
   export let tag = "div"
@@ -121,9 +122,29 @@
       : arrowCoords?.x
       ? `${arrowCoords?.x}px`
       : undefined}
+    style="--arrow-border-width: {arrowBorderWidth};"
     class:after:border-t={placement === "bottom" || placement === "left"}
+    class:border-t-width={placement === "bottom" || placement === "left"}
     class:after:border-r={placement === "top" || placement === "left"}
+    class:border-r-width={placement === "top" || placement === "left"}
     class:after:border-b={placement === "top" || placement === "right"}
+    class:border-b-width={placement === "top" || placement === "right"}
     class:after:border-l={placement === "bottom" || placement === "right"}
+    class:border-l-width={placement === "bottom" || placement === "right"}
   ></div>
 </div>
+
+<style>
+  .border-t-width::after {
+    border-top-width: var(--arrow-border-width);
+  }
+  .border-r-width::after {
+    border-right-width: var(--arrow-border-width);
+  }
+  .border-b-width::after {
+    border-bottom-width: var(--arrow-border-width);
+  }
+  .border-l-width::after {
+    border-left-width: var(--arrow-border-width);
+  }
+</style>
diff --git a/src/lib/components/variables/InflationLawButton.svelte b/src/lib/components/variables/InflationLawButton.svelte
index df0f4aff2709ed2bd7c4902532715cd46d72e13d..12ede2662d5bb472254b289c0cbbbb6afdff19f1 100644
--- a/src/lib/components/variables/InflationLawButton.svelte
+++ b/src/lib/components/variables/InflationLawButton.svelte
@@ -12,43 +12,6 @@
       : Object.entries(revaluationDetails.values).sort(
           ([instant1], [instant2]) => instant2.localeCompare(instant1),
         )[0][1]
-
-  const inflatedParametersDelete = [
-    "impot_revenu.bareme_ir_depuis_1945.bareme",
-    "impot_revenu.calcul_impot_revenu.plaf_qf.decote.seuil_couple",
-    "impot_revenu.calcul_impot_revenu.plaf_qf.decote.seuil_celib",
-    "impot_revenu.calcul_impot_revenu.plaf_qf.plafond_avantages_procures_par_demi_part",
-    "impot_revenu.calcul_revenus_imposables.abat_rni.enfant_marie.montant",
-    "impot_revenu.calcul_reductions_impots.dons.dons_coluche.plafond",
-    "impot_revenu.calcul_revenus_imposables.abat_rni.personne_agee_ou_invalide",
-    "impot_revenu.calcul_revenus_imposables.rpns.micro.microentreprise.regime_micro_bnc.marchandises.plafond",
-    "impot_revenu.calcul_revenus_imposables.deductions.abatpen",
-    "impot_revenu.calcul_revenus_imposables.deductions.abatpro",
-    "impot_revenu.calcul_revenus_imposables.rpns.micro.microentreprise.regime_micro_ba.plafond_recettes",
-    "impot_revenu.calcul_revenus_imposables.rpns.micro.microentreprise.regime_micro_bnc.services.plafond",
-    "impot_revenu.calcul_revenus_imposables.charges_deductibles.pensions_alimentaires.plafond",
-    "prelevements_sociaux.contributions_sociales.csg.remplacement.seuils",
-    "prestations_sociales.aides_logement.allocations_logement.al_loc2.par_zone",
-    "prestations_sociales.aides_logement.allocations_logement.al_charge",
-    "prestations_sociales.aides_logement.allocations_logement.al_etudiant",
-    "prestations_sociales.aides_logement.allocations_logement.al_plaf_logement_foyer",
-    "prestations_sociales.aides_logement.allocations_logement.al_loc2.montant_forfaitaire_participation_minimale_po",
-    "prestations_sociales.aides_logement.allocations_logement.al_param_r0.r0",
-    "prestations_sociales.aides_logement.ressources.dar_4",
-    "prestations_sociales.aides_logement.ressources.dar_5",
-    "prestations_sociales.aides_logement.ressources.dar_11",
-    "prestations_sociales.aides_logement.ressources.dar_12",
-    "prestations_sociales.solidarite_insertion.minima_sociaux.ppa.pa_m.montant_de_base",
-    "prestations_sociales.solidarite_insertion.minima_sociaux.rsa.rsa_m.montant_de_base_du_rsa",
-    "prestations_sociales.solidarite_insertion.minimum_vieillesse.aspa.plafond_ressources",
-    "prestations_sociales.solidarite_insertion.minimum_vieillesse.aspa.montant_maximum_annuel",
-    "prestations_sociales.prestations_etat_de_sante.invalidite.asi.plafond_ressource_couple",
-    "prestations_sociales.prestations_etat_de_sante.invalidite.asi.plafond_ressource_seul",
-    "prestations_sociales.aides_jeunes.contrat_engagement_jeune.montants",
-    "prestations_sociales.prestations_etat_de_sante.invalidite.aah.montant",
-    "prestations_sociales.prestations_familiales.bmaf.bmaf",
-    "prelevements_sociaux.pss",
-  ]
 </script>
 
 <button
diff --git a/src/lib/components/variables/InflationLawDetails.svelte b/src/lib/components/variables/InflationLawDetails.svelte
index 99c5e8e03ea2a2e84abe1c9400bf4806d2125471..e30e6e334cccf91a8cb757fd1ec40c3f64f0d6c7 100644
--- a/src/lib/components/variables/InflationLawDetails.svelte
+++ b/src/lib/components/variables/InflationLawDetails.svelte
@@ -13,43 +13,6 @@
   export let revaluationDetails: ValueParameter
   export let revaluationParameter: ScaleParameter | ValueParameter
 
-  const inflatedParametersDelete = [
-    "impot_revenu.bareme_ir_depuis_1945.bareme",
-    "impot_revenu.calcul_impot_revenu.plaf_qf.decote.seuil_couple",
-    "impot_revenu.calcul_impot_revenu.plaf_qf.decote.seuil_celib",
-    "impot_revenu.calcul_impot_revenu.plaf_qf.plafond_avantages_procures_par_demi_part",
-    "impot_revenu.calcul_revenus_imposables.abat_rni.enfant_marie.montant",
-    "impot_revenu.calcul_reductions_impots.dons.dons_coluche.plafond",
-    "impot_revenu.calcul_revenus_imposables.abat_rni.personne_agee_ou_invalide",
-    "impot_revenu.calcul_revenus_imposables.rpns.micro.microentreprise.regime_micro_bnc.marchandises.plafond",
-    "impot_revenu.calcul_revenus_imposables.deductions.abatpen",
-    "impot_revenu.calcul_revenus_imposables.deductions.abatpro",
-    "impot_revenu.calcul_revenus_imposables.rpns.micro.microentreprise.regime_micro_ba.plafond_recettes",
-    "impot_revenu.calcul_revenus_imposables.rpns.micro.microentreprise.regime_micro_bnc.services.plafond",
-    "impot_revenu.calcul_revenus_imposables.charges_deductibles.pensions_alimentaires.plafond",
-    "prelevements_sociaux.contributions_sociales.csg.remplacement.seuils",
-    "prestations_sociales.aides_logement.allocations_logement.al_loc2.par_zone",
-    "prestations_sociales.aides_logement.allocations_logement.al_charge",
-    "prestations_sociales.aides_logement.allocations_logement.al_etudiant",
-    "prestations_sociales.aides_logement.allocations_logement.al_plaf_logement_foyer",
-    "prestations_sociales.aides_logement.allocations_logement.al_loc2.montant_forfaitaire_participation_minimale_po",
-    "prestations_sociales.aides_logement.allocations_logement.al_param_r0.r0",
-    "prestations_sociales.aides_logement.ressources.dar_4",
-    "prestations_sociales.aides_logement.ressources.dar_5",
-    "prestations_sociales.aides_logement.ressources.dar_11",
-    "prestations_sociales.aides_logement.ressources.dar_12",
-    "prestations_sociales.solidarite_insertion.minima_sociaux.ppa.pa_m.montant_de_base",
-    "prestations_sociales.solidarite_insertion.minima_sociaux.rsa.rsa_m.montant_de_base_du_rsa",
-    "prestations_sociales.solidarite_insertion.minimum_vieillesse.aspa.plafond_ressources",
-    "prestations_sociales.solidarite_insertion.minimum_vieillesse.aspa.montant_maximum_annuel",
-    "prestations_sociales.prestations_etat_de_sante.invalidite.asi.plafond_ressource_couple",
-    "prestations_sociales.prestations_etat_de_sante.invalidite.asi.plafond_ressource_seul",
-    "prestations_sociales.aides_jeunes.contrat_engagement_jeune.montants",
-    "prestations_sociales.prestations_etat_de_sante.invalidite.aah.montant",
-    "prestations_sociales.prestations_familiales.bmaf.bmaf",
-    "prelevements_sociaux.pss",
-  ]
-
   const numberFormatter = (value: number): string =>
     new Intl.NumberFormat("fr-FR", {
       style: "decimal",
diff --git a/src/lib/components/variables/VariableReferredParameterHeader.svelte b/src/lib/components/variables/VariableReferredParameterHeader.svelte
index 43fddf5e885057f39677f53e8a8938eb57ca4ce7..792ee5c9d8da934307470d3ef41d5e5c693f5b64 100644
--- a/src/lib/components/variables/VariableReferredParameterHeader.svelte
+++ b/src/lib/components/variables/VariableReferredParameterHeader.svelte
@@ -1,26 +1,33 @@
 <script lang="ts">
   import type { Parameter } from "@openfisca/json-model"
   import { iterParameterAncestors, ParameterClass } from "@openfisca/json-model"
+  import smoothScrollIntoView from "scroll-into-view-if-needed"
   import { afterUpdate, getContext } from "svelte"
 
-  import type { SelfTargetAProps } from "$lib/urls"
   import type { DisplayMode } from "$lib/displays"
+  import type { SelfTargetAProps } from "$lib/urls"
   import viewport from "$lib/viewport"
-  import smoothScrollIntoView from "scroll-into-view-if-needed"
 
   export let depth: number
   export let displayMode: DisplayMode
   export let parameter: Parameter
 
+  let htmlElement: HTMLElement | undefined
+  let isCopiedSuccessfully = false
+  let isElementInViewport = false
+  const onCopyParameterLink = getContext("onCopyParameterLink") as (
+    parameterName: string,
+  ) => void
   const newSelfTargetAProps = getContext("newSelfTargetAProps") as (
     url: string,
   ) => SelfTargetAProps
 
-  const onCopyParameterLink = getContext("onCopyParameterLink") as (
-    parameterName: string,
-  ) => void
+  $: isParameterSelected = urlHash === parameter.name
+
+  $: urlHash = displayMode.parameterHash?.includes("-")
+    ? displayMode.parameterHash?.split("-")[0]
+    : displayMode.parameterHash
 
-  let isCopiedSuccessfully = false
   function copyLink() {
     if (parameter.name !== undefined) {
       onCopyParameterLink(parameter.name)
@@ -29,13 +36,6 @@
     }
   }
 
-  $: urlHash = displayMode.parameterHash?.includes("-")
-    ? displayMode.parameterHash?.split("-")[0]
-    : displayMode.parameterHash
-  $: isParameterSelected = urlHash === parameter.name
-  let htmlElement
-  let isElementInViewport = false
-
   afterUpdate(() => {
     if (htmlElement !== undefined && isParameterSelected) {
       smoothScrollIntoView(htmlElement, { behavior: "smooth", block: "center" })
diff --git a/src/lib/simulations.ts b/src/lib/simulations.ts
index 6eba71d7644295578b7bcadc84610f0b130c9c77..1722aca0b02f1d182c8895eb6db74b21a37d3f71 100644
--- a/src/lib/simulations.ts
+++ b/src/lib/simulations.ts
@@ -1,3 +1,10 @@
+export interface CachedSimulation {
+  date: string
+  hash: string
+  parameters: string[]
+  title: string
+}
+
 export interface EntitySimulation {
   [key: string]: { [date: string]: number } | string[]
 }
diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte
index 96d0b04a5f20f13d4f8538dabc365155b825614f..47911a032d48a9a8b78b708d8b00bc339474f08b 100644
--- a/src/routes/+page.svelte
+++ b/src/routes/+page.svelte
@@ -1416,8 +1416,9 @@
             <button
               class="z-30 absolute -bottom-4 right-5 flex items-center gap-2 py-2 px-5 shadow-lg bg-white hover:bg-gray-100 active:bg-gray-200 rounded border border-le-bleu text-le-bleu text-sm font-bold tracking-[0.085em] uppercase transition-all duration-200 ease-out-back disabled:opacity-0 disabled:scale-90"
               on:click={() => (isBudgetSimulationModalOpen = true)}
-              disabled={Object.keys($parametricReform).length === 0 ||
-                $budgetSimulation === undefined}
+              disabled={Object.keys($parametricReform).filter((parameterName) =>
+                budgetEditableParametersName.has(parameterName),
+              ).length === 0 || $budgetSimulation === undefined}
             >
               Partager cette simulation
               <iconify-icon class="text-lg" icon="ri-send-plane-2-line" />
@@ -1700,7 +1701,9 @@
       displayMode.budget &&
       !displayMode.mobileLaw &&
       displayMode.parametersVariableName !== undefined &&
-      Object.keys($parametricReform).length > 0 &&
+      Object.keys($parametricReform).filter((parameterName) =>
+        budgetEditableParametersName.has(parameterName),
+      ).length > 0 &&
       !deepEqual($budgetSimulationCache?.parametricReform, $parametricReform)}
     <div
       class="flex flex-col items-center md:block fixed bottom-0 md:bottom-auto md:top-12 2xl:top-14 md:right-3 bg-le-jaune-light z-40 rounded-t-lg md:rounded-t-none md:rounded-b-lg shadow-md mx-5 md:mx-0 inset-x-0 md:inset-x-auto px-3 lg:px-5 pt-3 pb-6 md:pt-6 md:pb-3 lg:pt-8 transition-transform duration-[350ms] ease-out-back md:delay-0"
diff --git a/src/routes/simulations_budget/+server.ts b/src/routes/simulations_budget/+server.ts
index da919b8bd50ebc9c73ae90a723025d4f5508225d..78e675b01993ed767988d1b65f07ba28ea60b452 100644
--- a/src/routes/simulations_budget/+server.ts
+++ b/src/routes/simulations_budget/+server.ts
@@ -2,11 +2,12 @@ import { auditRequire, cleanAudit, type Audit } from "@auditors/core"
 import { error, json } from "@sveltejs/kit"
 import fs from "fs-extra"
 import path from "path"
-
 import { XXH64 } from "xxh3-ts"
 
 import { getParameter, rootParameter } from "$lib/parameters"
+import type { ParametricReform } from "$lib/reforms"
 import config from "$lib/server/config"
+import type { CachedSimulation } from "$lib/simulations"
 
 import type { RequestHandler } from "./$types"
 
@@ -70,9 +71,13 @@ export const POST: RequestHandler = async ({ request, url }) => {
     throw error(400, `Invalid body: ${JSON.stringify(bodyError, null, 2)}`)
   }
 
-  const modifiedParameters = Object.keys(body.parametricReform).map(
-    (parameterName) => getParameter(rootParameter, parameterName)?.title,
-  )
+  const modifiedParametersTitles = Object.keys(
+    (body as { parametricReform: ParametricReform }).parametricReform,
+  ).map((parameterName) => getParameter(rootParameter, parameterName)?.title)
+
+  const modifiedParametersNames = Object.keys(
+    (body as { parametricReform: ParametricReform }).parametricReform,
+  ).map((parameterName) => getParameter(rootParameter, parameterName)?.name)
 
   const bodyJson = JSON.stringify(body, null, 2)
 
@@ -91,20 +96,22 @@ export const POST: RequestHandler = async ({ request, url }) => {
   }
 
   const indexDir = path.join(simulationsBudgetDir, "index.json")
-  const indexContents = (await fs.pathExists(indexDir))
+  const indexContents: CachedSimulation[] = (await fs.pathExists(indexDir))
     ? await fs.readJson(indexDir)
     : []
-  await fs.writeFile(
-    indexDir,
-    JSON.stringify([
-      ...indexContents,
-      {
-        date: new Intl.DateTimeFormat("fr-FR").format(new Date()),
-        hash: digest,
-        title: modifiedParameters.join(" | "),
-      },
-    ]),
+  const contents: CachedSimulation[] = [
+    ...indexContents,
+    {
+      date: new Intl.DateTimeFormat("fr-FR").format(new Date()),
+      hash: digest,
+      parameters: modifiedParametersNames,
+      title: modifiedParametersTitles.join(" | "),
+    } as CachedSimulation,
+  ].filter(
+    (value, index, self) =>
+      index === self.findIndex((el) => el.hash === value.hash),
   )
+  await fs.writeFile(indexDir, JSON.stringify(contents))
 
   return json({ token: digest })
 }
diff --git a/src/routes/simulations_budget/index/+server.ts b/src/routes/simulations_budget/index/+server.ts
index 0059bb9624541eb679c4a3644adc27623aa2ffe3..b8820b7dfd379daba454d35398da1464ce447369 100644
--- a/src/routes/simulations_budget/index/+server.ts
+++ b/src/routes/simulations_budget/index/+server.ts
@@ -3,6 +3,7 @@ import fs from "fs-extra"
 import path from "path"
 
 import config from "$lib/server/config"
+import type { CachedSimulation } from "$lib/simulations"
 
 import type { RequestHandler } from "./$types"
 
@@ -12,6 +13,8 @@ export const POST: RequestHandler = async () => {
   const indexDir = path.join(simulationsBudgetDir, "index.json")
 
   return json({
-    index: (await fs.pathExists(indexDir)) ? await fs.readJson(indexDir) : [],
+    index: (await fs.pathExists(indexDir))
+      ? ((await fs.readJson(indexDir)) as CachedSimulation[])
+      : [],
   })
 }