@@ -2,12 +2,12 @@ use crate::error::CrowdfundError;
22use crate :: events:: {
33 CampaignApproved , CampaignCancelled , CampaignCreated , CampaignFailed , CampaignFunded ,
44 CampaignRejected , CampaignSubmittedForReview , CampaignTerminated , CampaignValidated ,
5- DisputeResolved , MilestoneApproved , MilestoneDisputed , MilestoneOverdue ,
5+ CampaignVoteRejected , DisputeResolved , MilestoneApproved , MilestoneDisputed , MilestoneOverdue ,
66 MilestoneRevisionRequested , MilestoneSubmitted , PledgeRecorded , RefundBatchProcessed ,
77} ;
88use crate :: storage:: {
99 Campaign , CampaignStatus , CrowdfundDataKey , CrowdfundMilestoneStatus , DisputeResolution ,
10- Milestone , VoteContext ,
10+ Milestone , VoteContext , VoteOption , VotingSession ,
1111} ;
1212use boundless_types:: ttl:: {
1313 INSTANCE_TTL_EXTEND , INSTANCE_TTL_THRESHOLD , PERSISTENT_TTL_EXTEND , PERSISTENT_TTL_THRESHOLD ,
@@ -387,7 +387,11 @@ impl CrowdfundRegistry {
387387 campaign. vote_session_id = None ;
388388 env. storage ( ) . persistent ( ) . set ( & key, & campaign) ;
389389
390- CampaignRejected { id : campaign_id, reason } . publish ( & env) ;
390+ CampaignRejected {
391+ id : campaign_id,
392+ reason,
393+ }
394+ . publish ( & env) ;
391395 Ok ( ( ) )
392396 }
393397
@@ -441,17 +445,76 @@ impl CrowdfundRegistry {
441445 . ok_or ( CrowdfundError :: NoVoteSession ) ?;
442446
443447 let gov_addr = Self :: get_gov_addr ( & env) ;
444- let args: Vec < Val > = Vec :: from_array ( & env, [ session_id. into_val ( & env) ] ) ;
445- let reached: bool = env. invoke_contract ( & gov_addr, & sym ( & env, "threshold_reached" ) , args) ;
446448
447- if !reached {
448- return Err ( CrowdfundError :: VoteThresholdNotMet ) ;
449- }
449+ // Check if vote threshold has been reached
450+ let threshold_args: Vec < Val > = Vec :: from_array ( & env, [ session_id. clone ( ) . into_val ( & env) ] ) ;
451+ let reached: bool =
452+ env. invoke_contract ( & gov_addr, & sym ( & env, "threshold_reached" ) , threshold_args) ;
450453
451- campaign. status = CampaignStatus :: Campaigning ;
452- env. storage ( ) . persistent ( ) . set ( & key, & campaign) ;
454+ if reached {
455+ // Threshold reached — check which option won
456+ let approve_args: Vec < Val > = Vec :: from_array (
457+ & env,
458+ [
459+ session_id. clone ( ) . into_val ( & env) ,
460+ 0u32 . into_val ( & env) , // option 0 = Approve
461+ ] ,
462+ ) ;
463+ let reject_args: Vec < Val > = Vec :: from_array (
464+ & env,
465+ [
466+ session_id. into_val ( & env) ,
467+ 1u32 . into_val ( & env) , // option 1 = Reject
468+ ] ,
469+ ) ;
470+
471+ let approve_option: VoteOption =
472+ env. invoke_contract ( & gov_addr, & sym ( & env, "get_option" ) , approve_args) ;
473+ let reject_option: VoteOption =
474+ env. invoke_contract ( & gov_addr, & sym ( & env, "get_option" ) , reject_args) ;
475+
476+ let approve_votes = approve_option. votes ;
477+ let reject_votes = reject_option. votes ;
478+
479+ if approve_votes > reject_votes {
480+ campaign. status = CampaignStatus :: Campaigning ;
481+ env. storage ( ) . persistent ( ) . set ( & key, & campaign) ;
482+ CampaignValidated { id : campaign_id } . publish ( & env) ;
483+ } else if reject_votes > approve_votes {
484+ campaign. status = CampaignStatus :: Draft ;
485+ campaign. vote_session_id = None ;
486+ env. storage ( ) . persistent ( ) . set ( & key, & campaign) ;
487+ CampaignVoteRejected {
488+ id : campaign_id,
489+ reason : String :: from_str ( & env, "reject_majority" ) ,
490+ }
491+ . publish ( & env) ;
492+ } else {
493+ // Tie — leave state unchanged, session stays open
494+ return Err ( CrowdfundError :: VoteThresholdNotMet ) ;
495+ }
496+ } else {
497+ // Threshold not reached — check if voting period has expired
498+ let session_args: Vec < Val > = Vec :: from_array ( & env, [ session_id. into_val ( & env) ] ) ;
499+ let session: VotingSession =
500+ env. invoke_contract ( & gov_addr, & sym ( & env, "get_session" ) , session_args) ;
501+
502+ if env. ledger ( ) . timestamp ( ) <= session. end_at {
503+ // Voting still open, threshold not met yet
504+ return Err ( CrowdfundError :: VoteThresholdNotMet ) ;
505+ }
506+
507+ // Voting expired without reaching threshold — reject
508+ campaign. status = CampaignStatus :: Draft ;
509+ campaign. vote_session_id = None ;
510+ env. storage ( ) . persistent ( ) . set ( & key, & campaign) ;
511+ CampaignVoteRejected {
512+ id : campaign_id,
513+ reason : String :: from_str ( & env, "expired_without_approval" ) ,
514+ }
515+ . publish ( & env) ;
516+ }
453517
454- CampaignValidated { id : campaign_id } . publish ( & env) ;
455518 Ok ( ( ) )
456519 }
457520
@@ -961,11 +1024,7 @@ impl CrowdfundRegistry {
9611024 milestone_index. into_val ( & env) ,
9621025 ] ,
9631026 ) ;
964- env. invoke_contract :: < ( ) > (
965- & escrow_addr,
966- & sym ( & env, "release_slot" ) ,
967- release_args,
968- ) ;
1027+ env. invoke_contract :: < ( ) > ( & escrow_addr, & sym ( & env, "release_slot" ) , release_args) ;
9691028
9701029 // Check if all milestones are released
9711030 let mut all_done = true ;
@@ -1173,12 +1232,10 @@ impl CrowdfundRegistry {
11731232 pct,
11741233 status : CrowdfundMilestoneStatus :: Pending ,
11751234 } ;
1176- env. storage ( )
1177- . persistent ( )
1178- . set (
1179- & CrowdfundDataKey :: CampaignMilestone ( campaign_id, i) ,
1180- & milestone,
1181- ) ;
1235+ env. storage ( ) . persistent ( ) . set (
1236+ & CrowdfundDataKey :: CampaignMilestone ( campaign_id, i) ,
1237+ & milestone,
1238+ ) ;
11821239 }
11831240 }
11841241}
0 commit comments