diff --git a/pallets/identity/src/lib.rs b/pallets/identity/src/lib.rs
index 0cc9fc0895b89dc5a44acb99ae3f936da3267fd3..1da429a4a0b0d3de3cfd095abf6181f2f4de55c3 100644
--- a/pallets/identity/src/lib.rs
+++ b/pallets/identity/src/lib.rs
@@ -620,3 +620,32 @@ where
         Ok(result)
     }
 }
+
+pub struct IdtyDataIter<T: Config>(
+    Box<dyn Iterator<Item = IdtyValue<T::BlockNumber, T::AccountId, T::IdtyData>>>,
+);
+
+impl<T: Config> From<Option<Vec<u8>>> for IdtyDataIter<T> {
+    fn from(maybe_key: Option<Vec<u8>>) -> Self {
+        let mut iter = Identities::<T>::iter_values();
+        if let Some(key) = maybe_key {
+            iter.set_last_raw_key(key);
+        }
+        Self(Box::new(iter))
+    }
+}
+
+impl<T: Config> Iterator for IdtyDataIter<T> {
+    type Item = (T::AccountId, T::IdtyData);
+
+    fn next(&mut self) -> Option<Self::Item> {
+        if let Some(IdtyValue {
+            owner_key, data, ..
+        }) = self.0.next()
+        {
+            Some((owner_key, data))
+        } else {
+            None
+        }
+    }
+}
diff --git a/pallets/universal-dividend/Cargo.toml b/pallets/universal-dividend/Cargo.toml
index 27df84d6e81bf59ad29ba5cc982eddf8fd67510e..f6ab06ac8ba9283d204d110efe13d55e6b4f87e1 100644
--- a/pallets/universal-dividend/Cargo.toml
+++ b/pallets/universal-dividend/Cargo.toml
@@ -12,7 +12,7 @@ version = '3.0.0'
 default = ['std']
 runtime-benchmarks = [
 	"frame-benchmarking/runtime-benchmarks",
-	"pallet-balances"
+	"pallet-balances",
 ]
 std = [
     'codec/std',
diff --git a/pallets/universal-dividend/src/benchmarking.rs b/pallets/universal-dividend/src/benchmarking.rs
index 0d4cfafc686952dcfdda3e93da440edded17adcc..0dd6b662d68a911565134f4fd2d9491611379472 100644
--- a/pallets/universal-dividend/src/benchmarking.rs
+++ b/pallets/universal-dividend/src/benchmarking.rs
@@ -18,8 +18,8 @@
 
 use super::*;
 
-use frame_benchmarking::{account, benchmarks, whitelisted_caller};
-use frame_support::pallet_prelude::IsType;
+use frame_benchmarking::{account, benchmarks, whitelist_account, whitelisted_caller};
+use frame_support::pallet_prelude::{BoundedVec, IsType};
 use frame_support::traits::{Get, OnInitialize};
 use frame_system::RawOrigin;
 use pallet_balances::Pallet as Balances;
@@ -68,6 +68,40 @@ benchmarks! {
     }: { Pallet::<T>::on_initialize(block_number.into()); }
     verify {
     }
+    // Benchmark `claim_uds` extrinsic with the worst possible conditions:
+    // * UDs have never been claimed
+    // * The maximum number of revaluations has taken place since
+    where_clause {
+        where
+        T: pallet_balances::Config, T::Balance: From<u64>,
+        <T::Currency as Currency<T::AccountId>>::Balance: IsType<T::Balance>
+    }
+    claim_uds {
+        let n in 1 .. T::MaxPastReeval::get();
+
+        // Caller should be a member
+        let caller: T::AccountId = T::MembersStorageIter::from(None)
+            .next()
+            .expect("we need at least one member")
+            .0;
+
+        // Simulate n reevals
+        let mut past_reevals = BoundedVec::default();
+        for i in 0..n {
+            past_reevals
+                .try_push((((3 * i) + 1) as u16, ((1_000 + (100 * i)) as u32).into()))
+                .expect("unreachable");
+        }
+        PastReevals::<T>::put(past_reevals);
+
+        // Simulate 3n+2 UDs
+        CurrentUdIndex::<T>::put(((3 * n) + 2) as u16);
+
+        whitelist_account!(caller);
+    }: claim_uds(RawOrigin::Signed(caller))
+    verify {
+    }
+
     // Benchmark `transfer_ud` extrinsic with the worst possible conditions:
     // * Transfer will kill the sender account.
     // * Transfer will create the recipient account.
@@ -121,7 +155,7 @@ benchmarks! {
             first_reeval: 8,
             first_ud: 1_000,
             initial_monetary_mass: 0,
-            initial_members: Vec::new()
+            initial_members: vec![1],
         }),
         crate::mock::Test
     );
diff --git a/pallets/universal-dividend/src/lib.rs b/pallets/universal-dividend/src/lib.rs
index d6b181a26a4fc7b7343ceeef3cea5a8dbafe63fe..f6ebcc8afb51766c13bcd7ba91b6ffb67087d426 100644
--- a/pallets/universal-dividend/src/lib.rs
+++ b/pallets/universal-dividend/src/lib.rs
@@ -43,6 +43,7 @@ pub mod pallet {
     use frame_support::traits::{StorageVersion, StoredMap};
     use frame_system::pallet_prelude::*;
     use sp_runtime::traits::Convert;
+    use sp_std::vec::Vec;
 
     pub type BalanceOf<T> =
         <<T as Config>::Currency as Currency<<T as frame_system::Config>::AccountId>>::Balance;
@@ -71,6 +72,9 @@ pub mod pallet {
         type MembersCount: Get<BalanceOf<Self>>;
         /// Somethings that must provide the list of accounts ids allowed to create the universal dividend
         type MembersStorage: frame_support::traits::StoredMap<Self::AccountId, FirstEligibleUd>;
+        /// An iterator over all members
+        type MembersStorageIter: From<Option<Vec<u8>>>
+            + Iterator<Item = (Self::AccountId, FirstEligibleUd)>;
         #[pallet::constant]
         /// Square of the money growth rate per ud reevaluation period
         type SquareMoneyGrowthRate: Get<Perbill>;
diff --git a/pallets/universal-dividend/src/mock.rs b/pallets/universal-dividend/src/mock.rs
index 238a3d5968f31f45be385cd1ee505f57e1044ff2..a53a0fe966f6cef5d1c78be10bae9785417ce984 100644
--- a/pallets/universal-dividend/src/mock.rs
+++ b/pallets/universal-dividend/src/mock.rs
@@ -18,7 +18,7 @@ use super::*;
 use crate::{self as pallet_universal_dividend};
 use frame_support::{
     parameter_types,
-    traits::{Everything, OnFinalize, OnInitialize, StorageMapShim},
+    traits::{Everything, OnFinalize, OnInitialize},
 };
 use frame_system as system;
 use sp_core::H256;
@@ -102,13 +102,49 @@ parameter_types! {
     pub const UdReevalPeriod: BlockNumber = 8;
 }
 
+pub struct TestMembersStorage;
+impl frame_support::traits::StoredMap<u64, FirstEligibleUd> for TestMembersStorage {
+    fn get(key: &u64) -> FirstEligibleUd {
+        crate::TestMembers::<Test>::get(key)
+    }
+    fn try_mutate_exists<R, E: From<sp_runtime::DispatchError>>(
+        key: &u64,
+        f: impl FnOnce(&mut Option<FirstEligibleUd>) -> Result<R, E>,
+    ) -> Result<R, E> {
+        let mut value = Some(crate::TestMembers::<Test>::get(key));
+        let result = f(&mut value)?;
+        if let Some(value) = value {
+            crate::TestMembers::<Test>::insert(key, value)
+        }
+        Ok(result)
+    }
+}
+pub struct TestMembersStorageIter(frame_support::storage::PrefixIterator<(u64, FirstEligibleUd)>);
+impl From<Option<Vec<u8>>> for TestMembersStorageIter {
+    fn from(maybe_key: Option<Vec<u8>>) -> Self {
+        let mut iter = crate::TestMembers::<Test>::iter();
+        if let Some(key) = maybe_key {
+            iter.set_last_raw_key(key);
+        }
+        Self(iter)
+    }
+}
+impl Iterator for TestMembersStorageIter {
+    type Item = (u64, FirstEligibleUd);
+
+    fn next(&mut self) -> Option<Self::Item> {
+        self.0.next()
+    }
+}
+
 impl pallet_universal_dividend::Config for Test {
     type BlockNumberIntoBalance = sp_runtime::traits::ConvertInto;
     type Currency = pallet_balances::Pallet<Test>;
     type Event = Event;
     type MaxPastReeval = frame_support::traits::ConstU32<2>;
     type MembersCount = MembersCount;
-    type MembersStorage = StorageMapShim<crate::TestMembers<Test>, (), u64, FirstEligibleUd>;
+    type MembersStorage = TestMembersStorage;
+    type MembersStorageIter = TestMembersStorageIter;
     type SquareMoneyGrowthRate = SquareMoneyGrowthRate;
     type UdCreationPeriod = UdCreationPeriod;
     type UdReevalPeriod = UdReevalPeriod;
diff --git a/runtime/common/src/pallets_config.rs b/runtime/common/src/pallets_config.rs
index 46f01f6658fcf525561a1a5a00b2001280430c5c..be602e77dc69c1e0a2cbbc9236e0d8c9f72ea6cc 100644
--- a/runtime/common/src/pallets_config.rs
+++ b/runtime/common/src/pallets_config.rs
@@ -400,6 +400,7 @@ macro_rules! pallets_config {
 			type MaxPastReeval = frame_support::traits::ConstU32<4>;
             type MembersCount = MembersCount;
             type MembersStorage = Identity;
+			type MembersStorageIter = pallet_identity::IdtyDataIter<Runtime>;
             type SquareMoneyGrowthRate = SquareMoneyGrowthRate;
             type UdCreationPeriod = UdCreationPeriod;
             type UdReevalPeriod = UdReevalPeriod;