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

Investigate prop 77 #5

Merged
merged 7 commits into from
Jul 22, 2024
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
29 changes: 29 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
name: CI

on:
push:
paths:
- '**.cairo'
- '.github/'
- 'Scarb.lock'
- 'Scarb.toml'

env:
SCARB_VERSION: 2.6.4
FOUNDRY_VERSION: 0.23.0

jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout (GitHub)
uses: actions/checkout@v3
- name: Install Scarb
run: curl --proto '=https' --tlsv1.2 -sSf https://docs.swmansion.com/scarb/install.sh | bash -s -- -v $SCARB_VERSION
- name: Check formatting
run: scarb fmt --check
- uses: foundry-rs/setup-snfoundry@v3
with:
starknet-foundry-version: ${{ env.FOUNDRY_VERSION }}
- name: Run tests with snforge
run: snforge test
5 changes: 5 additions & 0 deletions Scarb.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@ name = "MAINNET"
url = "http://178.32.172.148:6060/v0_7"
block_id.tag = "Latest"

[[tool.snforge.fork]]
name = "MAINNET_BEFORE_UPGRADE_TO_KONOHA"
url = "http://178.32.172.148:6060/v0_7"
block_id.number = "652000"

[[tool.snforge.fork]]
name = "SEPOLIA"
url = "http://178.32.172.148:6062/v0_7"
Expand Down
2 changes: 1 addition & 1 deletion src/lib.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ pub mod carm;
pub mod constants;
pub mod contract;
mod options;
mod proposals;
pub mod proposals;
pub mod staking;
mod traits;
mod types;
Expand Down
2 changes: 1 addition & 1 deletion src/proposals.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use konoha::types::{ContractType, PropDetails, VoteStatus, CustomProposalConfig}
use starknet::ContractAddress;

#[starknet::interface]
trait IProposals<TContractState> {
pub trait IProposals<TContractState> {
fn vote(ref self: TContractState, prop_id: felt252, opinion: felt252);
fn get_proposal_details(self: @TContractState, prop_id: felt252) -> PropDetails;
fn get_vote_counts(self: @TContractState, prop_id: felt252) -> (u128, u128);
Expand Down
4 changes: 2 additions & 2 deletions tests/lib.cairo
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
mod unstake_airdrop;
mod test_prop_pass;
//mod unstake_airdrop;
//mod add_options;
mod upgrade;
pub mod utils;

190 changes: 190 additions & 0 deletions tests/test_prop_pass.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
use amm_governance::proposals::{IProposalsDispatcherTrait, IProposalsDispatcher};
use amm_governance::staking::{IStakingDispatcherTrait, IStakingDispatcher};
use openzeppelin::token::erc20::interface::{IERC20DispatcherTrait, IERC20Dispatcher};

use snforge_std::{CheatSpan, CheatTarget, prank, start_warp};
use starknet::{ContractAddress, get_block_timestamp};

const DECS: u128 = 1000000000000000000; // 10*18

fn get_team_addresses() -> @Span<felt252> {
let arr = array![
0x0583a9d956d65628f806386ab5b12dccd74236a3c6b930ded9cf3c54efc722a1,
0x06717eaf502baac2b6b2c6ee3ac39b34a52e726a73905ed586e757158270a0af,
0x058d2ddce3e4387dc0da7e45c291cb436bb809e00a4c132bcc5758e4574f55c7,
0x05e61dfb8a9863e446981e804a203a7ad3a2d15495c85b79cfd053ec63e9bfb3,
0x04379c63976feaca8019db2c08f7af8e976b11aef7eda9dfe2ef604e76fc99d2,
0x0011d341c6e841426448ff39aa443a6dbb428914e05ba2259463c18308b86233,
0x00d79a15d84f5820310db21f953a0fae92c95e25d93cb983cc0c27fc4c52273c,
0x03d1525605db970fa1724693404f5f64cba8af82ec4aab514e6ebd3dec4838ad,
0x06fd0529AC6d4515dA8E5f7B093e29ac0A546a42FB36C695c8f9D13c5f787f82,
0x04d2FE1Ff7c0181a4F473dCd982402D456385BAE3a0fc38C49C0A99A620d1abe,
0x062c290f0afa1ea2d6b6d11f6f8ffb8e626f796e13be1cf09b84b2edaa083472,
0x01714ab9a05b062e0c09cf635fd469ce664c914ef9d9ff2394928e31707ce9a6,
0x06c59d2244250f2540a2694472e3c31262e887ff02582ef864bf0e76c34e1298,
0x0528f064c43e2d6Ee73bCbfB725bAa293CD31Ea1f1861EA2F80Bc283Ea4Ad728,
0x05105649f42252f79109356e1c8765b7dcdb9bf4a6a68534e7fc962421c7efd2,
0x00777558f1c767126461540d1f10118981d30bd620707e99686bfc9f00ae66f0,
0x06e2c2a5da2e5478b1103d452486afba8378e91f32a124f0712f09edd3ccd923,
0x035e0845154423c485e5216f70496130079b5ddc8ac66e3e316184482788e2a0,
0x0244dda2c6581eb158db225992153c9d49e92c412424daeb83a773fa9822eeef, // team multisig
0x059c0d4c5dde72e8cab06105be5f2beeb4de52dc516ccbafcaa0b58894d16397, // company wallet
];
@arr.span()
}

fn get_investor_addresses() -> @Span<felt252> {
let arr = array![
0x05a4523982b437aadd1b5109b6618c46f7b1c42f5f9e7de1a3b84091f87d411b,
0x056d761e1e5d1918dba05de02afdbd8de8da01a63147dce828c9b1fe9227077d, // investor multisig
];
@arr.span()
}

fn get_adjusted_group_voting_power(contract: IStakingDispatcher, investors: bool) -> u128 {
let mut total: u128 = 0;
let mut addresses = *get_team_addresses();
loop {
match addresses.pop_front() {
Option::Some(addr) => {
total += contract.get_adjusted_voting_power((*addr).try_into().unwrap());
},
Option::None(_) => { break total; }
}
}
}


fn get_total_group_voting_power(contract: IStakingDispatcher, investors: bool) -> u128 {
let mut total: u128 = 0;
let mut addresses = if investors {
*get_investor_addresses()
} else {
*get_team_addresses()
};
loop {
match addresses.pop_front() {
Option::Some(addr) => {
total += contract.get_total_voting_power((*addr).try_into().unwrap());
},
Option::None(_) => { break total; }
}
}
}

fn get_total_voted_adjusted(
proposals: IProposalsDispatcher, staking: IStakingDispatcher, prop_id: u32
) -> u128 {
let mut addresses = *get_team_addresses();
let mut total = 0;
loop {
match addresses.pop_front() {
Option::Some(addr) => {
if (proposals.get_user_voted((*addr).try_into().unwrap(), prop_id.into()) != 0) {
total += staking.get_adjusted_voting_power((*addr).try_into().unwrap());
}
},
Option::None(_) => { break total; }
}
}
}

#[test]
#[fork("MAINNET")]
fn test_prop_pass() {
let staking = IStakingDispatcher {
contract_address: 0x001405ab78ab6ec90fba09e6116f373cda53b0ba557789a4578d8c1ec374ba0f
.try_into()
.unwrap()
};
let total_team_adj = get_adjusted_group_voting_power(staking, false);
println!("total team adjusted: {:?}", total_team_adj / DECS);
let total_team_total = get_total_group_voting_power(staking, false);
println!("total team total: {:?}", total_team_total / DECS);
let investors_total = get_total_group_voting_power(staking, true);
println!("investors total: {:?}", investors_total);
let vecrm = IERC20Dispatcher {
contract_address: 0x3c0286e9e428a130ae7fbbe911b794e8a829c367dd788e7cfe3efb0367548fa
.try_into()
.unwrap()
};
println!("vecrm total supply: {:?}", vecrm.total_supply() / DECS.into());
let props = IProposalsDispatcher {
contract_address: 0x001405ab78ab6ec90fba09e6116f373cda53b0ba557789a4578d8c1ec374ba0f
.try_into()
.unwrap()
};
let total_voted_on_prop_adj = get_total_voted_adjusted(props, staking, 77);
println!("total adjusted votes on prop: {:?}", total_voted_on_prop_adj / DECS);
let (yay, _nay) = props.get_vote_counts(77);
println!("recorded vote count: {:?}", yay / DECS);
}

#[test]
#[fork("MAINNET")]
fn test_can_pass_next_prop() {
let user1: ContractAddress =
0x0011d341c6e841426448ff39aa443a6dbb428914e05ba2259463c18308b86233 // team m 1
.try_into()
.unwrap();
let gov_addr = 0x001405ab78ab6ec90fba09e6116f373cda53b0ba557789a4578d8c1ec374ba0f
.try_into()
.unwrap();
let props = IProposalsDispatcher { contract_address: gov_addr };
let staking = IStakingDispatcher { contract_address: gov_addr };
let vecrm = IERC20Dispatcher {
contract_address: 0x3c0286e9e428a130ae7fbbe911b794e8a829c367dd788e7cfe3efb0367548fa
.try_into()
.unwrap()
};
prank(CheatTarget::One(gov_addr), user1, CheatSpan::TargetCalls(1));
let prop_id = props.submit_proposal(0x42, 0x4);
prank(CheatTarget::One(gov_addr), user1, CheatSpan::TargetCalls(1));
props.vote(prop_id, 1);

let user2: ContractAddress = 0x0583a9d956d65628f806386ab5b12dccd74236a3c6b930ded9cf3c54efc722a1
.try_into()
.unwrap(); // team o
prank(CheatTarget::One(gov_addr), user2, CheatSpan::TargetCalls(1));
props.vote(prop_id, 1);

let user3: ContractAddress = 0x03d1525605db970fa1724693404f5f64cba8af82ec4aab514e6ebd3dec4838ad
.try_into()
.unwrap(); //team d
prank(CheatTarget::One(gov_addr), user3, CheatSpan::TargetCalls(1));
props.vote(prop_id, 1);

let user4: ContractAddress = 0x00d79a15d84f5820310db21f953a0fae92c95e25d93cb983cc0c27fc4c52273c
.try_into()
.unwrap(); //team m 2
prank(CheatTarget::One(gov_addr), user4, CheatSpan::TargetCalls(1));
props.vote(prop_id, 1);

let community1: ContractAddress =
0x0428c240649b76353644faF011B0d212e167f148fdd7479008Aa44eEaC782BfC
.try_into()
.unwrap(); // community m 1
prank(CheatTarget::One(gov_addr), community1, CheatSpan::TargetCalls(1));
props.vote(prop_id, 1);
let community1_balance: u128 = vecrm.balance_of(community1).try_into().unwrap();

let user5: ContractAddress = 0x06717eaf502baac2b6b2c6ee3ac39b34a52e726a73905ed586e757158270a0af
.try_into()
.unwrap(); //team a 1
prank(CheatTarget::One(gov_addr), user5, CheatSpan::TargetCalls(1));
props.vote(prop_id, 1);

let (yay, _nay) = props.get_vote_counts(prop_id);
assert(
get_total_voted_adjusted(props, staking, prop_id.try_into().unwrap())
+ community1_balance == yay,
'votes dont match??'
);
println!("voted on prop_id: {:?}", yay / DECS);

let curr_timestamp = get_block_timestamp();
let warped_timestamp = curr_timestamp + consteval_int!(60 * 60 * 24 * 7) + 420;

start_warp(CheatTarget::One(gov_addr), warped_timestamp);
assert(props.get_proposal_status(prop_id) == 1, 'prop not passed');
}
9 changes: 6 additions & 3 deletions tests/unstake_airdrop.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,8 @@ fn test_unstake_airdrop() {
props.vote(prop_id_gov_upgrade, 1);

// Upgrade veCarm token
let prop_id_vecarm_upgrade = props.submit_proposal(0x008e98fd1f76f0d6fca8b03292e1dd6c8a6c5362f5aa0fd1186592168e9ad692, 2);
let prop_id_vecarm_upgrade = props
.submit_proposal(0x008e98fd1f76f0d6fca8b03292e1dd6c8a6c5362f5aa0fd1186592168e9ad692, 2);
props.vote(prop_id_vecarm_upgrade, 1);

// Propose Airdrop
Expand Down Expand Up @@ -230,7 +231,8 @@ fn test_unstake_airdrop_unstake_again_failing() {
props.vote(prop_id_gov_upgrade, 1);

// Upgrade veCarm token
let prop_id_vecarm_upgrade = props.submit_proposal(0x008e98fd1f76f0d6fca8b03292e1dd6c8a6c5362f5aa0fd1186592168e9ad692, 2);
let prop_id_vecarm_upgrade = props
.submit_proposal(0x008e98fd1f76f0d6fca8b03292e1dd6c8a6c5362f5aa0fd1186592168e9ad692, 2);
props.vote(prop_id_vecarm_upgrade, 1);

// Propose Airdrop
Expand Down Expand Up @@ -332,7 +334,8 @@ fn test_unstake_airdrop_team_member_failing() {
props.vote(prop_id_gov_upgrade, 1);

// Upgrade veCarm token
let prop_id_vecarm_upgrade = props.submit_proposal(0x008e98fd1f76f0d6fca8b03292e1dd6c8a6c5362f5aa0fd1186592168e9ad692, 2);
let prop_id_vecarm_upgrade = props
.submit_proposal(0x008e98fd1f76f0d6fca8b03292e1dd6c8a6c5362f5aa0fd1186592168e9ad692, 2);
props.vote(prop_id_vecarm_upgrade, 1);

// Propose Airdrop
Expand Down
40 changes: 19 additions & 21 deletions tests/upgrade.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use amm_governance::contract::{
use amm_governance::staking::{IStakingDispatcher, IStakingDispatcherTrait};
use amm_governance::vecarm::{IVeCRMDispatcher, IVeCRMDispatcherTrait};
use core::num::traits::Zero;
use konoha::constants;

use konoha::contract::IGovernanceDispatcher;
use konoha::contract::IGovernanceDispatcherTrait;
Expand All @@ -17,15 +18,15 @@ use konoha::upgrades::IUpgradesDispatcher;
use konoha::upgrades::IUpgradesDispatcherTrait;
use openzeppelin::upgrades::interface::{IUpgradeableDispatcher, IUpgradeableDispatcherTrait};
use snforge_std::{
BlockId, declare, ContractClassTrait, ContractClass, start_prank, CheatTarget, prank, CheatSpan,
roll, start_warp
BlockId, declare, ContractClassTrait, ContractClass, start_prank, stop_prank, CheatTarget,
prank, CheatSpan, roll, start_warp
};
use starknet::{ClassHash, ContractAddress, get_block_timestamp, get_block_number};
use super::utils::vote_on_proposal;

// commented out as it fails with 'No voting power' for now
//#[test]
//#[fork("MAINNET")]

#[test]
#[fork("MAINNET")]
fn test_upgrade_to_master() {
let gov_contract_addr: ContractAddress =
0x001405ab78ab6ec90fba09e6116f373cda53b0ba557789a4578d8c1ec374ba0f
Expand All @@ -37,24 +38,21 @@ fn test_upgrade_to_master() {
let gov_class: ContractClass = declare("Governance").expect('unable to declare!');
assert(Zero::is_non_zero(@gov_class.class_hash), 'new classhash zero??');
let user2_address: ContractAddress =
0x052df7acdfd3174241fa6bd5e1b7192cd133f8fc30a2a6ed99b0ddbfb5b22dcd
0x06e2c2a5da2e5478b1103d452486afba8378e91f32a124f0712f09edd3ccd923
.try_into()
.unwrap();
start_prank(CheatTarget::One(gov_contract_addr), user2_address);
prank(CheatTarget::One(gov_contract_addr), user2_address, CheatSpan::TargetCalls(1));
let new_prop_id = dispatcher.submit_proposal(gov_class.class_hash.into(), 1);
println!("Prop submitted: {:?}", new_prop_id);
vote_on_proposal(gov_contract_addr, new_prop_id.try_into().unwrap());

//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 upgrade_dispatcher = IUpgradesDispatcher { contract_address: gov_contract_addr };
upgrade_dispatcher.apply_passed_proposal(new_prop_id);
let amm_governance = IMigrateDispatcher { contract_address: gov_contract_addr };
amm_governance.add_custom_proposals();
println!("Checking if new gov is healthy...");
assert(check_if_healthy(gov_contract_addr), 'new gov not healthy');
upgrade_amm(
gov_contract_addr,
0x0239b6f9eeb5ffba1df4da7f33e116d3603d724283bc01338125eed82964e729.try_into().unwrap()
);
}

fn test_deposit_to_amm_from_treasury(gov_contract_addr: ContractAddress) {
Expand Down Expand Up @@ -139,7 +137,7 @@ fn test_upgrade_amm_back(amm: ContractAddress, owner: ContractAddress, new_class


#[test]
#[fork("MAINNET")]
#[fork("MAINNET_BEFORE_UPGRADE_TO_KONOHA")]
fn scenario_airdrop_staked_carm() {
let gov_addr: ContractAddress =
0x001405ab78ab6ec90fba09e6116f373cda53b0ba557789a4578d8c1ec374ba0f
Expand Down Expand Up @@ -185,14 +183,14 @@ fn scenario_airdrop_staked_carm() {

let props = IProposalsDispatcher { contract_address: gov_addr };
prank(CheatTarget::One(gov_addr), user1, CheatSpan::TargetCalls(6));
let prop_id_gov_upgrade = props.submit_proposal(0x04bc8bc7c476c4fca95624809dab1f1aa718edb566184a9d6dfe54f65b32b507, 1);
let prop_id_vecarm_upgrade = props.submit_proposal(0x008e98fd1f76f0d6fca8b03292e1dd6c8a6c5362f5aa0fd1186592168e9ad692, 2);
let prop_id_gov_upgrade = props
.submit_proposal(0x04bc8bc7c476c4fca95624809dab1f1aa718edb566184a9d6dfe54f65b32b507, 1);
let prop_id_vecarm_upgrade = props
.submit_proposal(0x008e98fd1f76f0d6fca8b03292e1dd6c8a6c5362f5aa0fd1186592168e9ad692, 2);
props.vote(prop_id_gov_upgrade, 1);
props.vote(prop_id_vecarm_upgrade, 1);
let prop_id_airdrop = props
.submit_proposal(
0x1337, 3
); // simulate airdrop proposal, no merkle tree root yet
.submit_proposal(0x1337, 3); // simulate airdrop proposal, no merkle tree root yet
props.vote(prop_id_airdrop, 1);
prank(CheatTarget::One(gov_addr), user2, CheatSpan::TargetCalls(3));
props.vote(prop_id_gov_upgrade, 1);
Expand Down
Loading
Loading