diff --git a/governance/program/src/processor/process_cast_vote.rs b/governance/program/src/processor/process_cast_vote.rs index eb20c9d1..b8434d3c 100644 --- a/governance/program/src/processor/process_cast_vote.rs +++ b/governance/program/src/processor/process_cast_vote.rs @@ -82,11 +82,7 @@ pub fn process_cast_vote( governance_info.key, &proposal_governing_token_mint, )?; - proposal_data.assert_can_cast_vote( - &vote_kind, - &governance_data.config, - clock.unix_timestamp, - )?; + proposal_data.assert_can_cast_vote(&governance_data.config, clock.unix_timestamp)?; let mut voter_token_owner_record_data = get_token_owner_record_data_for_realm_and_governing_mint( diff --git a/governance/program/src/state/governance.rs b/governance/program/src/state/governance.rs index e536d8f4..fdfb9294 100644 --- a/governance/program/src/state/governance.rs +++ b/governance/program/src/state/governance.rs @@ -31,7 +31,6 @@ pub struct GovernanceConfig { pub min_community_weight_to_create_proposal: u64, /// Minimum waiting time in seconds for a transaction to be executed after proposal is voted on - /// If Veto vote is enabled then it can also be cast within the hold up period after Proposal vote ends pub min_transaction_hold_up_time: u32, /// Time limit in seconds for proposal to be open for voting diff --git a/governance/program/src/state/proposal.rs b/governance/program/src/state/proposal.rs index 490f18a9..0230a3a7 100644 --- a/governance/program/src/state/proposal.rs +++ b/governance/program/src/state/proposal.rs @@ -260,88 +260,25 @@ impl ProposalV2 { Ok(()) } - /// Checks if the given vote kind can be cast for the Proposal + /// Checks if Proposal can be voted on pub fn assert_can_cast_vote( &self, - vote_kind: &VoteKind, - governance_config: &GovernanceConfig, + config: &GovernanceConfig, current_unix_timestamp: UnixTimestamp, ) -> Result<(), ProgramError> { - match vote_kind { - VoteKind::Electorate => { - self.assert_can_cast_electorate_vote(governance_config, current_unix_timestamp) - } - VoteKind::Veto => { - self.assert_can_cast_veto_vote(governance_config, current_unix_timestamp) - } - } - } - - /// Checks if Electorate vote can be cast for the Proposal - pub fn assert_can_cast_electorate_vote( - &self, - governance_config: &GovernanceConfig, - current_unix_timestamp: UnixTimestamp, - ) -> Result<(), ProgramError> { - // Electorate vote can only be cast in Voting state self.assert_is_voting_state() .map_err(|_| GovernanceError::InvalidStateCannotVote)?; - // The Proposal can be still in Voting state after the voting time ends and before it's finalized // Check if we are still within the configured max_voting_time period - if self.has_vote_time_ended(governance_config, current_unix_timestamp) { + if self.has_vote_time_ended(config, current_unix_timestamp) { return Err(GovernanceError::ProposalVotingTimeExpired.into()); } Ok(()) } - /// Checks if Veto vote can be cast for the Proposal - pub fn assert_can_cast_veto_vote( - &self, - governance_config: &GovernanceConfig, - current_unix_timestamp: UnixTimestamp, - ) -> Result<(), ProgramError> { - match self.state { - // Veto vote can be cast when: - // Proposal is in Voting state and within max_voting_time + min_transaction_hold_up_time period - ProposalState::Voting => { - if self - .expected_vote_end_time(governance_config) - .saturating_add(governance_config.min_transaction_hold_up_time as i64) - < current_unix_timestamp - { - Err(GovernanceError::ProposalVotingTimeExpired.into()) - } else { - Ok(()) - } - } - // Proposal is in Succeeded state and within min_transaction_hold_up_time period calculated from the time when the vote ended (voting_completed_at) - ProposalState::Succeeded => { - if self - .voting_completed_at - .unwrap() - .saturating_add(governance_config.min_transaction_hold_up_time as i64) - < current_unix_timestamp - { - Err(GovernanceError::ProposalVotingTimeExpired.into()) - } else { - Ok(()) - } - } - ProposalState::Draft - | ProposalState::Executing - | ProposalState::ExecutingWithErrors - | ProposalState::Completed - | ProposalState::Cancelled - | ProposalState::SigningOff - | ProposalState::Defeated - | ProposalState::Vetoed => Err(GovernanceError::InvalidStateCannotVote.into()), - } - } - - /// Expected vote end time determined by the configured max_voting_time period - pub fn expected_vote_end_time(&self, config: &GovernanceConfig) -> UnixTimestamp { + /// Vote end time determined by the configured max_voting_time period + pub fn vote_end_time(&self, config: &GovernanceConfig) -> UnixTimestamp { self.voting_at .unwrap() .checked_add(config.max_voting_time as i64) @@ -355,7 +292,7 @@ impl ProposalV2 { current_unix_timestamp: UnixTimestamp, ) -> bool { // Check if we passed vote_end_time - self.expected_vote_end_time(config) < current_unix_timestamp + self.vote_end_time(config) < current_unix_timestamp } /// Checks if Proposal can be finalized @@ -387,7 +324,7 @@ impl ProposalV2 { self.assert_can_finalize_vote(config, current_unix_timestamp)?; self.state = self.resolve_final_vote_state(max_voter_weight, vote_threshold)?; - self.voting_completed_at = Some(self.expected_vote_end_time(config)); + self.voting_completed_at = Some(self.vote_end_time(config)); // Capture vote params to correctly display historical results self.max_vote_weight = Some(max_voter_weight); @@ -1715,7 +1652,7 @@ mod test { // Assert assert_eq!(proposal.state,test_case.expected_finalized_state,"CASE: {:?}",test_case); assert_eq!( - Some(proposal.expected_vote_end_time(&governance_config)), + Some(proposal.vote_end_time(&governance_config)), proposal.voting_completed_at ); @@ -2290,11 +2227,9 @@ mod test { let current_timestamp = proposal.voting_at.unwrap() + governance_config.max_voting_time as i64 + 1; - let vote_kind = VoteKind::Electorate; - // Act let err = proposal - .assert_can_cast_vote(&vote_kind, &governance_config, current_timestamp) + .assert_can_cast_vote(&governance_config, current_timestamp) .err() .unwrap(); @@ -2312,62 +2247,13 @@ mod test { let current_timestamp = proposal.voting_at.unwrap() + governance_config.max_voting_time as i64; - let vote_kind = VoteKind::Electorate; - // Act - let result = - proposal.assert_can_cast_vote(&vote_kind, &governance_config, current_timestamp); + let result = proposal.assert_can_cast_vote(&governance_config, current_timestamp); // Assert assert_eq!(result, Ok(())); } - #[test] - pub fn test_assert_can_cast_veto_vote_for_voting_proposal_within_hold_up_time() { - // Arrange - let mut proposal = create_test_proposal(); - proposal.state = ProposalState::Voting; - let governance_config = create_test_governance_config(); - - let current_timestamp = proposal.voting_at.unwrap() - + governance_config.max_voting_time as i64 - + governance_config.min_transaction_hold_up_time as i64; - - let vote_kind = VoteKind::Veto; - - // Act - let result = - proposal.assert_can_cast_vote(&vote_kind, &governance_config, current_timestamp); - - // Assert - assert_eq!(result, Ok(())); - } - - #[test] - pub fn test_assert_can_cast_veto_vote_for_voting_proposal_with_cannot_cast_after_hold_up_time_error( - ) { - // Arrange - let mut proposal = create_test_proposal(); - proposal.state = ProposalState::Voting; - let governance_config = create_test_governance_config(); - - let current_timestamp = proposal.voting_at.unwrap() - + governance_config.max_voting_time as i64 - + governance_config.min_transaction_hold_up_time as i64 - + 1; - - let vote_kind = VoteKind::Veto; - - // Act - let err = proposal - .assert_can_cast_vote(&vote_kind, &governance_config, current_timestamp) - .err() - .unwrap(); - - // Assert - assert_eq!(err, GovernanceError::ProposalVotingTimeExpired.into()); - } - #[test] pub fn test_assert_valid_vote_with_deny_vote_for_survey_only_proposal_error() { // Arrange @@ -2384,52 +2270,6 @@ mod test { assert_eq!(result, Err(GovernanceError::InvalidVote.into())); } - #[test] - pub fn test_assert_can_cast_veto_vote_for_succeeded_proposal_within_hold_up_time() { - // Arrange - let mut proposal = create_test_proposal(); - proposal.state = ProposalState::Succeeded; - - let governance_config = create_test_governance_config(); - - let current_timestamp = proposal.voting_completed_at.unwrap() - + governance_config.min_transaction_hold_up_time as i64; - - let vote_kind = VoteKind::Veto; - - // Act - let result = - proposal.assert_can_cast_vote(&vote_kind, &governance_config, current_timestamp); - - // Assert - assert_eq!(result, Ok(())); - } - - #[test] - pub fn test_assert_can_cast_veto_vote_for_succeeded_proposal_with_cannot_cast_after_hold_up_time_error( - ) { - // Arrange - let mut proposal = create_test_proposal(); - proposal.state = ProposalState::Succeeded; - - let governance_config = create_test_governance_config(); - - let current_timestamp = proposal.voting_completed_at.unwrap() - + governance_config.min_transaction_hold_up_time as i64 - + 1; - - let vote_kind = VoteKind::Veto; - - // Act - let err = proposal - .assert_can_cast_vote(&vote_kind, &governance_config, current_timestamp) - .err() - .unwrap(); - - // Assert - assert_eq!(err, GovernanceError::ProposalVotingTimeExpired.into()); - } - #[test] pub fn test_assert_valid_vote_with_too_many_options_error() { // Arrange diff --git a/governance/program/tests/process_finalize_vote.rs b/governance/program/tests/process_finalize_vote.rs index 9431e465..ae0aa37f 100644 --- a/governance/program/tests/process_finalize_vote.rs +++ b/governance/program/tests/process_finalize_vote.rs @@ -82,7 +82,7 @@ async fn test_finalize_vote_to_succeeded() { assert_eq!(proposal_account.state, ProposalState::Succeeded); assert_eq!( - Some(proposal_account.expected_vote_end_time(&governance_cookie.account.config)), + Some(proposal_account.vote_end_time(&governance_cookie.account.config)), proposal_account.voting_completed_at ); @@ -385,7 +385,7 @@ async fn test_finalize_council_vote() { assert_eq!(proposal_account.state, ProposalState::Succeeded); assert_eq!( - Some(proposal_account.expected_vote_end_time(&governance_cookie.account.config)), + Some(proposal_account.vote_end_time(&governance_cookie.account.config)), proposal_account.voting_completed_at ); diff --git a/governance/program/tests/use_veto_vote.rs b/governance/program/tests/use_veto_vote.rs index d23440ab..55b0d52b 100644 --- a/governance/program/tests/use_veto_vote.rs +++ b/governance/program/tests/use_veto_vote.rs @@ -968,66 +968,3 @@ async fn test_veto_vote_with_community_max_voter_weight_addin_and_veto_not_tippe assert_eq!(proposal_account.state, ProposalState::Voting); } - -#[tokio::test] -async fn test_cast_council_veto_vote_within_hold_up_time() { - // Arrange - let mut governance_test = GovernanceProgramTest::start_new().await; - - let realm_cookie = governance_test.with_realm().await; - let governed_account_cookie = governance_test.with_governed_account().await; - - let token_owner_record_cookie = governance_test - .with_council_token_deposit(&realm_cookie) - .await - .unwrap(); - - // Mint extra council tokens for total supply of 120 - governance_test.mint_council_tokens(&realm_cookie, 20).await; - - let mut governance_cookie = governance_test - .with_governance( - &realm_cookie, - &governed_account_cookie, - &token_owner_record_cookie, - ) - .await - .unwrap(); - - let proposal_owner_record_cookie = governance_test - .with_community_token_deposit(&realm_cookie) - .await - .unwrap(); - - let proposal_cookie = governance_test - .with_signed_off_proposal(&proposal_owner_record_cookie, &mut governance_cookie) - .await - .unwrap(); - - governance_test - .with_cast_yes_no_vote( - &proposal_cookie, - &proposal_owner_record_cookie, - YesNoVote::Yes, - ) - .await - .unwrap(); - - // Move the clock within the hold up time period - governance_test.advance_clock().await; - - // Act - - governance_test - .with_cast_vote(&proposal_cookie, &token_owner_record_cookie, Vote::Veto) - .await - .unwrap(); - - // Assert - - let proposal_account = governance_test - .get_proposal_account(&proposal_cookie.address) - .await; - - assert_eq!(proposal_account.state, ProposalState::Vetoed); -}