Skip to content

Commit

Permalink
Merge branch master
Browse files Browse the repository at this point in the history
  • Loading branch information
tensojka committed May 27, 2024
1 parent 5135607 commit 9109ef3
Show file tree
Hide file tree
Showing 7 changed files with 299 additions and 39 deletions.
16 changes: 13 additions & 3 deletions src/contract.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ trait IGovernance<TContractState> {

// in component

// VESTING

// in component
// OPTIONS / ONE-OFF
}

Expand All @@ -31,17 +34,21 @@ mod Governance {
use konoha::proposals::proposals as proposals_component;
use konoha::upgrades::upgrades as upgrades_component;
use konoha::airdrop::airdrop as airdrop_component;
use konoha::vesting::vesting as vesting_component;

use starknet::ContractAddress;


component!(path: airdrop_component, storage: airdrop, event: AirdropEvent);
component!(path: vesting_component, storage: vesting, event: VestingEvent);
component!(path: proposals_component, storage: proposals, event: ProposalsEvent);
component!(path: upgrades_component, storage: upgrades, event: UpgradesEvent);

#[abi(embed_v0)]
impl Airdrop = airdrop_component::AirdropImpl<ContractState>;

#[abi(embed_v0)]
impl Vesting = vesting_component::VestingImpl<ContractState>;
#[abi(embed_v0)]
impl Proposals = proposals_component::ProposalsImpl<ContractState>;

Expand All @@ -53,10 +60,12 @@ mod Governance {
proposal_initializer_run: LegacyMap::<u64, bool>,
governance_token_address: ContractAddress,
#[substorage(v0)]
proposals: proposals_component::Storage,
#[substorage(v0)]
airdrop: airdrop_component::Storage,
#[substorage(v0)]
vesting: vesting_component::Storage,
#[substorage(v0)]
proposals: proposals_component::Storage,
#[substorage(v0)]
upgrades: upgrades_component::Storage
}

Expand All @@ -66,7 +75,7 @@ mod Governance {
struct Proposed {
prop_id: felt252,
payload: felt252,
to_upgrade: ContractType
to_upgrade: ContractType,
}

#[derive(starknet::Event, Drop)]
Expand All @@ -82,6 +91,7 @@ mod Governance {
Proposed: Proposed,
Voted: Voted,
AirdropEvent: airdrop_component::Event,
VestingEvent: vesting_component::Event,
ProposalsEvent: proposals_component::Event,
UpgradesEvent: upgrades_component::Event
}
Expand Down
1 change: 1 addition & 0 deletions src/lib.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,5 @@ mod traits;
mod treasury;
mod types;
mod upgrades;
mod vesting;
mod voting_token;
36 changes: 20 additions & 16 deletions src/vesting.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,21 @@ trait IVesting<TContractState> {
ref self: TContractState,
first_vest: u64,
period: u64,
increments_count: u64,
total_amount: u128
increments_count: u16,
total_amount: u128,
grantee: ContractAddress
);
// MAYBE – streaming?
// MAYBE – options on the govtoken?
}

#[starknet::component]
mod vesting {
use starknet::syscalls::get_block_timestamp;

use konoha::traits::IGovernanceTokenDispatcher;
use konoha::traits::IGovernanceTokenDispatcherTrait;
use starknet::ContractAddress;
use starknet::{get_block_timestamp, get_caller_address, get_contract_address};
use konoha::contract::Governance;
use konoha::contract::{IGovernanceDispatcher, IGovernanceDispatcherTrait};
use konoha::traits::{IGovernanceTokenDispatcher, IGovernanceTokenDispatcherTrait};

#[storage]
struct Storage {
Expand Down Expand Up @@ -65,10 +67,11 @@ mod vesting {
vested_timestamp: u64
) {
let amt_to_vest = self.milestone.read((vested_timestamp, grantee));
assert(amt_to_vest != 0, 'no vesting milestone found, or already vested');
assert(amt_to_vest != 0, 'nothing to vest');
assert(get_block_timestamp() > vested_timestamp, 'not yet eligible');
IGovernanceTokenDispatcher { contract_address: govtoken_addr }
.mint(claimee, u256 { high: 0, low: amt_to_vest });
let self_dsp = IGovernanceDispatcher { contract_address: get_contract_address() };
IGovernanceTokenDispatcher { contract_address: self_dsp.get_governance_token_address() }
.mint(grantee, amt_to_vest.into());
self.milestone.write((vested_timestamp, grantee), 0);
self
.emit(
Expand All @@ -82,29 +85,30 @@ mod vesting {
grantee: ContractAddress,
amount: u128
) {
self.milestone.write((vested_timestamp, grantee), amount);
assert(get_caller_address() == get_contract_address(), 'not self-call');
self.milestone.write((vesting_timestamp, grantee), amount);
self
.emit(
VestingMilestoneAdded {
grantee: grantee, timestamp: vesting_timestamp, amount: u128
grantee: grantee, timestamp: vesting_timestamp, amount: amount
}
)
}

fn add_linear_vesting_schedule(
ref self: TContractState,
ref self: ComponentState<TContractState>,
first_vest: u64,
period: u64,
increments_count: u16,
total_amount: u128,
grantee: ContractAddress
) {
assert(get_caller_address() == get_contract_address(), 'not self-call');
let mut i: u16 = 0;
let mut curr_timestamp = first_vest;
assert(increments_count > 1, 'schedule must have more than one milestone');
assert(get_block_timestamp() < first_vest, 'first vest cannot be in the past');
assert()
let per_vest_amount = total_amount / increments_count;
assert(increments_count > 1, 'increments_count <= 1');
assert(get_block_timestamp() < first_vest, 'first vest can\'t be in the past');
let per_vest_amount = total_amount / increments_count.into();
let mut total_scheduled = 0;
loop {
if i == increments_count {
Expand Down
2 changes: 1 addition & 1 deletion tests/lib.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ mod basic;
mod test_treasury;
mod proposals_tests;
mod airdrop_tests;
mod setup;
mod setup;
55 changes: 43 additions & 12 deletions tests/proposals_tests.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,18 @@ use array::ArrayTrait;
use core::traits::TryInto;
use debug::PrintTrait;
use starknet::ContractAddress;
use openzeppelin::token::erc20::interface::{IERC20Dispatcher, IERC20DispatcherTrait, IERC20CamelOnlyDispatcher, IERC20CamelOnlyDispatcherTrait};
use openzeppelin::token::erc20::interface::{
IERC20Dispatcher, IERC20DispatcherTrait, IERC20CamelOnlyDispatcher,
IERC20CamelOnlyDispatcherTrait
};
use snforge_std::{
BlockId, declare, ContractClassTrait, ContractClass, start_prank, start_warp, CheatTarget, prank, CheatSpan
BlockId, declare, ContractClassTrait, ContractClass, start_prank, start_warp, CheatTarget,
prank, CheatSpan
};

use super::setup::{
admin_addr, first_address, second_address, deploy_governance, deploy_and_distribute_gov_tokens, test_vote_upgrade_root, check_if_healthy
admin_addr, first_address, second_address, deploy_governance, deploy_and_distribute_gov_tokens,
test_vote_upgrade_root, check_if_healthy
};
use konoha::contract::IGovernanceDispatcher;
use konoha::contract::IGovernanceDispatcherTrait;
Expand Down Expand Up @@ -76,8 +81,11 @@ fn test_vote_on_expired_proposal() {
let end_timestamp = current_timestamp + constants::PROPOSAL_VOTING_SECONDS;
start_warp(CheatTarget::One(gov_contract_addr), end_timestamp + 1);


prank(CheatTarget::One(token_contract.contract_address), admin_addr.try_into().unwrap(), CheatSpan::TargetCalls(1));
prank(
CheatTarget::One(token_contract.contract_address),
admin_addr.try_into().unwrap(),
CheatSpan::TargetCalls(1)
);
token_contract.transfer(first_address.try_into().unwrap(), 100000.try_into().unwrap());
start_prank(CheatTarget::One(gov_contract_addr), first_address.try_into().unwrap());
dispatcher.vote(prop_id, 1);
Expand All @@ -91,13 +99,25 @@ fn test_vote_on_quorum_not_met() {

let dispatcher = IProposalsDispatcher { contract_address: gov_contract_addr };

prank(CheatTarget::One(gov_contract_addr), admin_addr.try_into().unwrap(), CheatSpan::TargetCalls(1));
prank(
CheatTarget::One(gov_contract_addr),
admin_addr.try_into().unwrap(),
CheatSpan::TargetCalls(1)
);
let prop_id = dispatcher.submit_proposal(42, 1);

prank(CheatTarget::One(token_contract.contract_address), admin_addr.try_into().unwrap(), CheatSpan::TargetCalls(1));
prank(
CheatTarget::One(token_contract.contract_address),
admin_addr.try_into().unwrap(),
CheatSpan::TargetCalls(1)
);
token_contract.transfer(first_address.try_into().unwrap(), 100000.try_into().unwrap());

prank(CheatTarget::One(gov_contract_addr), first_address.try_into().unwrap(), CheatSpan::TargetCalls(1));
prank(
CheatTarget::One(gov_contract_addr),
first_address.try_into().unwrap(),
CheatSpan::TargetCalls(1)
);
dispatcher.vote(prop_id, 1);

let (yay_votes, nay_votes) = dispatcher.get_vote_counts(prop_id);
Expand All @@ -113,7 +133,10 @@ fn test_vote_on_quorum_not_met() {
let current_timestamp = get_block_timestamp();
let end_timestamp = current_timestamp + constants::PROPOSAL_VOTING_SECONDS;
start_warp(CheatTarget::One(gov_contract_addr), end_timestamp + 1);
assert(dispatcher.get_proposal_status(prop_id) == constants::MINUS_ONE, 'Proposal pass & quorum not met');
assert(
dispatcher.get_proposal_status(prop_id) == constants::MINUS_ONE,
'Proposal pass & quorum not met'
);
}

#[test]
Expand All @@ -125,9 +148,17 @@ fn test_submit_proposal_under_quorum() {

let dispatcher = IProposalsDispatcher { contract_address: gov_contract_addr };

prank(CheatTarget::One(token_contract.contract_address), admin_addr.try_into().unwrap(), CheatSpan::TargetCalls(1));
prank(
CheatTarget::One(token_contract.contract_address),
admin_addr.try_into().unwrap(),
CheatSpan::TargetCalls(1)
);
token_contract.transfer(first_address.try_into().unwrap(), 100000.try_into().unwrap());

prank(CheatTarget::One(gov_contract_addr), first_address.try_into().unwrap(), CheatSpan::TargetCalls(1));
dispatcher.submit_proposal(42,1);
prank(
CheatTarget::One(gov_contract_addr),
first_address.try_into().unwrap(),
CheatSpan::TargetCalls(1)
);
dispatcher.submit_proposal(42, 1);
}
Loading

0 comments on commit 9109ef3

Please sign in to comment.