Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: enhanced process_result proposal call #491

Merged
merged 5 commits into from
Feb 16, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 42 additions & 19 deletions onchain/cairo/afk/src/dao/dao_aa.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,14 @@ pub mod DaoAA {
MIN_TRANSACTION_VERSION, QUERY_OFFSET, execute_calls // is_valid_stark_signature
};
use core::ecdsa::check_ecdsa_signature;
use core::hash::{HashStateExTrait, HashStateTrait};
use core::num::traits::Zero;
use core::poseidon::{PoseidonTrait, poseidon_hash_span};
use openzeppelin::access::accesscontrol::AccessControlComponent;
use openzeppelin::governance::timelock::TimelockControllerComponent;
use openzeppelin::introspection::src5::SRC5Component;
use openzeppelin::upgrades::upgradeable::UpgradeableComponent;
use openzeppelin::utils::cryptography::snip12::StructHash;
use starknet::account::Call;

use starknet::storage::{
Expand Down Expand Up @@ -104,16 +107,15 @@ pub mod DaoAA {
proposals_calldata: Map<u256, Calldata>, // Map ProposalID => calldata
proposal_by_user: Map<ContractAddress, u256>,
total_proposal: u256,
executable_tx: Map<felt252, bool>, // Map Hashed Call => executable
proposal_tx: Map<
u256, felt252
>, // Map Proposal ID => Hashed Call (for one call, multicall excluded)
vote_state_by_proposal: Map<u256, VoteState>, // Map ProposalID => VoteState
// vote_by_proposal: Map<u256, Proposal>,
tx_data_per_proposal: Map<u256, Span<felt252>>, //
starknet_address: felt252,
proposals_call_external:Map<u256, Vec<Call>>, // Map ProposalID => calldata

tx_to_execute: Map<u256, Span<felt252>>, // Map ProposalID => TX to execute
tx_executed: Map<u256, Span<felt252>>, // Map ProposalID => TX to execute
tx_call_to_execute: Map<u256, Span<Call>>, // Map ProposalID => TX to execute
tx_call_executed: Map<u256, Span<Call>>, // Map ProposalID => TX to execute
executables_count: u64,
// votes_by_proposal: Map<u256, u256>, // Maps proposal ID to vote count
// here
// user_votes: Map<
Expand Down Expand Up @@ -229,17 +231,21 @@ pub mod DaoAA {
proposal_result_by: contract_address_const::<0x0>(),
};

// check
self.proposals.entry(id).write(Option::Some(proposal));

let proposal_calldata = self.proposals_calldata.entry(id);

proposal_calldata.to.write(calldata.to);
proposal_calldata.selector.write(calldata.selector);
proposal_calldata.is_executed.write(false);

for data in calldata.calldata {
proposal_calldata.calldata.append().write(*data);
};
// end check.

self.proposal_tx.entry(id).write(calldata.hash_struct());
self.total_proposal.write(id);
self.emit(ProposalCreated { id, owner, created_at, end_at });

Expand Down Expand Up @@ -386,20 +392,12 @@ pub mod DaoAA {
let total_votes = yes_votes + no_votes;
let valid_threshold_percentage = yes_votes * 100 / total_votes;

let executables_count = self.executables_count.read();
if valid_threshold_percentage >= self.minimum_threshold_percentage.read() {
proposal.proposal_result = ProposalResult::Passed;
// let proposal_calldata = self.proposals_calldata.entry(proposal_id);

// let tx_to_execute = self.tx_to_execute.read(proposal_id);
// for i in 0
// ..proposal_calldata
// .len() {
// let data = *calldata.at(i);
// tx_to_execute.append().write(data);
// };
// tx_call_to_execute: Map<u256, Span<Call>>, // Map ProposalID => TX to execute


let proposal_tx = self.proposal_tx.entry(proposal_id).read();
self.executable_tx.entry(proposal_tx).write(true);
self.executables_count.write(executables_count + 1);
} else {
proposal.proposal_result = ProposalResult::Failed;
}
Expand All @@ -412,6 +410,22 @@ pub mod DaoAA {
);
self.proposals.entry(proposal_id).write(Option::Some(proposal));
}

fn is_executable(ref self: ContractState, calldata: Call) -> bool {
self.executable_tx.entry(calldata.hash_struct()).read()
}
}

pub impl CallStructHash of StructHash<Call> {
fn hash_struct(self: @Call) -> felt252 {
let hash_state = PoseidonTrait::new();
hash_state
.update_with('AFK_DAO')
.update_with(*self.to)
.update_with(*self.selector)
.update_with(poseidon_hash_span(*self.calldata))
.finalize()
}
}

#[abi(embed_v0)]
Expand Down Expand Up @@ -617,7 +631,9 @@ mod tests {
calldata: array!['data 1', 'data 2'].span()
};
// created by 'CREATOR'
proposal_dispatcher.create_proposal(proposal_params, calldata)
let proposal_id = proposal_dispatcher.create_proposal(proposal_params, calldata);
assert(!proposal_dispatcher.is_executable(calldata), '');
proposal_id
}

/// TESTS
Expand Down Expand Up @@ -843,5 +859,12 @@ mod tests {
);

spy.assert_emitted(@array![(proposal_contract, expected_event)]);
let calldata = Call {
to: contract_address_const::<'TO'>(),
selector: 'selector',
calldata: array!['data 1', 'data 2'].span()
};
// the creating call should be executable
assert(proposal_dispatcher.is_executable(calldata), 'NOT EXECUTABLE');
}
}
4 changes: 3 additions & 1 deletion onchain/cairo/afk/src/interfaces/voting.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ pub struct Calldata {
pub to: ContractAddress,
pub selector: felt252,
pub calldata: Vec<felt252>,
pub is_executed: bool
pub is_executed: bool,
}

// #[derive(Drop, Serde, Copy, starknet::Store, PartialEq)]
Expand Down Expand Up @@ -181,6 +181,8 @@ pub trait IVoteProposal<TContractState> {
fn get_user_vote(self: @TContractState, proposal_id: u256, user: ContractAddress) -> UserVote;
fn cancel_proposal(ref self: TContractState, proposal_id: u256);
fn process_result(ref self: TContractState, proposal_id: u256);
// debugging
fn is_executable(ref self: TContractState, calldata: Call) -> bool;
}
// Possible extracted Proposal Functions
// Mint the token with a specific ratio
Expand Down
Loading