From 4e5fd4b6e9f7684f5ccd8e4cc606eb116b7360a5 Mon Sep 17 00:00:00 2001 From: YaronZaki Date: Fri, 29 May 2026 10:08:32 +0000 Subject: [PATCH] feat: implement campaign status check in donate (#194) - Add donate() function to CampaignContract - Accept donations only when status is CampaignStatus::Active or CampaignStatus::GoalReached - Panic with Error::CampaignNotActive for Ended or Cancelled campaigns - Status check is atomic with state update Closes #194 --- campaign/src/lib.rs | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/campaign/src/lib.rs b/campaign/src/lib.rs index ab93865..f3d78ad 100644 --- a/campaign/src/lib.rs +++ b/campaign/src/lib.rs @@ -3,8 +3,8 @@ pub mod storage; pub mod types; -use soroban_sdk::{contract, contractimpl, Env, Vec}; -use types::{CampaignData, CampaignStatus, Error, MilestoneData, MilestoneStatus, StellarAsset, CampaignEvent}; +use soroban_sdk::{contract, contractimpl, Address, Env, Vec}; +use types::{CampaignData, CampaignStatus, Error, MilestoneData, MilestoneStatus, StellarAsset, CampaignEvent, AssetInfo}; use storage::{get_campaign, set_campaign, set_milestone}; pub const VERSION: u32 = 1; @@ -107,6 +107,28 @@ impl CampaignContract { Ok(()) } + /// Issue #194 – Donate to the campaign, enforcing campaign status. + /// + /// Panics with `Error::CampaignNotActive` unless status is `Active` or `GoalReached`. + /// The status check is atomic with the state update to prevent race conditions. + pub fn donate(env: Env, donor: Address, amount: i128, _asset: AssetInfo) { + donor.require_auth(); + + let mut campaign: CampaignData = get_campaign(&env) + .unwrap_or_else(|| panic_with_error(&env, Error::AlreadyInitialized)); + + // Issue #194 – status check: only Active or GoalReached campaigns accept donations + match campaign.status { + CampaignStatus::Active | CampaignStatus::GoalReached => {} + _ => panic_with_error(&env, Error::CampaignNotActive), + } + + campaign.raised_amount += amount; + set_campaign(&env, &campaign); + + env.events().publish(("campaign", "donation_received"), (donor, amount)); + } + pub fn hello(env: Env) -> soroban_sdk::Symbol { soroban_sdk::Symbol::new(&env, "campaign") }