Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 4 additions & 0 deletions contracts/claims-processor/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -496,6 +496,10 @@ impl ClaimsProcessor {
if policy.policyholder != *claimant {
panic_with_error!(env, Error::Unauthorized);
}
// Guard: reject claims for cancelled policies (issue #731).
if policy.status == parashield_policy_engine::PolicyStatus::Cancelled {
panic_with_error!(env, Error::PolicyNotActive);
}
if policy.status != parashield_policy_engine::PolicyStatus::Active {
panic_with_error!(env, Error::PolicyNotActive);
}
Expand Down
13 changes: 8 additions & 5 deletions contracts/governance-dao/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -324,11 +324,10 @@ impl GovernanceDao {
panic_with_error!(&env, Error::TitleTooLong);
}

// SECURITY FIX: Validate impact analysis length to prevent storage exhaustion.
// Limit to 4096 bytes — reasonable for a proposal description without enabling
// attacks that reserve huge storage or inflate transaction costs.
if impact_analysis.is_empty() {
panic_with_error!(&env, Error::InvalidInput);
// SECURITY FIX: Validate proposal description (impact_analysis) is not empty (issue #732).
// Enforce non-empty and minimum length to ensure informative proposals, bounded up to 4096 bytes.
if impact_analysis.is_empty() || impact_analysis.len() < 5 {
panic_with_error!(&env, Error::EmptyDescription);
}
if impact_analysis.len() > 4096 {
panic_with_error!(&env, Error::InvalidInput);
Expand Down Expand Up @@ -1872,6 +1871,10 @@ impl GovernanceDao {
) {
Self::require_admin(&env, &admin);

if description.is_empty() {
panic_with_error!(&env, Error::EmptyDescription);
}

if env.storage().instance().has(&StorageKey::Template(name.clone())) {
panic_with_error!(&env, Error::DuplicateTemplateName);
}
Expand Down
15 changes: 15 additions & 0 deletions contracts/policy-engine/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,8 @@ impl PolicyEngine {
if oracle_buf[0] != b'C' {
panic_with_error!(&env, Error::InvalidAddress);
}
// Reject zero address as oracle (issue #730)
Self::require_not_zero_address(&env, &oracle_address);

let balance_res = env.try_invoke_contract::<i128, soroban_sdk::Error>(
&usdc_token,
Expand Down Expand Up @@ -367,6 +369,8 @@ impl PolicyEngine {
if oracle_buf[0] != b'C' {
panic_with_error!(&env, Error::InvalidAddress);
}
// Reject zero address as oracle (issue #730)
Self::require_not_zero_address(&env, &new_oracle);

let change = PendingOracleChange {
new_oracle: new_oracle.clone(),
Expand Down Expand Up @@ -2004,6 +2008,17 @@ impl PolicyEngine {
}

fn migrate_v2_to_v3(_env: &Env) {}

/// Require that an address is not the zero address (issue #730).
fn require_not_zero_address(env: &Env, address: &Address) {
let zero = Address::from_string(&soroban_sdk::String::from_str(
env,
"GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWHF",
));
if *address == zero {
panic_with_error!(env, Error::InvalidAddress);
}
}
}

#[cfg(test)]
Expand Down
4 changes: 2 additions & 2 deletions contracts/risk-pool/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -281,8 +281,8 @@ impl RiskPool {
if env.storage().instance().has(&StorageKey::Initialized) {
panic_with_error!(&env, Error::AlreadyInitialized);
}
// An empty category would make the pool's accounting and LP NFT
// metadata ambiguous, so reject it up front (issue #520).
// Category name cannot be empty and must describe a valid risk category (issue #729, #520).
// Empty category names are rejected to prevent unnamed categories in the pool registry.
if category == Symbol::new(&env, "") {
panic_with_error!(&env, Error::InvalidCategory);
}
Expand Down
Loading