Skip to content

Commit

Permalink
fix(pallet-dao): expired proposal approval (#887)
Browse files Browse the repository at this point in the history
  • Loading branch information
renauter authored Nov 13, 2023
1 parent 1da1c15 commit faaf0c9
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 3 deletions.
9 changes: 6 additions & 3 deletions substrate-node/pallets/pallet-dao/src/dao.rs
Original file line number Diff line number Diff line change
Expand Up @@ -205,17 +205,20 @@ impl<T: Config> Pallet<T> {
let no_votes = voting.nays.len() as u32;
let yes_votes = voting.ayes.len() as u32;

let threshold_is_met = (no_votes + yes_votes) >= voting.threshold;
let proposal_is_expired = frame_system::Pallet::<T>::block_number() >= voting.end;

// Only allow actual closing of the proposal after the voting threshold is met or voting period has ended
ensure!(
(no_votes + yes_votes) >= voting.threshold
|| frame_system::Pallet::<T>::block_number() >= voting.end,
threshold_is_met || proposal_is_expired,
Error::<T>::OngoingVoteAndTresholdStillNotMet
);

let total_aye_weight: u64 = voting.ayes.iter().map(|y| y.weight).sum();
let total_naye_weight: u64 = voting.nays.iter().map(|y| y.weight).sum();

let approved = total_aye_weight > total_naye_weight;
// Only approve proposal if the voting threshold is met and simple majority (expressed in weight) is reached
let approved = threshold_is_met && (total_aye_weight > total_naye_weight);

if approved {
let proposal = Self::validate_and_get_proposal(&proposal_hash)?;
Expand Down
46 changes: 46 additions & 0 deletions substrate-node/pallets/pallet-dao/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,52 @@ fn close_after_proposal_duration_works() {
});
}

#[test]
fn close_after_proposal_duration_threshold_not_met_works() {
new_test_ext().execute_with(|| {
System::set_block_number(1);

let proposal = make_proposal(b"some_remark".to_vec());
let hash = BlakeTwo256::hash_of(&proposal);
let threshold = 2;

assert_ok!(DaoModule::propose(
RuntimeOrigin::signed(1),
threshold,
Box::new(proposal.clone()),
b"some_description".to_vec(),
b"some_link".to_vec(),
None
));
let proposal_index = 0;

// Farmer 1 votes yes
let farm_id = 1;
prepare_twin_farm_and_node(10, b"farm1".to_vec(), farm_id);
assert_ok!(DaoModule::vote(
RuntimeOrigin::signed(10),
farm_id,
hash.clone(),
true
));

System::set_block_number(5); // default duration is 4 blocks
assert_ok!(DaoModule::close(
RuntimeOrigin::signed(2),
hash.clone(),
proposal_index
));

let e = System::events();
assert_eq!(
e[6],
record(MockEvent::DaoModule(DaoEvent::Disapproved {
proposal_hash: hash,
}))
);
});
}

#[test]
fn close_if_not_council_member_fails() {
new_test_ext().execute_with(|| {
Expand Down

0 comments on commit faaf0c9

Please sign in to comment.