From 94c1c5043d4abf19767f104da5d5a16c048e211a Mon Sep 17 00:00:00 2001 From: YaronZaki Date: Fri, 29 May 2026 10:07:48 +0000 Subject: [PATCH] feat: implement campaign deadline enforcement in donate (#193) - Add donate() function to CampaignContract - Check env.ledger().timestamp() > campaign.end_time before accepting donation - Panic with Error::CampaignEnded when deadline has passed - Check is atomic with state update to prevent race conditions Closes #193 --- campaign/src/lib.rs | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/campaign/src/lib.rs b/campaign/src/lib.rs index ab93865..33bd0cd 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,27 @@ impl CampaignContract { Ok(()) } + /// Issue #193 – Donate to the campaign, enforcing the campaign deadline. + /// + /// Panics with `Error::CampaignEnded` if `env.ledger().timestamp() > campaign.end_time`. + /// The 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 #193 – deadline enforcement: reject donations after end_time + if env.ledger().timestamp() > campaign.end_time { + panic_with_error(&env, Error::CampaignEnded); + } + + 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") }