diff --git a/Cargo.lock b/Cargo.lock
index a38e386296b9761631a3b2817111b0e1afa37f0b..e4cbdab308701d3599a2dfc6aac9ec857905a5a1 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -653,6 +653,12 @@ dependencies = [
  "jobserver",
 ]
 
+[[package]]
+name = "cc-traits"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "becb23f44ae9dd141d637d520b908c291bf4c5eed016ca368daa1430d54ebf4c"
+
 [[package]]
 name = "cfg-expr"
 version = "0.10.3"
@@ -1558,7 +1564,9 @@ dependencies = [
 name = "distance-oracle"
 version = "0.1.0"
 dependencies = [
+ "cc-traits",
  "clap 4.1.4",
+ "median-accumulator",
  "parity-scale-codec",
  "rayon",
  "sp-core",
@@ -4367,6 +4375,15 @@ dependencies = [
  "rawpointer",
 ]
 
+[[package]]
+name = "median-accumulator"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9777055bcc453173875aab61f856474ec399120e8828fd02093841fc602eb73a"
+dependencies = [
+ "cc-traits",
+]
+
 [[package]]
 name = "memchr"
 version = "2.5.0"
@@ -5203,8 +5220,10 @@ dependencies = [
 name = "pallet-distance"
 version = "1.0.0"
 dependencies = [
+ "cc-traits",
  "frame-support",
  "frame-system",
+ "median-accumulator",
  "pallet-authority-members",
  "pallet-authorship",
  "pallet-certification",
@@ -9798,7 +9817,7 @@ version = "1.6.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "97fee6b57c6a41524a810daee9286c02d7752c4253064d0b05472833a438f675"
 dependencies = [
- "cfg-if 0.1.10",
+ "cfg-if 1.0.0",
  "digest 0.10.6",
  "rand 0.8.5",
  "static_assertions",
diff --git a/distance-oracle/Cargo.toml b/distance-oracle/Cargo.toml
index 8869a5fc6b1901d53eb0bd49904822139890f497..8c80fb6f6b34dab1d4ed36a9d61eb00cc1f16d56 100644
--- a/distance-oracle/Cargo.toml
+++ b/distance-oracle/Cargo.toml
@@ -9,7 +9,9 @@ edition = "2021"
 [dependencies]
 sp-distance = { path = "../primitives/distance" }
 
+cc-traits = "1.0.0"
 codec = { package = "parity-scale-codec", version = "3.1.5" }
+median-accumulator = { version = "0.2.0", features = ["nostd"] }
 rayon = "1.7.0"
 sp-core = { git = "https://github.com/duniter/substrate.git", branch = "duniter-substrate-v0.9.32" }
 sp-runtime = { git = "https://github.com/duniter/substrate.git", branch = "duniter-substrate-v0.9.32" }
diff --git a/distance-oracle/src/api.rs b/distance-oracle/src/api.rs
new file mode 100644
index 0000000000000000000000000000000000000000..6a177aeebad18bbc64ffd0f917e1b9a919aefed3
--- /dev/null
+++ b/distance-oracle/src/api.rs
@@ -0,0 +1,98 @@
+use crate::{AccountId, EvaluationPool, IdtyIndex};
+
+use codec::Encode;
+use sp_core::H256;
+use subxt::ext::sp_runtime::Perbill;
+use subxt::storage::StorageKey;
+
+#[subxt::subxt(runtime_metadata_path = "../resources/metadata.scale")]
+pub mod gdev {}
+
+pub type Client = subxt::OnlineClient<GdevConfig>;
+
+pub enum GdevConfig {}
+impl subxt::config::Config for GdevConfig {
+    type Index = u32;
+    type BlockNumber = u32;
+    type Hash = sp_core::H256;
+    type Hashing = subxt::ext::sp_runtime::traits::BlakeTwo256;
+    type AccountId = AccountId;
+    type Address = subxt::ext::sp_runtime::MultiAddress<Self::AccountId, u32>;
+    type Header = subxt::ext::sp_runtime::generic::Header<
+        Self::BlockNumber,
+        subxt::ext::sp_runtime::traits::BlakeTwo256,
+    >;
+    type Signature = subxt::ext::sp_runtime::MultiSignature;
+    type ExtrinsicParams = subxt::tx::BaseExtrinsicParams<Self, Tip>;
+}
+
+#[derive(Copy, Clone, Debug, Default, Encode)]
+pub struct Tip {
+    #[codec(compact)]
+    tip: u64,
+}
+
+impl Tip {
+    pub fn new(amount: u64) -> Self {
+        Tip { tip: amount }
+    }
+}
+
+impl From<u64> for Tip {
+    fn from(n: u64) -> Self {
+        Self::new(n)
+    }
+}
+
+pub async fn parent_hash(client: &Client) -> H256 {
+    client
+        .storage()
+        .fetch(&gdev::storage().system().parent_hash(), None)
+        .await
+        .unwrap()
+        .unwrap()
+}
+
+pub async fn current_session(client: &Client, parent_hash: H256) -> u32 {
+    client
+        .storage()
+        .fetch(
+            &gdev::storage().session().current_index(),
+            Some(parent_hash),
+        )
+        .await
+        .unwrap()
+        .unwrap_or_default()
+}
+
+pub async fn current_pool<MaxEvaluationsPerSession, MaxEvaluatorsPerSession>(
+    client: &Client,
+    parent_hash: H256,
+    current_session: u32,
+) -> Option<EvaluationPool<AccountId, IdtyIndex, MaxEvaluationsPerSession, MaxEvaluatorsPerSession>>
+{
+    client
+        .storage()
+        .fetch(
+            &match current_session % 3 {
+                0 => gdev::storage().distance().evaluation_pool1(),
+                1 => gdev::storage().distance().evaluation_pool2(),
+                2 => gdev::storage().distance().evaluation_pool0(),
+                _ => unreachable!("n%3<3"),
+            },
+            Some(parent_hash),
+        )
+        .await
+}
+
+pub async fn evaluation_block(client: &Client, parent_hash: H256) -> H256 {
+    client
+        .storage()
+        .fetch(
+            &gdev::storage().distance().evaluation_block(),
+            Some(parent_hash),
+        )
+        .await
+        .unwrap()
+        .unwrap()
+}
diff --git a/distance-oracle/src/impls.rs b/distance-oracle/src/impls.rs
new file mode 100644
index 0000000000000000000000000000000000000000..7ceed4f23388a8b780928b4f1c8ec36350b28413
--- /dev/null
+++ b/distance-oracle/src/impls.rs
@@ -0,0 +1,7 @@
+impl<T, S> cc_traits::GetMut<T> for sp_core::bounded::BoundedVec<T, S> {}
+
+impl<T, S> cc_traits::Len for sp_core::bounded::BoundedVec<T, S> {
+    fn len(&self) -> usize {
+        self.len()
+    }
+}
diff --git a/distance-oracle/src/lib.rs b/distance-oracle/src/lib.rs
index 62fc97b5d772ef81d36ce479684702360ec02e22..83d94f5f23039bca6fab7a7faa5c3f4b105ca725 100644
--- a/distance-oracle/src/lib.rs
+++ b/distance-oracle/src/lib.rs
@@ -1,5 +1,18 @@
+#[cfg(not(test))]
+mod api;
+mod impls;
+#[cfg(test)]
+mod mock;
+#[cfg(test)]
+mod tests;
+
+#[cfg(not(test))]
+use api::{gdev, Client};
+
 use codec::Encode;
+use median_accumulator::*;
 use rayon::iter::{IntoParallelIterator, ParallelIterator};
+use sp_core::bounded::{BoundedBTreeSet, BoundedVec};
 use std::collections::{HashMap, HashSet};
 use std::io::Write;
 use std::path::PathBuf;
@@ -22,80 +35,29 @@ impl Default for Settings {
     }
 }
 
-#[subxt::subxt(runtime_metadata_path = "../resources/metadata.scale")]
-pub mod gdev {}
-
-pub type Client = subxt::OnlineClient<GdevConfig>;
-
-pub enum GdevConfig {}
-impl subxt::config::Config for GdevConfig {
-    type Index = u32;
-    type BlockNumber = u32;
-    type Hash = sp_core::H256;
-    type Hashing = subxt::ext::sp_runtime::traits::BlakeTwo256;
-    type AccountId = subxt::ext::sp_runtime::AccountId32;
-    type Address = subxt::ext::sp_runtime::MultiAddress<Self::AccountId, u32>;
-    type Header = subxt::ext::sp_runtime::generic::Header<
-        Self::BlockNumber,
-        subxt::ext::sp_runtime::traits::BlakeTwo256,
-    >;
-    type Signature = subxt::ext::sp_runtime::MultiSignature;
-    type ExtrinsicParams = subxt::tx::BaseExtrinsicParams<Self, Tip>;
-}
-
-#[derive(Copy, Clone, Debug, Default, Encode)]
-pub struct Tip {
-    #[codec(compact)]
-    tip: u64,
-}
-
-impl Tip {
-    pub fn new(amount: u64) -> Self {
-        Tip { tip: amount }
-    }
-}
-
-impl From<u64> for Tip {
-    fn from(n: u64) -> Self {
-        Self::new(n)
-    }
-}
-
+type AccountId = subxt::ext::sp_runtime::AccountId32;
 type IdtyIndex = u32;
 
+type EvaluationPool<AccountId, IdtyIndex, MaxEvaluationsPerSession, MaxEvaluatorsPerSession> = (
+    BoundedVec<
+        (
+            IdtyIndex,
+            MedianAcc<Perbill, BoundedVec<Perbill, MaxEvaluatorsPerSession>>,
+        ),
+        MaxEvaluationsPerSession,
+    >,
+    BoundedBTreeSet<AccountId, MaxEvaluatorsPerSession>,
+);
+
 pub async fn run(settings: Settings) {
     let client = Client::from_url(settings.rpc_url).await.unwrap();
 
-    let parent_hash = client
-        .storage()
-        .fetch(&gdev::storage().system().parent_hash(), None)
-        .await
-        .unwrap()
-        .unwrap();
+    let parent_hash = api::parent_hash(&client).await;
 
-    let current_session = client
-        .storage()
-        .fetch(
-            &gdev::storage().session().current_index(),
-            Some(parent_hash),
-        )
-        .await
-        .unwrap()
-        .unwrap_or_default();
+    let current_session = api::current_session(&client, parent_hash).await;
 
     // Fetch the pending identities
-    let Some(evaluation_pool) = client
-        .storage()
-        .fetch(
-            &match current_session % 3 {
-                0 => gdev::storage().distance().evaluation_pool1(),
-                1 => gdev::storage().distance().evaluation_pool2(),
-                2 => gdev::storage().distance().evaluation_pool0(),
-                _ => unreachable!("n%3<3"),
-            },
-            Some(parent_hash),
-        )
-        .await
+    let Some(evaluation_pool) = api::current_pool(&client, parent_hash, current_session).await
         .unwrap() else {
             println!("Pool does not exist");
             return
@@ -117,15 +79,7 @@ pub async fn run(settings: Settings) {
         return;
     }
 
-    let evaluation_block = client
-        .storage()
-        .fetch(
-            &gdev::storage().distance().evaluation_block(),
-            Some(parent_hash),
-        )
-        .await
-        .unwrap()
-        .unwrap();
+    let evaluation_block = api::evaluation_block(&client, parent_hash).await;
 
     std::fs::create_dir_all(&settings.evaluation_result_dir).unwrap();
 
diff --git a/distance-oracle/src/mock.rs b/distance-oracle/src/mock.rs
new file mode 100644
index 0000000000000000000000000000000000000000..8b137891791fe96927ad78e64b0aad7bded08bdc
--- /dev/null
+++ b/distance-oracle/src/mock.rs
@@ -0,0 +1 @@
+
diff --git a/distance-oracle/src/tests.rs b/distance-oracle/src/tests.rs
new file mode 100644
index 0000000000000000000000000000000000000000..0c833b61a9f4587b93a5f94f74e61c210e28d1e3
--- /dev/null
+++ b/distance-oracle/src/tests.rs
@@ -0,0 +1,2 @@
+#[test]
+fn test_distance_validity() {}
diff --git a/pallets/distance/Cargo.toml b/pallets/distance/Cargo.toml
index 47f1f67105a70867e2ab8494eb6bdfd7ed0cc506..b2cb197a9fa0959eae518e369c26273e65dde624 100644
--- a/pallets/distance/Cargo.toml
+++ b/pallets/distance/Cargo.toml
@@ -34,6 +34,9 @@ pallet-identity = { path = "../identity", default-features = false }
 pallet-membership = { path = "../membership", default-features = false }
 sp-distance = { path = "../../primitives/distance", default-features = false }
 
+cc-traits = "1.0.0"
+median-accumulator = { version = "0.2.0", features = ["nostd"] }
+
 # substrate
 scale-info = { version = "2.1.1", default-features = false, features = [
     "derive",
diff --git a/pallets/distance/src/lib.rs b/pallets/distance/src/lib.rs
index cce777e7d6d3e43a76b6135c2534774ab1497c9c..09c38cbb248019d563b5714388ae617bf466b740 100644
--- a/pallets/distance/src/lib.rs
+++ b/pallets/distance/src/lib.rs
@@ -26,6 +26,7 @@ pub use traits::*;
 pub use types::*;
 
 use frame_support::traits::StorageVersion;
+//use median_accumulator::*;
 use pallet_authority_members::SessionIndex;
 use sp_distance::{InherentError, INHERENT_IDENTIFIER};
 use sp_inherents::{InherentData, InherentIdentifier};
@@ -65,7 +66,7 @@ pub mod pallet {
         /// Maximum number of identities to be evaluated in a session
         type MaxEvaluationsPerSession: Get<u32>;
         /// Maximum number of evaluators in a session
-        type MaxEvaluatorsPerSession: Get<u32>;
+        type MaxEvaluatorsPerSession: Get<u32> + TypeInfo;
         /// Minimum ratio of accessible referees
         type MinAccessibleReferees: Get<Perbill>;
         // /// Handler for the evaluation price in case of negative result
@@ -74,17 +75,8 @@ pub mod pallet {
 
     // STORAGE //
 
-    pub type EvaluationPool<
-        AccountId,
-        IdtyIndex,
-        MaxEvaluationsPerSession,
-        MaxEvaluatorsPerSession,
-    > = (
-        BoundedVec<(IdtyIndex, MedianAcc<Perbill>), MaxEvaluationsPerSession>,
-        BoundedBTreeSet<AccountId, MaxEvaluatorsPerSession>,
-    );
-
     #[pallet::storage]
+    #[pallet::getter(fn evaluation_pool_0)]
     pub type EvaluationPool0<T: Config<I>, I: 'static = ()> = StorageValue<
         _,
         EvaluationPool<
@@ -96,6 +88,7 @@ pub mod pallet {
         ValueQuery,
     >;
     #[pallet::storage]
+    #[pallet::getter(fn evaluation_pool_1)]
     pub type EvaluationPool1<T: Config<I>, I: 'static = ()> = StorageValue<
         _,
         EvaluationPool<
@@ -107,6 +100,7 @@ pub mod pallet {
         ValueQuery,
     >;
     #[pallet::storage]
+    #[pallet::getter(fn evaluation_pool_2)]
     pub type EvaluationPool2<T: Config<I>, I: 'static = ()> = StorageValue<
         _,
         EvaluationPool<
diff --git a/pallets/distance/src/median.rs b/pallets/distance/src/median.rs
index 065efb3119377cea4906e86c45e176f56f1b1941..a5f078d781c5d522abea2ddd65cef0882fa9fb97 100644
--- a/pallets/distance/src/median.rs
+++ b/pallets/distance/src/median.rs
@@ -14,12 +14,12 @@
 // You should have received a copy of the GNU Affero General Public License
 // along with Duniter-v2S. If not, see <https://www.gnu.org/licenses/>.
 
-use frame_support::pallet_prelude::*;
+use frame_support::{pallet_prelude::*, traits::*};
 use sp_std::{cmp::Ordering, vec::Vec};
 
 #[derive(Clone, Debug, Decode, Default, Encode, TypeInfo)]
-pub struct MedianAcc<T: Clone + Decode + Encode + Ord + TypeInfo> {
-    samples: Vec<(T, u32)>,
+pub struct MedianAcc<T: Clone + Decode + Encode + Ord + TypeInfo, S: Get<u32> + TypeInfo> {
+    samples: BoundedVec<(T, u32), S>,
     median_index: Option<u32>,
     median_subindex: u32,
 }
@@ -30,10 +30,10 @@ pub enum MedianResult<T: Clone + Ord> {
     Two(T, T),
 }
 
-impl<T: Clone + Decode + Encode + Ord + TypeInfo> MedianAcc<T> {
+impl<T: Clone + Decode + Encode + Ord + TypeInfo, S: Get<u32> + TypeInfo> MedianAcc<T, S> {
     pub fn new() -> Self {
         Self {
-            samples: Vec::new(),
+            samples: BoundedVec::default(),
             median_index: None,
             median_subindex: 0,
         }
@@ -84,7 +84,7 @@ impl<T: Clone + Decode + Encode + Ord + TypeInfo> MedianAcc<T> {
                     }
                 }
                 Err(sample_index) => {
-                    self.samples.insert(sample_index, (sample, 1));
+                    self.samples.try_insert(sample_index, (sample, 1));
                     if *median_index as usize >= sample_index {
                         if self.median_subindex == 0 {
                             self.median_subindex = self
@@ -115,7 +115,7 @@ impl<T: Clone + Decode + Encode + Ord + TypeInfo> MedianAcc<T> {
                 }
             }
         } else {
-            self.samples.push((sample, 1));
+            self.samples.try_push((sample, 1));
             self.median_index = Some(0);
         }
     }
diff --git a/pallets/distance/src/types.rs b/pallets/distance/src/types.rs
index 2d3edf946f670bc274f11519046e2a32fb3ea6ea..ab629ec482290350863cadfb8a85de3273a67b13 100644
--- a/pallets/distance/src/types.rs
+++ b/pallets/distance/src/types.rs
@@ -14,10 +14,13 @@
 // You should have received a copy of the GNU Affero General Public License
 // along with Duniter-v2S. If not, see <https://www.gnu.org/licenses/>.
 
+pub use crate::median::*;
 pub use sp_distance::ComputationResult;
 
 use codec::{Decode, Encode};
-use frame_support::pallet_prelude::*;
+use frame_support::{pallet_prelude::*, BoundedBTreeSet};
+//use median_accumulator::*;
+use sp_runtime::Perbill;
 
 #[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo)]
 pub enum DistanceStatus {
@@ -26,3 +29,18 @@ pub enum DistanceStatus {
     /// Identity respects the distance
     Valid,
 }
+
+pub type EvaluationPool<AccountId, IdtyIndex, MaxEvaluationsPerSession, MaxEvaluatorsPerSession> = (
+    BoundedVec<(IdtyIndex, MedianAcc<Perbill, MaxEvaluatorsPerSession>), MaxEvaluationsPerSession>,
+    BoundedBTreeSet<AccountId, MaxEvaluatorsPerSession>,
+);
+
+/*pub struct BoundedVecC<T, S>(BoundedVec<T, S>);
+
+impl<T, S> cc_traits::GetMut<T> for BoundedVecC<T, S> {}
+
+impl<T, S> cc_traits::Len for BoundedVecC<T, S> {
+    fn len(&self) -> usize {
+        self.0.len()
+    }
+}*/
diff --git a/resources/metadata.scale b/resources/metadata.scale
index c5d992edbe02769551ed0a8ba738d79232bccfbe..d877488391b6849628755f61564641ad0e10c5e8 100644
Binary files a/resources/metadata.scale and b/resources/metadata.scale differ