Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
d6900bf
feat: Implement Development Grants Fund contract (SOV-L0-2.3)
umwelt Jan 7, 2026
61084ce
fix: Apply critical security fixes to Development Grants contract (Ph…
umwelt Jan 7, 2026
5f5779e
fix: Implement final Phase-2 DevGrants with atomic token transfer and…
umwelt Jan 7, 2026
cde4b19
feat: Implement Universal Basic Income Distribution contract (SOV-L0-…
umwelt Jan 7, 2026
75cbc80
feat: Enhance capability-bound authorization in token transfers and U…
umwelt Jan 7, 2026
05d2e97
feat: Add UBI Distribution and Development Grants contract types to t…
umwelt Jan 7, 2026
e25411e
feat: Implement system configuration and persistence for UBI and DevG…
umwelt Jan 7, 2026
3581847
feat: Enhance system configuration management and governance authorit…
umwelt Jan 7, 2026
47b67d9
fix: Borrow String as &str in node identity tests
umwelt Jan 7, 2026
bf46298
fix: Implement restart-safe global alert manager
umwelt Jan 7, 2026
0f17917
Merge development into branch
umwelt Jan 8, 2026
0cc6538
fix: Remove unused cfg feature condition in dao_registry
umwelt Jan 8, 2026
f629191
fix: Replace panic-prone expect() with Result in dao_registry list me…
umwelt Jan 8, 2026
209b8a8
fix: Remove dead code in dao_registry update_metadata
umwelt Jan 8, 2026
4b2630e
fix: Log Byzantine faults at ERROR level when monitoring is unavailable
umwelt Jan 8, 2026
64bf4a3
fix: Webhook notifications now properly report failures instead of si…
umwelt Jan 8, 2026
08b0753
fix: Remove invalid Default implementations from DevGrants and UbiDis…
umwelt Jan 8, 2026
0e6f6e2
fix: Address all code review findings - critical, important, and nice…
umwelt Jan 8, 2026
6cf963f
fix: Enforce governance authority checks for fund reception in UbiDis…
umwelt Jan 8, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -67,3 +67,4 @@ docs/sov_final/SOV_QUICK_REFERENCE.md
docs/sov_final/SOV_TICKET_AUDIT.md
docs/sov_final/SOV_TOKENOMICS_CORRECTED.md
.serena/project.yml
docs/sov_final/SOV_COMPREHENSIVE_REFERENCE.md
85 changes: 38 additions & 47 deletions lib-blockchain/src/contracts/dao_registry/registry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ impl DAORegistry {
// Defensive check: DAO ID should not already exist (extremely unlikely with BLAKE3)
if self.entries.contains_key(&dao_id) {
return Err(format!(
"DAO ID collision detected (probability ~1 in 2^256): {}",
"DAO ID collision detected (cryptographically implausible): {}",
hex::encode(&dao_id)
));
}
Expand Down Expand Up @@ -246,41 +246,45 @@ impl DAORegistry {
/// # Invariant
/// Order is guaranteed to be insertion order and stable across upgrades
///
/// # Panics
/// If dao_list and entries diverge (catastrophic registry corruption)
/// This is the correct behavior: silent data loss is unacceptable
pub fn list_daos(&self) -> Vec<DAOEntry> {
self.dao_list
.iter()
.map(|&dao_id| {
self.entries.get(&dao_id)
.cloned()
.expect(&format!(
"CRITICAL: DAO registry corrupted - dao_list contains ID {} but entry not found. \
/// # Returns
/// Returns `Ok(Vec<DAOEntry>)` on success, or `Err` if registry is corrupted
/// (dao_list and entries out of sync). This is a fail-safe to prevent
/// silent data loss - corruption is always reported, never silently ignored.
pub fn list_daos(&self) -> Result<Vec<DAOEntry>, String> {
let mut entries = Vec::new();
for &dao_id in &self.dao_list {
match self.entries.get(&dao_id) {
Some(entry) => entries.push(entry.clone()),
None => {
return Err(format!(
"DAO registry corrupted: dao_list contains ID {} but entry not found. \
This indicates data structure desynchronization.",
hex::encode(&dao_id)
))
})
.collect()
}
}
}
Ok(entries)
}

/// List all DAOs with their IDs
///
/// # Panics
/// If dao_list and entries diverge (catastrophic registry corruption)
pub fn list_daos_with_ids(&self) -> Vec<(DAOEntry, [u8; 32])> {
self.dao_list
.iter()
.map(|&dao_id| {
let entry = self.entries.get(&dao_id)
.cloned()
.expect(&format!(
"CRITICAL: DAO registry corrupted - dao_list contains ID {} but entry not found",
/// # Returns
/// Returns `Ok(Vec<(DAOEntry, ID)>)` on success, or `Err` if registry is corrupted.
pub fn list_daos_with_ids(&self) -> Result<Vec<(DAOEntry, [u8; 32])>, String> {
let mut result = Vec::new();
for &dao_id in &self.dao_list {
match self.entries.get(&dao_id) {
Some(entry) => result.push((entry.clone(), dao_id)),
None => {
return Err(format!(
"DAO registry corrupted: dao_list contains ID {} but entry not found",
hex::encode(&dao_id)
));
(entry, dao_id)
})
.collect()
))
}
}
}
Ok(result)
}

/// Update DAO metadata
Expand Down Expand Up @@ -321,21 +325,8 @@ impl DAORegistry {
}

// === MUTATION PHASE ===
let old_hash = entry.metadata_hash;
entry.metadata_hash = new_metadata_hash;

// Emit event (if logging is available)
// Include both old and new hash for audit trail and compliance
#[cfg(feature = "logging")]
{
tracing::info!(
"DAO metadata updated: {} (old_hash: {} → new_hash: {})",
hex::encode(&dao_id),
hex::encode(&old_hash),
hex::encode(&new_metadata_hash)
);
}

Ok(())
}

Expand Down Expand Up @@ -594,7 +585,7 @@ mod tests {
);

assert!(result.is_ok());
let entry = registry.list_daos()[0].clone();
let entry = registry.list_daos().unwrap()[0].clone();
assert_eq!(entry.created_at, 0);
}

Expand Down Expand Up @@ -657,7 +648,7 @@ mod tests {
})
.collect();

let list = registry.list_daos_with_ids();
let list = registry.list_daos_with_ids().unwrap();
assert_eq!(list.len(), 3);

// Verify order
Expand Down Expand Up @@ -1080,12 +1071,12 @@ mod tests {
assert!(registry.dao_list.contains(&dao_id));
}

// Verify list_daos() returns all without panic
let daos = registry.list_daos();
// Verify list_daos() returns all without error
let daos = registry.list_daos().unwrap();
assert_eq!(daos.len(), 5);

// Verify list_daos_with_ids() returns all without panic
let daos_with_ids = registry.list_daos_with_ids();
// Verify list_daos_with_ids() returns all without error
let daos_with_ids = registry.list_daos_with_ids().unwrap();
assert_eq!(daos_with_ids.len(), 5);

// Verify counts match
Expand Down
Loading
Loading