-
Notifications
You must be signed in to change notification settings - Fork 43
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
Implement tests according to missing test list #58 #61
Merged
Merged
Changes from all commits
Commits
Show all changes
40 commits
Select commit
Hold shift + click to select a range
d4071f4
Add custom proposal implementation
tensojka 25ec5d5
Add arbitrary proposal
tensojka 676a2e2
Polish apply_passed_proposal
tensojka d178036
Polish scarb fmt
tensojka 1850814
Cherry pick setup.cairo from 1fab54f
tensojka 4a308b9
Move test setup to src/
tensojka 03d1ba5
Remove unrelated functions from setup.cairo
tensojka 82d7947
Fix setup
tensojka 6ed9c58
Polish tests
tensojka 0ef0d64
Add airdrop tests
Nerrolol aa54ac2
Adding setup file with generic function which applies a proposal to u…
Nerrolol 7f32f99
Setup environment to deploy governance, deploy gov token and distribu…
Nerrolol a2e7bfa
Add tests on proposals
Nerrolol 3f5f10d
fix some issues on proposal tests
Nerrolol b944b09
Proposals Frontend (#66)
tomashobza 0e0c0b7
Update README.md
tensojka c51f55a
Update README.md
tensojka 04f6801
feat: default to_upgrade value (#69)
tomashobza 9f14427
Telegram Notification bot for proposal (#71)
xkrivan5 b144b85
Adding proposals tests
Nerrolol d4fdf9b
Comment code for airdrop_tests and remove old setup file
Nerrolol 2884f06
Add minor fixes towards compilability
tensojka 89f9028
Fix all proposals tests
Nerrolol dc964b5
Fix formatting
tensojka 72883ab
Proposals Frontend (#66)
tomashobza b7f718e
feat: default to_upgrade value (#69)
tomashobza d622ff9
Update frontend domain to konoha.vote
tensojka fc71439
Rename package from 'governance' to 'konoha'
tensojka 4620dd0
Add contributor guidelines
tensojka 2a12029
Update README.md with contributing info
tensojka 32dbf37
Update CONTRIBUTING.md
tensojka 7b4cb3c
Add mdbook scaffolding (#75)
tensojka 7cf23cd
Add custom proposal implementation (#64)
tensojka 9837f69
Remove mentions of Carmine in this repository (#73)
tensojka eb1181d
Rename governance:: to konoha::
tensojka 9f61980
Fix proposals tests and mint tokens to admin addr before distributing…
Nerrolol d837e28
Add quorum tests
Nerrolol 5135607
Move setup to testing, fix tests so they compile
tensojka 9109ef3
Merge branch master
tensojka 37d590d
Merge branch 'master' into missing-tests
tensojka File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
// use core::hash::HashStateExTrait; | ||
// use core::{ArrayTrait, SpanTrait}; | ||
// use core::debug::PrintTrait; | ||
// use governance::airdrop::{airdrop, IAirdropDispatcher, IAirdropDispatcherTrait}; | ||
// use airdrop::STRK_ADDRESS; | ||
// use openzeppelin::token::erc20::interface::{IERC20Dispatcher, IERC20DispatcherTrait}; | ||
// use snforge_std::{ContractClassTrait, declare, start_prank, CheatTarget}; | ||
// use starknet::{ContractAddress, deploy_syscall}; | ||
|
||
// const ADMIN_ADDR: felt252 = 0x42; | ||
// const CLAIMEE_1: felt252 = 0x13; | ||
// const CLAIMEE_2: felt252 = 0x14; | ||
|
||
// fn deploy() -> IAirdropDispatcher { | ||
// let mut calldata = ArrayTrait::new(); | ||
// calldata.append(ADMIN_ADDR); | ||
|
||
// let contract = declare('Airdrop'); | ||
// let address = contract.deploy().expect('unable to deploy Airdrop'); | ||
// IAirdropDispatcher { contract_address: address } | ||
// } | ||
|
||
// #[test] | ||
// fn test_claim_twice_with_same_proof() { | ||
// let airdrop_contract = deploy(); | ||
// let token_contract = deploy_token(airdrop_contract.contract_address); | ||
|
||
// start_prank( | ||
// CheatTarget::One(airdrop_contract.contract_address), ADMIN_ADDR.try_into().unwrap() | ||
// ); | ||
// airdrop_contract.add_root(valid_root); | ||
|
||
// start_prank(CheatTarget::One(airdrop_contract.contract_address), CLAIMEE_1.try_into().unwrap()); | ||
// let initial_proof = array![valid_proof_element]; | ||
// airdrop_contract.claim(CLAIMEE_1, valid_claim_amount, initial_proof.span()); | ||
// assert( | ||
// token_contract.balance_of(CLAIMEE_1.try_into().unwrap()) == valid_claim_amount, | ||
// "First claim failed" | ||
// ); | ||
|
||
// airdrop_contract.claim(CLAIMEE_1, valid_claim_amount, initial_proof.span()); | ||
// assert( | ||
// token_contract.balance_of(CLAIMEE_1.try_into().unwrap()) == valid_claim_amount, | ||
// "Second claim modified the claimee's balance" | ||
// ); | ||
// } | ||
|
||
// #[test] | ||
// #[should_panic(expected: ('INVALID PROOF',))] | ||
// fn test_claim_invalid_proof() { | ||
// let contract = deploy(); | ||
// deploy_token(contract.contract_address); | ||
// start_prank(CheatTarget::One(contract.contract_address), ADMIN_ADDR.try_into().unwrap()); | ||
// contract.add_root(0xf7c8d3f309262572ad35df8ff6c33f24d8114c60eac3bc27bf42382ca82faf); | ||
|
||
// start_prank(CheatTarget::One(contract.contract_address), CLAIMEE_1.try_into().unwrap()); | ||
// let proof = array![0x2a18afb0550a011d54ca3940648e59894c06e4c3d0a611256c0b575bd528b3b, 0x1]; | ||
// contract.claim(0x88, proof.span()); | ||
// } | ||
|
||
// #[test] | ||
// fn test_update_root_and_claim_attempts() { | ||
// let contract = deploy(); | ||
// let tok = deploy_token(contract.contract_address); | ||
// start_prank(CheatTarget::One(contract.contract_address), ADMIN_ADDR.try_into().unwrap()); | ||
|
||
// // add intial root and valid claim | ||
// contract.add_root(initial_root); | ||
// start_prank(CheatTarget::One(contract.contract_address), CLAIMEE_1.try_into().unwrap()); | ||
// contract.claim(claim_amount, valid_proof_for_initial_root.span()); | ||
// assert(tok.balance_of(CLAIMEE_1.try_into().unwrap()) == claim_amount, 'initial claim failed'); | ||
|
||
// // update root | ||
// start_prank(CheatTarget::One(contract.contract_address), ADMIN_ADDR.try_into().unwrap()); | ||
// contract.add_root(new_root); | ||
|
||
// // claim with old root + new proof, should fail | ||
// start_prank(CheatTarget::One(contract.contract_address), CLAIMEE_2.try_into().unwrap()); | ||
// contract.claim(claim_amount, new_proof_not_matching_old_root.span()); | ||
// // check fail : to do, use should panic ? | ||
|
||
// // claim with new root + old proof, should fail | ||
// contract.claim(claim_amount, old_proof_not_matching_new_root.span()); | ||
// // check fail : to do | ||
// } | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,5 @@ | ||
mod vesting; | ||
mod basic; | ||
mod test_treasury; | ||
mod proposals_tests; | ||
mod airdrop_tests; | ||
mod setup; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,164 @@ | ||
use array::ArrayTrait; | ||
use core::traits::TryInto; | ||
use debug::PrintTrait; | ||
use starknet::ContractAddress; | ||
use openzeppelin::token::erc20::interface::{ | ||
IERC20Dispatcher, IERC20DispatcherTrait, IERC20CamelOnlyDispatcher, | ||
IERC20CamelOnlyDispatcherTrait | ||
}; | ||
use snforge_std::{ | ||
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 | ||
}; | ||
use konoha::contract::IGovernanceDispatcher; | ||
use konoha::contract::IGovernanceDispatcherTrait; | ||
use konoha::proposals::IProposalsDispatcher; | ||
use konoha::proposals::IProposalsDispatcherTrait; | ||
use konoha::upgrades::IUpgradesDispatcher; | ||
use konoha::upgrades::IUpgradesDispatcherTrait; | ||
use konoha::constants; | ||
use starknet::get_block_timestamp; | ||
|
||
|
||
const GOV_TOKEN_INITIAL_SUPPLY: felt252 = 1000000000000000000; | ||
|
||
|
||
fn test_express_proposal() { | ||
let token_contract = deploy_and_distribute_gov_tokens(admin_addr.try_into().unwrap()); | ||
let gov_contract = deploy_governance(token_contract.contract_address); | ||
let gov_contract_addr = gov_contract.contract_address; | ||
|
||
let dispatcher = IProposalsDispatcher { contract_address: gov_contract_addr }; | ||
|
||
start_prank(CheatTarget::One(gov_contract_addr), admin_addr.try_into().unwrap()); | ||
let prop_id = dispatcher.submit_proposal(42, 1); | ||
|
||
start_prank(CheatTarget::One(gov_contract_addr), admin_addr.try_into().unwrap()); | ||
dispatcher.vote(prop_id, 1); | ||
|
||
assert!(dispatcher.get_proposal_status(prop_id) == 1, "proposal not passed!"); | ||
} | ||
|
||
#[test] | ||
fn test_proposal_expiry() { | ||
let token_contract = deploy_and_distribute_gov_tokens(admin_addr.try_into().unwrap()); | ||
let gov_contract = deploy_governance(token_contract.contract_address); | ||
let gov_contract_addr = gov_contract.contract_address; | ||
|
||
let dispatcher = IProposalsDispatcher { contract_address: gov_contract_addr }; | ||
|
||
start_prank(CheatTarget::One(gov_contract_addr), admin_addr.try_into().unwrap()); | ||
let prop_id = dispatcher.submit_proposal(42, 1); | ||
|
||
//simulate passage of time | ||
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); | ||
|
||
let status = dispatcher.get_proposal_status(prop_id); | ||
assert!(status == constants::MINUS_ONE, "proposal not expired!"); | ||
} | ||
|
||
#[test] | ||
#[should_panic(expected: ('voting concluded',))] | ||
fn test_vote_on_expired_proposal() { | ||
let token_contract = deploy_and_distribute_gov_tokens(admin_addr.try_into().unwrap()); | ||
let gov_contract = deploy_governance(token_contract.contract_address); | ||
let gov_contract_addr = gov_contract.contract_address; | ||
|
||
let dispatcher = IProposalsDispatcher { contract_address: gov_contract_addr }; | ||
|
||
start_prank(CheatTarget::One(gov_contract_addr), admin_addr.try_into().unwrap()); | ||
let prop_id = dispatcher.submit_proposal(42, 1); | ||
|
||
//simulate passage of time | ||
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); | ||
|
||
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); | ||
} | ||
|
||
#[test] | ||
fn test_vote_on_quorum_not_met() { | ||
let token_contract = deploy_and_distribute_gov_tokens(admin_addr.try_into().unwrap()); | ||
let gov_contract = deploy_governance(token_contract.contract_address); | ||
let gov_contract_addr = gov_contract.contract_address; | ||
|
||
let dispatcher = IProposalsDispatcher { contract_address: gov_contract_addr }; | ||
|
||
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) | ||
); | ||
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.vote(prop_id, 1); | ||
|
||
let (yay_votes, nay_votes) = dispatcher.get_vote_counts(prop_id); | ||
let total_votes = yay_votes + nay_votes; | ||
let total_eligible_votes: u128 = IERC20CamelOnlyDispatcher { | ||
contract_address: token_contract.contract_address | ||
} | ||
.totalSupply() | ||
.low; | ||
let quorum_threshold = total_eligible_votes * constants::QUORUM / 100; | ||
|
||
assert(total_votes < quorum_threshold, 'Total votes >= quorum threshold'); | ||
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' | ||
); | ||
} | ||
|
||
#[test] | ||
#[should_panic(expected: ('not enough tokens to submit',))] | ||
fn test_submit_proposal_under_quorum() { | ||
let token_contract = deploy_and_distribute_gov_tokens(admin_addr.try_into().unwrap()); | ||
let gov_contract = deploy_governance(token_contract.contract_address); | ||
let gov_contract_addr = gov_contract.contract_address; | ||
|
||
let dispatcher = IProposalsDispatcher { contract_address: gov_contract_addr }; | ||
|
||
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); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
use core::traits::Into; | ||
use array::ArrayTrait; | ||
use core::traits::TryInto; | ||
use debug::PrintTrait; | ||
use starknet::ContractAddress; | ||
use openzeppelin::token::erc20::interface::{IERC20Dispatcher, IERC20DispatcherTrait}; | ||
use snforge_std::{ | ||
BlockId, declare, ContractClassTrait, ContractClass, start_prank, start_warp, CheatTarget | ||
}; | ||
use core::ResultTrait; | ||
|
||
|
||
use konoha::contract::IGovernanceDispatcher; | ||
use konoha::contract::IGovernanceDispatcherTrait; | ||
use konoha::proposals::IProposalsDispatcher; | ||
use konoha::proposals::IProposalsDispatcherTrait; | ||
use konoha::upgrades::IUpgradesDispatcher; | ||
use konoha::upgrades::IUpgradesDispatcherTrait; | ||
use konoha::constants; | ||
use openzeppelin::token::erc20::interface::IERC20; | ||
use starknet::get_block_timestamp; | ||
|
||
|
||
const GOV_TOKEN_INITIAL_SUPPLY: u256 = 1000000000000000000; | ||
|
||
const first_address: felt252 = 0x1; | ||
const second_address: felt252 = 0x2; | ||
const admin_addr: felt252 = 0x3; | ||
|
||
fn deploy_governance(token_address: ContractAddress) -> IGovernanceDispatcher { | ||
let gov_contract = declare("Governance").expect('unable to declare governance'); | ||
let mut args: Array<felt252> = ArrayTrait::new(); | ||
args.append(token_address.into()); | ||
let (address, _) = gov_contract.deploy(@args).expect('unable to deploy governance'); | ||
IGovernanceDispatcher { contract_address: address } | ||
} | ||
|
||
|
||
fn deploy_and_distribute_gov_tokens(recipient: ContractAddress) -> IERC20Dispatcher { | ||
let mut calldata = ArrayTrait::new(); | ||
calldata.append(GOV_TOKEN_INITIAL_SUPPLY.low.into()); | ||
calldata.append(GOV_TOKEN_INITIAL_SUPPLY.high.into()); | ||
calldata.append(recipient.into()); | ||
|
||
let gov_token_contract = declare("FloatingToken").expect('unable to declare FloatingToken'); | ||
let (token_addr, _) = gov_token_contract | ||
.deploy(@calldata) | ||
.expect('unable to deploy FloatingToken'); | ||
IERC20Dispatcher { contract_address: token_addr } | ||
} | ||
|
||
|
||
fn test_vote_upgrade_root(new_merkle_root: felt252) { | ||
let token_contract = deploy_and_distribute_gov_tokens(admin_addr.try_into().unwrap()); | ||
let gov_contract = deploy_governance(token_contract.contract_address); | ||
let gov_contract_addr = gov_contract.contract_address; | ||
|
||
let dispatcher = IProposalsDispatcher { contract_address: gov_contract_addr }; | ||
|
||
start_prank(CheatTarget::One(gov_contract_addr), admin_addr.try_into().unwrap()); | ||
let prop_id = dispatcher.submit_proposal(new_merkle_root, 3); | ||
|
||
start_prank(CheatTarget::One(gov_contract_addr), first_address.try_into().unwrap()); | ||
dispatcher.vote(prop_id, 1); | ||
start_prank(CheatTarget::One(gov_contract_addr), second_address.try_into().unwrap()); | ||
dispatcher.vote(prop_id, 1); | ||
start_prank(CheatTarget::One(gov_contract_addr), admin_addr.try_into().unwrap()); | ||
dispatcher.vote(prop_id, 1); | ||
|
||
assert(dispatcher.get_proposal_status(prop_id) == 1, 'proposal not passed!'); | ||
|
||
let upgrade_dispatcher = IUpgradesDispatcher { contract_address: gov_contract_addr }; | ||
upgrade_dispatcher.apply_passed_proposal(prop_id); | ||
assert(check_if_healthy(gov_contract_addr), 'new gov not healthy'); | ||
} | ||
|
||
fn check_if_healthy(gov_contract_addr: ContractAddress) -> bool { | ||
// TODO | ||
let dispatcher = IProposalsDispatcher { contract_address: gov_contract_addr }; | ||
dispatcher.get_proposal_status(0); | ||
let prop_details = dispatcher.get_proposal_details(0); | ||
(prop_details.payload + prop_details.to_upgrade) != 0 | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Need to add check that status is -1 (or 2? not sure) meaning it failed.