Skip to content

Commit

Permalink
fix: quorum applies to yea votes, not yea+nay
Browse files Browse the repository at this point in the history
this is required so a user is never incentivized _not_ to vote against a proposal they oppose, so that a proposal does not reach quorum
  • Loading branch information
moodysalem committed May 6, 2024
1 parent 326f0ba commit cbfb083
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 7 deletions.
2 changes: 1 addition & 1 deletion src/governor.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -364,7 +364,7 @@ pub mod Governor {
let window_end = window_start + config.execution_window;
assert(timestamp_current < window_end, 'EXECUTION_WINDOW_OVER');

assert((proposal.yea + proposal.nay) >= config.quorum, 'QUORUM_NOT_MET');
assert(proposal.yea >= config.quorum, 'QUORUM_NOT_MET');
assert(proposal.yea >= proposal.nay, 'NO_MAJORITY');

proposal
Expand Down
61 changes: 55 additions & 6 deletions src/governor_test.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ fn deploy(staker: IStakerDispatcher, config: Config) -> IGovernorDispatcher {
}

fn setup() -> (IStakerDispatcher, IERC20Dispatcher, IGovernorDispatcher, Config) {
let (staker, token) = setup_staker(1000);
let (staker, token) = setup_staker(1000000);
let config = Config {
voting_start_delay: 86400,
voting_period: 604800,
Expand Down Expand Up @@ -668,9 +668,9 @@ fn test_execute_quorum_not_met_should_fail() {
fn test_execute_no_majority_should_fail() {
let (staker, token, governor, config) = setup();

token.approve(staker.contract_address, 499);
token.approve(staker.contract_address, config.quorum.into());
staker.stake(voter1());
token.approve(staker.contract_address, 501);
token.approve(staker.contract_address, (config.quorum + 1).into());
staker.stake(voter2());

// now voter2 has enough weighted voting power to propose
Expand All @@ -686,14 +686,14 @@ fn test_execute_no_majority_should_fail() {
set_contract_address(voter1());
governor.vote(id, true);
let proposal = governor.get_proposal(id);
assert_eq!(proposal.yea, 499);
assert_eq!(proposal.yea, config.quorum);
assert_eq!(proposal.nay, 0);

set_contract_address(voter2());
governor.vote(id, false);
let proposal = governor.get_proposal(id);
assert_eq!(proposal.yea, 499);
assert_eq!(proposal.nay, 501);
assert_eq!(proposal.yea, config.quorum);
assert_eq!(proposal.nay, config.quorum + 1);

advance_time(config.voting_period + config.execution_delay);

Expand All @@ -704,6 +704,55 @@ fn test_execute_no_majority_should_fail() {
);
}

#[test]
#[should_panic(expected: ('EXECUTION_WINDOW_NOT_STARTED', 'ENTRYPOINT_FAILED'))]
fn test_execute_before_execution_window_begins() {
let (staker, token, governor, config) = setup();

token.approve(staker.contract_address, config.quorum.into());
staker.stake(voter1());

// now voter2 has enough weighted voting power to propose
advance_time(config.voting_weight_smoothing_duration);

set_contract_address(voter1());
let id = governor
.propose(array![transfer_call(token: token, recipient: recipient(), amount: 100)].span());
advance_time(config.voting_start_delay);
governor.vote(id, true);

advance_time(config.voting_period);
governor
.execute(
id, array![transfer_call(token: token, recipient: recipient(), amount: 100)].span()
);
}


#[test]
#[should_panic(expected: ('EXECUTION_WINDOW_OVER', 'ENTRYPOINT_FAILED'))]
fn test_execute_after_execution_window_ends() {
let (staker, token, governor, config) = setup();

token.approve(staker.contract_address, config.quorum.into());
staker.stake(voter1());

// now voter2 has enough weighted voting power to propose
advance_time(config.voting_weight_smoothing_duration);

set_contract_address(voter1());
let id = governor
.propose(array![transfer_call(token: token, recipient: recipient(), amount: 100)].span());
advance_time(config.voting_start_delay);
governor.vote(id, true);

advance_time(config.voting_period + config.execution_delay + config.execution_window);
governor
.execute(
id, array![transfer_call(token: token, recipient: recipient(), amount: 100)].span()
);
}

#[test]
#[should_panic(expected: ('QUORUM_NOT_MET', 'ENTRYPOINT_FAILED'))]
fn test_verify_votes_are_counted_over_voting_weight_smoothing_duration_from_start() {
Expand Down

0 comments on commit cbfb083

Please sign in to comment.