Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
tensojka committed Nov 17, 2023
1 parent ca98b7f commit df308f8
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 153 deletions.
11 changes: 8 additions & 3 deletions src/airdrop.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@ use starknet::ContractAddress;
#[starknet::interface]
trait IAirdrop<TContractState> {
fn claim(ref self: TContractState, claimee: ContractAddress, amount: u128, proof: Array::<felt252>);
fn set_root(ref self: TContractState, merkle_root: felt252);
}

#[starknet::component]
mod airdrop {
use array::ArrayTrait;
use governance::contract::IGovernance;
use array::ArrayTrait;
use hash::LegacyHash;
use traits::Into;
use starknet::ContractAddressIntoFelt252;
Expand All @@ -25,7 +27,6 @@ mod airdrop {
use governance::contract::Governance::ContractState;
use governance::traits::IGovernanceTokenDispatcher;
use governance::traits::IGovernanceTokenDispatcherTrait;
use governance::contract::Governance::governance_token_address;

#[storage]
struct Storage {
Expand Down Expand Up @@ -63,7 +64,7 @@ mod airdrop {
let to_mint = amount - claimed_so_far;

// Mint
let govtoken_addr = state.governance_token_address.read(); // TODO solve – can't expose this as fn param due to it being public, can't access state. Prob just do this via another function and have this be non-public?
let govtoken_addr = state.get_governance_token_address();
IGovernanceTokenDispatcher {
contract_address: govtoken_addr
}.mint(claimee, u256 { high: 0, low: to_mint });
Expand All @@ -74,5 +75,9 @@ mod airdrop {
// Emit event
self.emit(Claimed { address: claimee, received: to_mint });
}

fn set_root(ref self: ComponentState<TContractState>, merkle_root: felt252) {
self.merkle_root.write(merkle_root);
}
}
}
12 changes: 3 additions & 9 deletions src/options.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ mod Options {
// TODO use block hash from block_hash syscall as salt // actually doable with the new syscall
let governance_address = get_contract_address();
let state = Governance::unsafe_new_contract_state();
let amm_address = amm_address::InternalContractStateTrait::read(@state.amm_address);
let amm_address = state.amm_address.read();
let proxy_class: felt252 =
0x00eafb0413e759430def79539db681f8a4eb98cf4196fe457077d694c6aeeb82;
let opt_class: felt252 = 0x5ce3a80daeb5b7a766df9b41ca8d9e52b6b0a045a0d2ced72f43d4dd2f93b10;
Expand Down Expand Up @@ -214,14 +214,8 @@ mod Options {
fn run_add_0911_1611_options() {
let mut state = Governance::unsafe_new_contract_state();
assert(
!proposal_initializer_run::InternalContractStateTrait::read(
@state.proposal_initializer_run, 36
),
'prop36 initializer called again'
);
proposal_initializer_run::InternalContractStateTrait::write(
ref state.proposal_initializer_run, 36, true
);
!read.@state.proposal_initializer_run;
state.proposal_initializer_run.write(36, true);

add_0911_options();
add_1611_options();
Expand Down
166 changes: 40 additions & 126 deletions src/proposals.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -45,29 +45,18 @@ mod Proposals {
fn get_vote_counts(prop_id: felt252) -> (u128, u128) {
let state: ContractState = Governance::unsafe_new_contract_state();

let yay = proposal_total_yay::InternalContractStateTrait::read(
@state.proposal_total_yay, prop_id
let yay = state.proposal_total_yay.read(prop_id
);
let nay = proposal_total_nay::InternalContractStateTrait::read(
@state.proposal_total_nay, prop_id
let nay = state.proposal_total_nay.read(prop_id
);

(yay.try_into().unwrap(), nay.try_into().unwrap())
}

fn get_proposal_details(prop_id: felt252) -> PropDetails {
let state = Governance::unsafe_new_contract_state();
proposal_details::InternalContractStateTrait::read(@state.proposal_details, prop_id)
}

fn get_free_prop_id() -> felt252 {
_get_free_prop_id(0)
}

fn _get_free_prop_id(currid: felt252) -> felt252 {
let state = Governance::unsafe_new_contract_state();
let res = proposal_vote_ends::InternalContractStateTrait::read(
@state.proposal_vote_ends, currid
read.@state.proposal_details;
let res = state.proposal_vote_ends.read(currid
);

if res == 0 {
Expand All @@ -84,8 +73,7 @@ mod Proposals {

fn assert_voting_in_progress(prop_id: felt252) {
let state = Governance::unsafe_new_contract_state();
let end_block_number_felt: felt252 = proposal_vote_ends::InternalContractStateTrait::read(
@state.proposal_vote_ends, prop_id
let end_block_number_felt: felt252 = state.proposal_vote_ends.read(prop_id
);
let end_block_number: u64 = end_block_number_felt.try_into().unwrap();
assert(end_block_number != 0, 'prop_id not found');
Expand All @@ -102,9 +90,7 @@ mod Proposals {
fn submit_proposal(payload: felt252, to_upgrade: ContractType) -> felt252 {
assert_correct_contract_type(to_upgrade);
let mut state = Governance::unsafe_new_contract_state();
let govtoken_addr = governance_token_address::InternalContractStateTrait::read(
@state.governance_token_address
);
let govtoken_addr = state.governance_token_address.read();
let caller = get_caller_address();
let caller_balance: u128 = IERC20Dispatcher {
contract_address: govtoken_addr
Expand All @@ -117,17 +103,13 @@ mod Proposals {

let prop_id = get_free_prop_id();
let prop_details = PropDetails { payload: payload, to_upgrade: to_upgrade };
proposal_details::InternalContractStateTrait::write(
ref state.proposal_details, prop_id, prop_details
);
state.proposal_details.write(prop_id, prop_details);

let current_block_number: u64 = get_block_info().unbox().block_number;
let end_block_number: BlockNumber = (current_block_number
+ constants::PROPOSAL_VOTING_TIME_BLOCKS)
.into();
proposal_vote_ends::InternalContractStateTrait::write(
ref state.proposal_vote_ends, prop_id, end_block_number
);
state.proposal_vote_ends.write(prop_id, end_block_number);

state.emit(Governance::Proposed { prop_id, payload, to_upgrade });
prop_id
Expand Down Expand Up @@ -190,20 +172,16 @@ mod Proposals {
let mut state = Governance::unsafe_new_contract_state();

let caller_addr = get_caller_address();
let stored_hash = delegate_hash::InternalContractStateTrait::read(
@state.delegate_hash, caller_addr
let stored_hash = state.delegate_hash.read(caller_addr
);
let calldata_span: Span<(ContractAddress, u128)> = calldata.span();
assert(stored_hash == hashing(0, calldata_span, 0), 'incorrect delegate list');

let curr_total_delegated_to = total_delegated_to::InternalContractStateTrait::read(
@state.total_delegated_to, to_addr
let curr_total_delegated_to = state.total_delegated_to.read(to_addr
);
let converted_addr = contract_address_to_felt252(caller_addr);

let gov_token_addr = governance_token_address::InternalContractStateTrait::read(
@state.governance_token_address
);
let gov_token_addr = state.governance_token_address.read();
let caller_balance_u256: u256 = IERC20Dispatcher {
contract_address: gov_token_addr
}.balanceOf(caller_addr);
Expand All @@ -219,21 +197,16 @@ mod Proposals {

update_calldata(to_addr, already_delegated + amount, calldata_span, updated_list, 0);

delegate_hash::InternalContractStateTrait::write(
ref state.delegate_hash, caller_addr, hashing(0, updated_list_span, 0)
);
total_delegated_to::InternalContractStateTrait::write(
ref state.total_delegated_to, to_addr, curr_total_delegated_to + amount
);
state.delegate_hash.write(caller_addr, hashing(0, updated_list_span, 0));
state.total_delegated_to.write(to_addr, curr_total_delegated_to + amount);
}

fn withdraw_delegation(
to_addr: ContractAddress, calldata: Array<(ContractAddress, u128)>, amount: u128
) {
let mut state = Governance::unsafe_new_contract_state();
let caller_addr = get_caller_address();
let stored_hash = delegate_hash::InternalContractStateTrait::read(
@state.delegate_hash, caller_addr
let stored_hash = state.delegate_hash.read(caller_addr
);
let calldata_span: Span<(ContractAddress, u128)> = calldata.span();
assert(stored_hash == hashing(0, calldata_span, 0), 'incorrect delegate list');
Expand All @@ -246,16 +219,11 @@ mod Proposals {
let minus_amount = 0 - amount;
update_calldata(to_addr, minus_amount, calldata_span, updated_list, 0);

delegate_hash::InternalContractStateTrait::write(
ref state.delegate_hash, caller_addr, hashing(0, updated_list_span, 0)
);
state.delegate_hash.write(caller_addr, hashing(0, updated_list_span, 0));

let curr_total_delegated_to = total_delegated_to::InternalContractStateTrait::read(
@state.total_delegated_to, to_addr
);
total_delegated_to::InternalContractStateTrait::write(
ref state.total_delegated_to, to_addr, curr_total_delegated_to - amount
let curr_total_delegated_to = state.total_delegated_to.read(to_addr
);
state.total_delegated_to.write(to_addr, curr_total_delegated_to - amount);
}


Expand All @@ -271,13 +239,9 @@ mod Proposals {

let mut state = Governance::unsafe_new_contract_state();

let gov_token_addr = governance_token_address::InternalContractStateTrait::read(
@state.governance_token_address
);
let gov_token_addr = state.governance_token_address.read();
let caller_addr = get_caller_address();
let curr_vote_status: felt252 = proposal_voted_by::InternalContractStateTrait::read(
@state.proposal_voted_by, (prop_id, caller_addr)
);
let curr_vote_status: felt252 = read.@state.proposal_voted_by;
assert(curr_vote_status == 0, 'already voted');

let caller_balance_u256: u256 = IERC20Dispatcher {
Expand All @@ -288,52 +252,34 @@ mod Proposals {
assert(caller_balance != 0, 'CARM balance is zero');

let caller_voting_power = caller_balance
+ total_delegated_to::InternalContractStateTrait::read(
@state.total_delegated_to, caller_addr
+ state.total_delegated_to.read(caller_addr
);

assert(caller_voting_power > 0, 'No voting power');

assert_voting_in_progress(prop_id);

// Cast vote
proposal_voted_by::InternalContractStateTrait::write(
ref state.proposal_voted_by, (prop_id, caller_addr), actual_opinion
);
state.proposal_voted_by.write((prop_id, caller_addr), actual_opinion);
if actual_opinion == constants::MINUS_ONE {
let curr_votes: u128 = proposal_total_nay::InternalContractStateTrait::read(
@state.proposal_total_nay, prop_id
)
.try_into()
.unwrap();
let curr_votes: u128 = read.@state.proposal_total_nay;
let new_votes: u128 = curr_votes + caller_voting_power;
assert(new_votes >= 0, 'new_votes must be non-negative');
proposal_total_nay::InternalContractStateTrait::write(
ref state.proposal_total_nay, prop_id, new_votes.into()
);
state.proposal_total_nay.write(prop_id, new_votes.into());
} else {
let curr_votes: u128 = proposal_total_yay::InternalContractStateTrait::read(
@state.proposal_total_yay, prop_id
)
.try_into()
.unwrap();
let curr_votes: u128 = read.@state.proposal_total_yay;
let new_votes: u128 = curr_votes + caller_voting_power;
assert(new_votes >= 0, 'new_votes must be non-negative');
proposal_total_yay::InternalContractStateTrait::write(
ref state.proposal_total_yay, prop_id, new_votes.into()
);
state.proposal_total_yay.write(prop_id, new_votes.into());
}
state.emit(Governance::Voted { prop_id: prop_id, voter: caller_addr, opinion: opinion });
}


fn check_proposal_passed_express(prop_id: felt252) -> u8 {
let state = Governance::unsafe_new_contract_state();
let gov_token_addr = governance_token_address::InternalContractStateTrait::read(
@state.governance_token_address
);
let yay_tally_felt: felt252 = proposal_total_yay::InternalContractStateTrait::read(
@state.proposal_total_yay, prop_id
let gov_token_addr = state.governance_token_address.read();
let yay_tally_felt: felt252 = state.proposal_total_yay.read(prop_id
);
let yay_tally: u128 = yay_tally_felt.try_into().unwrap();
let total_eligible_votes_from_tokenholders_u256: u256 = IERC20Dispatcher {
Expand Down Expand Up @@ -363,8 +309,7 @@ mod Proposals {
fn get_proposal_status(prop_id: felt252) -> felt252 {
let state = Governance::unsafe_new_contract_state();

let end_block_number_felt: felt252 = proposal_vote_ends::InternalContractStateTrait::read(
@state.proposal_vote_ends, prop_id
let end_block_number_felt: felt252 = state.proposal_vote_ends.read(prop_id
);
let end_block_number: u64 = end_block_number_felt.try_into().unwrap();
let current_block_number: u64 = get_block_info().unbox().block_number;
Expand All @@ -373,14 +318,10 @@ mod Proposals {
return check_proposal_passed_express(prop_id).into();
}

let gov_token_addr = governance_token_address::InternalContractStateTrait::read(
@state.governance_token_address
let gov_token_addr = state.governance_token_address.read();
let nay_tally_felt: felt252 = state.proposal_total_nay.read(prop_id
);
let nay_tally_felt: felt252 = proposal_total_nay::InternalContractStateTrait::read(
@state.proposal_total_nay, prop_id
);
let yay_tally_felt: felt252 = proposal_total_yay::InternalContractStateTrait::read(
@state.proposal_total_yay, prop_id
let yay_tally_felt: felt252 = state.proposal_total_yay.read(prop_id
);
let nay_tally: u128 = nay_tally_felt.try_into().unwrap();
let yay_tally: u128 = yay_tally_felt.try_into().unwrap();
Expand Down Expand Up @@ -421,67 +362,40 @@ mod Proposals {
let mut state = Governance::unsafe_new_contract_state();

let caller_addr = get_caller_address();
let investor_voting_power: u128 = investor_voting_power::InternalContractStateTrait::read(
@state.investor_voting_power, caller_addr
)
.try_into()
.unwrap();
let investor_voting_power: u128 = read.@state.investor_voting_power;
assert(investor_voting_power != 0, 'caller not whitelisted investor');

let curr_vote_status: felt252 = proposal_voted_by::InternalContractStateTrait::read(
@state.proposal_voted_by, (prop_id, caller_addr)
);
let curr_vote_status: felt252 = read.@state.proposal_voted_by;
assert(curr_vote_status == 0, 'already voted');

assert_voting_in_progress(prop_id);

// Calculate real voting power
let gov_token_addr = governance_token_address::InternalContractStateTrait::read(
@state.governance_token_address
);
let gov_token_addr = state.governance_token_address.read();
let total_supply_u256: u256 = IERC20Dispatcher {
contract_address: gov_token_addr
}.totalSupply();
assert(total_supply_u256.high == 0, 'totalSupply weirdly high');
let total_supply: u128 = total_supply_u256.low;
let real_investor_voting_power: u128 = total_supply - constants::TEAM_TOKEN_BALANCE;
assert(total_supply >= constants::TEAM_TOKEN_BALANCE, 'total_supply<team token bal?');
let total_distributed_power: u128 =
total_investor_distributed_power::InternalContractStateTrait::read(
@state.total_investor_distributed_power
)
.try_into()
.unwrap();
let total_distributed_power: u128 = state.total_investor_distributed_power.read();
let vote_power = (real_investor_voting_power * investor_voting_power)
/ total_distributed_power;
assert(vote_power != 0, 'vote_power is zero');

// Cast vote
proposal_voted_by::InternalContractStateTrait::write(
ref state.proposal_voted_by, (prop_id, caller_addr), opinion
);
state.proposal_voted_by.write((prop_id, caller_addr), opinion);
if opinion == constants::MINUS_ONE {
let curr_votes: u128 = proposal_total_nay::InternalContractStateTrait::read(
@state.proposal_total_nay, prop_id
)
.try_into()
.unwrap();
let curr_votes: u128 = read.@state.proposal_total_nay;
let new_votes: u128 = curr_votes + vote_power;
assert(new_votes >= 0, 'new_votes negative');
proposal_total_nay::InternalContractStateTrait::write(
ref state.proposal_total_nay, prop_id, new_votes.into()
);
state.proposal_total_nay.write(prop_id, new_votes.into());
} else {
let curr_votes: u128 = proposal_total_yay::InternalContractStateTrait::read(
@state.proposal_total_yay, prop_id
)
.try_into()
.unwrap();
let curr_votes: u128 = state.proposal_total_yay.read(prop_id);
let new_votes: u128 = curr_votes + vote_power;
assert(new_votes >= 0, 'new_votes negative');
proposal_total_yay::InternalContractStateTrait::write(
ref state.proposal_total_yay, prop_id, new_votes.into()
);
state.proposal_total_yay.write(prop_id, new_votes.into());
}
}
}
Loading

0 comments on commit df308f8

Please sign in to comment.