From 7e3b9aee1e829d7179c60f8aca5a4d346e9dca07 Mon Sep 17 00:00:00 2001 From: Collins Ikechukwu Date: Sat, 4 Apr 2026 08:02:05 +0100 Subject: [PATCH 1/2] fix: Emit MilestoneRejected event in reject_milestone() reject_milestone() updated status but emitted no event, making it invisible to the backend indexer. Adds MilestoneRejected event with campaign_id and milestone_id, matching the pattern of MilestoneApproved. Closes #5 Co-Authored-By: Claude Opus 4.6 (1M context) --- contracts/crowdfund_registry/src/contract.rs | 8 +++++++- contracts/crowdfund_registry/src/events/mod.rs | 8 ++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/contracts/crowdfund_registry/src/contract.rs b/contracts/crowdfund_registry/src/contract.rs index e7b58d4..0f2f61e 100644 --- a/contracts/crowdfund_registry/src/contract.rs +++ b/contracts/crowdfund_registry/src/contract.rs @@ -2,7 +2,7 @@ use crate::error::CrowdfundError; use crate::events::{ CampaignApproved, CampaignCancelled, CampaignCreated, CampaignFailed, CampaignFunded, CampaignRejected, CampaignSubmittedForReview, CampaignTerminated, CampaignValidated, - DisputeResolved, MilestoneApproved, MilestoneDisputed, MilestoneOverdue, + DisputeResolved, MilestoneApproved, MilestoneDisputed, MilestoneOverdue, MilestoneRejected, MilestoneRevisionRequested, MilestoneSubmitted, PledgeRecorded, RefundBatchProcessed, }; use crate::storage::{ @@ -722,6 +722,12 @@ impl CrowdfundRegistry { ms.status = CrowdfundMilestoneStatus::Rejected; env.storage().persistent().set(&ms_key, &ms); + MilestoneRejected { + campaign_id, + milestone_id: milestone_index, + } + .publish(&env); + Ok(()) } diff --git a/contracts/crowdfund_registry/src/events/mod.rs b/contracts/crowdfund_registry/src/events/mod.rs index 7a66a21..3348132 100644 --- a/contracts/crowdfund_registry/src/events/mod.rs +++ b/contracts/crowdfund_registry/src/events/mod.rs @@ -43,6 +43,14 @@ pub struct MilestoneApproved { pub milestone_id: u32, } +#[contractevent] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct MilestoneRejected { + #[topic] + pub campaign_id: u64, + pub milestone_id: u32, +} + #[contractevent] #[derive(Clone, Debug, Eq, PartialEq)] pub struct CampaignFailed { From e30c71ac58991f91eaf0f7e7aabe66b151461fba Mon Sep 17 00:00:00 2001 From: Collins Ikechukwu Date: Sat, 4 Apr 2026 08:06:14 +0100 Subject: [PATCH 2/2] refactor: apply consistent code formatting and indentation across contract and test files --- contracts/crowdfund_registry/src/contract.rs | 22 +++++++++---------- contracts/crowdfund_registry/src/tests/mod.rs | 8 +++++-- tests/integration/src/test_crowdfund_e2e.rs | 3 ++- 3 files changed, 18 insertions(+), 15 deletions(-) diff --git a/contracts/crowdfund_registry/src/contract.rs b/contracts/crowdfund_registry/src/contract.rs index 0f2f61e..6e91a74 100644 --- a/contracts/crowdfund_registry/src/contract.rs +++ b/contracts/crowdfund_registry/src/contract.rs @@ -387,7 +387,11 @@ impl CrowdfundRegistry { campaign.vote_session_id = None; env.storage().persistent().set(&key, &campaign); - CampaignRejected { id: campaign_id, reason }.publish(&env); + CampaignRejected { + id: campaign_id, + reason, + } + .publish(&env); Ok(()) } @@ -967,11 +971,7 @@ impl CrowdfundRegistry { milestone_index.into_val(&env), ], ); - env.invoke_contract::<()>( - &escrow_addr, - &sym(&env, "release_slot"), - release_args, - ); + env.invoke_contract::<()>(&escrow_addr, &sym(&env, "release_slot"), release_args); // Check if all milestones are released let mut all_done = true; @@ -1179,12 +1179,10 @@ impl CrowdfundRegistry { pct, status: CrowdfundMilestoneStatus::Pending, }; - env.storage() - .persistent() - .set( - &CrowdfundDataKey::CampaignMilestone(campaign_id, i), - &milestone, - ); + env.storage().persistent().set( + &CrowdfundDataKey::CampaignMilestone(campaign_id, i), + &milestone, + ); } } } diff --git a/contracts/crowdfund_registry/src/tests/mod.rs b/contracts/crowdfund_registry/src/tests/mod.rs index a210ae2..6b6b55e 100644 --- a/contracts/crowdfund_registry/src/tests/mod.rs +++ b/contracts/crowdfund_registry/src/tests/mod.rs @@ -182,7 +182,8 @@ fn test_reject_campaign() { ); t.client.submit_for_review(&cid); - t.client.reject_campaign(&cid, &String::from_str(&t.env, "Need more detail")); + t.client + .reject_campaign(&cid, &String::from_str(&t.env, "Need more detail")); assert_eq!(t.client.get_campaign(&cid).status, CampaignStatus::Draft); } @@ -202,7 +203,10 @@ fn test_create_and_submit_campaign() { &true, ); - assert_eq!(t.client.get_campaign(&cid).status, CampaignStatus::Submitted); + assert_eq!( + t.client.get_campaign(&cid).status, + CampaignStatus::Submitted + ); } #[test] diff --git a/tests/integration/src/test_crowdfund_e2e.rs b/tests/integration/src/test_crowdfund_e2e.rs index edb3f2e..aa57e0e 100644 --- a/tests/integration/src/test_crowdfund_e2e.rs +++ b/tests/integration/src/test_crowdfund_e2e.rs @@ -328,7 +328,8 @@ fn test_governance_rejection_flow() { p.crowdfund.submit_for_review(&cid); // Admin rejects → back to Draft - p.crowdfund.reject_campaign(&cid, &String::from_str(&p.env, "Needs more detail")); + p.crowdfund + .reject_campaign(&cid, &String::from_str(&p.env, "Needs more detail")); assert_eq!(p.crowdfund.get_campaign(&cid).status, CampaignStatus::Draft); // Owner can resubmit