Skip to content
This repository was archived by the owner on Mar 11, 2025. It is now read-only.

Commit a6bd22f

Browse files
authored
Governance: Do not allow relinquishing votes in Finalising state (#3210)
* fix: Do not allow relinquishing votes in Finalising state * chore: rename voting to finalising state * chore: update comments * chore: revert Anchor version
1 parent f7abf4a commit a6bd22f

File tree

3 files changed

+20
-25
lines changed

3 files changed

+20
-25
lines changed

governance/program/src/error.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -401,6 +401,10 @@ pub enum GovernanceError {
401401
/// Reserved buffer must be empty
402402
#[error("Reserved buffer must be empty")]
403403
ReservedBufferMustBeEmpty,
404+
405+
/// Cannot Relinquish in Finalizing state
406+
#[error("Cannot Relinquish in Finalizing state")]
407+
CannotRelinquishInFinalizingState,
404408
}
405409

406410
impl PrintProgramError for GovernanceError {

governance/program/src/processor/process_relinquish_vote.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ pub fn process_relinquish_vote(program_id: &Pubkey, accounts: &[AccountInfo]) ->
6666

6767
// If the Proposal is still being voted on then the token owner vote will be withdrawn and it won't count towards the vote outcome
6868
// Note: If there is no tipping point the proposal can be still in Voting state but already past the configured max_voting_time
69-
// It means it awaits manual finalization (FinalizeVote) and it should no longer be possible to withdraw the vote and we only release the tokens
69+
// It means it awaits manual finalization (FinalizeVote) and it should no longer be possible to withdraw the vote
7070
if proposal_data.state == ProposalState::Voting
7171
&& !proposal_data.has_vote_time_ended(&governance_data.config, clock.unix_timestamp)
7272
{
@@ -116,6 +116,13 @@ pub fn process_relinquish_vote(program_id: &Pubkey, accounts: &[AccountInfo]) ->
116116
.checked_sub(1)
117117
.unwrap();
118118
} else {
119+
// After Proposal voting time ends and it's not tipped then it enters implicit (time based) Finalizing state
120+
// and releasing tokens in this state should be disallowed
121+
// In other words releasing tokens is only possible once Proposal is manually finalized using FinalizeVote
122+
if proposal_data.state == ProposalState::Voting {
123+
return Err(GovernanceError::CannotRelinquishInFinalizingState.into());
124+
}
125+
119126
vote_record_data.is_relinquished = true;
120127
vote_record_data.serialize(&mut *vote_record_info.data.borrow_mut())?;
121128
}

governance/program/tests/process_relinquish_vote.rs

Lines changed: 8 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -447,7 +447,7 @@ async fn test_relinquish_vote_with_already_relinquished_error() {
447447
}
448448

449449
#[tokio::test]
450-
async fn test_relinquish_proposal_in_voting_state_after_vote_time_ended() {
450+
async fn test_relinquish_proposal_with_cannot_relinquish_in_finalizing_state_error() {
451451
// Arrange
452452
let mut governance_test = GovernanceProgramTest::start_new().await;
453453

@@ -481,7 +481,7 @@ async fn test_relinquish_proposal_in_voting_state_after_vote_time_ended() {
481481

482482
let clock = governance_test.bench.get_clock().await;
483483

484-
let mut vote_record_cookie = governance_test
484+
governance_test
485485
.with_cast_yes_no_vote(&proposal_cookie, &token_owner_record_cookie, YesNoVote::Yes)
486486
.await
487487
.unwrap();
@@ -494,32 +494,16 @@ async fn test_relinquish_proposal_in_voting_state_after_vote_time_ended() {
494494
.await;
495495

496496
// Act
497-
governance_test
497+
let err = governance_test
498498
.relinquish_vote(&proposal_cookie, &token_owner_record_cookie)
499499
.await
500+
.err()
500501
.unwrap();
501502

502503
// Assert
503504

504-
let proposal_account = governance_test
505-
.get_proposal_account(&proposal_cookie.address)
506-
.await;
507-
508-
// Proposal should be still in voting state but the vote count should not change
509-
assert_eq!(100, proposal_account.options[0].vote_weight);
510-
assert_eq!(ProposalState::Voting, proposal_account.state);
511-
512-
let token_owner_record = governance_test
513-
.get_token_owner_record_account(&token_owner_record_cookie.address)
514-
.await;
515-
516-
assert_eq!(0, token_owner_record.unrelinquished_votes_count);
517-
assert_eq!(1, token_owner_record.total_votes_count);
518-
519-
let vote_record_account = governance_test
520-
.get_vote_record_account(&vote_record_cookie.address)
521-
.await;
522-
523-
vote_record_cookie.account.is_relinquished = true;
524-
assert_eq!(vote_record_cookie.account, vote_record_account);
505+
assert_eq!(
506+
err,
507+
GovernanceError::CannotRelinquishInFinalizingState.into()
508+
);
525509
}

0 commit comments

Comments
 (0)