Skip to content

Commit

Permalink
Allow describing proposals on-chain (#36)
Browse files Browse the repository at this point in the history
* Allow describing proposals on-chain

* add some unit tests
  • Loading branch information
moodysalem authored Apr 12, 2024
1 parent 264e811 commit d47c7f3
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 7 deletions.
8 changes: 4 additions & 4 deletions src/airdrop_claim_check.cairo
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use starknet::{ContractAddress};
use governance::airdrop::{IAirdropDispatcher};
use starknet::{ContractAddress};

#[derive(Serde, Copy, Drop)]
struct CheckParams {
Expand All @@ -21,11 +21,11 @@ trait IAirdropClaimCheck<TContractState> {

#[starknet::contract]
mod AirdropClaimCheck {
use super::{IAirdropClaimCheck, IAirdropDispatcher, CheckParams, CheckResult};
use governance::airdrop::{IAirdropDispatcherTrait};
use governance::interfaces::erc20::{IERC20Dispatcher, IERC20DispatcherTrait};
use core::array::{SpanTrait};
use core::option::{OptionTrait};
use governance::airdrop::{IAirdropDispatcherTrait};
use governance::interfaces::erc20::{IERC20Dispatcher, IERC20DispatcherTrait};
use super::{IAirdropClaimCheck, IAirdropDispatcher, CheckParams, CheckResult};

#[storage]
struct Storage {}
Expand Down
22 changes: 21 additions & 1 deletion src/governor.cairo
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use core::array::{Array};
use core::byte_array::{ByteArray};
use core::integer::{u128_safe_divmod};
use core::option::{Option, OptionTrait};
use core::traits::{Into, TryInto};
Expand Down Expand Up @@ -49,6 +50,9 @@ pub trait IGovernor<TContractState> {
// Execute the given proposal.
fn execute(ref self: TContractState, call: Call) -> Span<felt252>;

// Attaches the given text to the proposal. Simply emits an event containing the proposal description.
fn describe(ref self: TContractState, id: felt252, description: ByteArray);

// Get the configuration for this governor contract.
fn get_staker(self: @TContractState) -> IStakerDispatcher;

Expand All @@ -68,7 +72,7 @@ pub mod Governor {
use starknet::{get_block_timestamp, get_caller_address, contract_address_const};
use super::{
IStakerDispatcher, ContractAddress, Array, IGovernor, Config, ProposalInfo, Call,
ExecutionState
ExecutionState, ByteArray
};


Expand All @@ -79,6 +83,12 @@ pub mod Governor {
pub call: Call,
}

#[derive(starknet::Event, Drop, Debug, PartialEq)]
pub struct Described {
pub id: felt252,
pub description: ByteArray,
}

#[derive(starknet::Event, Drop)]
pub struct Voted {
pub id: felt252,
Expand All @@ -101,6 +111,7 @@ pub mod Governor {
#[event]
enum Event {
Proposed: Proposed,
Described: Described,
Voted: Voted,
Canceled: Canceled,
Executed: Executed,
Expand Down Expand Up @@ -183,6 +194,15 @@ pub mod Governor {
id
}

fn describe(ref self: ContractState, id: felt252, description: ByteArray) {
let proposal = self.proposals.read(id);
assert(proposal.proposer.is_non_zero(), 'DOES_NOT_EXIST');
assert(proposal.proposer == get_caller_address(), 'NOT_PROPOSER');
assert(proposal.execution_state.executed.is_zero(), 'ALREADY_EXECUTED');
assert(proposal.execution_state.canceled.is_zero(), 'PROPOSAL_CANCELED');
self.emit(Described { id, description });
}

fn vote(ref self: ContractState, id: felt252, yea: bool) {
let mut proposal = self.proposals.read(id);

Expand Down
49 changes: 48 additions & 1 deletion src/governor_test.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ use governance::timelock_test::{single_call, transfer_call, deploy as deploy_tim
use starknet::account::{Call};
use starknet::{
get_contract_address, syscalls::deploy_syscall, ClassHash, contract_address_const,
ContractAddress, get_block_timestamp, testing::{set_block_timestamp, set_contract_address}
ContractAddress, get_block_timestamp,
testing::{set_block_timestamp, set_contract_address, pop_log}
};


Expand Down Expand Up @@ -250,6 +251,52 @@ fn test_anyone_can_vote() {
assert_eq!(proposal.nay, 0);
}

#[test]
fn test_describe_proposal_successful() {
let (staker, token, governor, _config) = setup();
let id = create_proposal(governor, token, staker);

set_contract_address(proposer());
governor
.describe(
id,
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
);
pop_log::<Governor::Proposed>(governor.contract_address).unwrap();
assert_eq!(
pop_log::<Governor::Described>(governor.contract_address).unwrap(),
Governor::Described {
id,
description: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
}
);
}

#[test]
#[should_panic(expected: ('NOT_PROPOSER', 'ENTRYPOINT_FAILED'))]
fn test_describe_proposal_fails_for_unknown_proposal() {
let (staker, token, governor, _config) = setup();
let id = create_proposal(governor, token, staker);
governor.describe(id, "I am not the proposer");
}

#[test]
#[should_panic(expected: ('PROPOSAL_CANCELED', 'ENTRYPOINT_FAILED'))]
fn test_describe_proposal_fails_if_canceled() {
let (staker, token, governor, _config) = setup();
let id = create_proposal(governor, token, staker);
set_contract_address(proposer());
governor.cancel(id);
governor.describe(id, "This proposal is canceled");
}

#[test]
#[should_panic(expected: ('DOES_NOT_EXIST', 'ENTRYPOINT_FAILED'))]
fn test_describe_proposal_fails_if_not_proposer() {
let (_staker, _token, governor, _config) = setup();
governor.describe(123, "This proposal does not exist");
}

#[test]
fn test_vote_no_staking_after_period_starts() {
let (staker, token, governor, config) = setup();
Expand Down
2 changes: 1 addition & 1 deletion src/lib.cairo
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
mod airdrop_claim_check;
pub mod airdrop;
mod airdrop_claim_check;

#[cfg(test)]
pub(crate) mod airdrop_test;
Expand Down

0 comments on commit d47c7f3

Please sign in to comment.