diff --git a/starknet/src/tests.cairo b/starknet/src/tests.cairo index 11f06222..6e9c28c2 100644 --- a/starknet/src/tests.cairo +++ b/starknet/src/tests.cairo @@ -3,6 +3,7 @@ mod test_factory; mod test_space; mod test_upgrade; mod test_stark_tx_auth; +mod test_update_settings; mod execution_strategies; mod proposal_validation_strategies; diff --git a/starknet/src/tests/setup/setup.cairo b/starknet/src/tests/setup/setup.cairo index 38d4e412..59d424c7 100644 --- a/starknet/src/tests/setup/setup.cairo +++ b/starknet/src/tests/setup/setup.cairo @@ -22,9 +22,9 @@ mod setup { #[derive(Drop)] struct Config { owner: ContractAddress, - min_voting_duration: u64, - max_voting_duration: u64, - voting_delay: u64, + min_voting_duration: u32, + max_voting_duration: u32, + voting_delay: u32, proposal_validation_strategy: Strategy, voting_strategies: Array, authenticators: Array, @@ -37,9 +37,9 @@ mod setup { // Space Settings let owner = contract_address_const::<0x123456789>(); - let max_voting_duration = 2_u64; - let min_voting_duration = 1_u64; - let voting_delay = 1_u64; + let max_voting_duration = 2_u32; + let min_voting_duration = 1_u32; + let voting_delay = 1_u32; let quorum = u256_from_felt252(1); // Deploy Vanilla Authenticator @@ -98,9 +98,9 @@ mod setup { fn get_initialize_calldata( owner: @ContractAddress, - min_voting_duration: @u64, - max_voting_duration: @u64, - voting_delay: @u64, + min_voting_duration: @u32, + max_voting_duration: @u32, + voting_delay: @u32, proposal_validation_strategy: @Strategy, voting_strategies: @Array, authenticators: @Array diff --git a/starknet/src/tests/test_space.cairo b/starknet/src/tests/test_space.cairo index ba651290..f809ca75 100644 --- a/starknet/src/tests/test_space.cairo +++ b/starknet/src/tests/test_space.cairo @@ -264,7 +264,7 @@ mod tests { authenticator .authenticate(space.contract_address, UPDATE_PROPOSAL_SELECTOR, update_calldata); - testing::set_block_timestamp(config.voting_delay); + testing::set_block_timestamp(config.voting_delay.into()); let mut vote_calldata = array![]; let voter = UserAddress::Starknet(contract_address_const::<0x8765>()); @@ -280,7 +280,9 @@ mod tests { // Vote on Proposal authenticator.authenticate(space.contract_address, VOTE_SELECTOR, vote_calldata); - testing::set_block_timestamp(config.voting_delay + config.max_voting_duration); + testing::set_block_timestamp( + config.voting_delay.into() + config.max_voting_duration.into() + ); // Execute Proposal space.execute(u256_from_felt252(1), new_payload); @@ -377,7 +379,7 @@ mod tests { assert(space.next_proposal_id() == 2_u256, 'next_proposal_id should be 2'); - testing::set_block_timestamp(config.voting_delay); + testing::set_block_timestamp(config.voting_delay.into()); let mut vote_calldata = array![]; let voter = UserAddress::Starknet(contract_address_const::<0x8765>()); @@ -393,7 +395,9 @@ mod tests { // Vote on Proposal authenticator.authenticate(space.contract_address, VOTE_SELECTOR, vote_calldata); - testing::set_block_timestamp(config.voting_delay + config.max_voting_duration); + testing::set_block_timestamp( + config.voting_delay.into() + config.max_voting_duration.into() + ); // Execute Proposal space.execute(u256_from_felt252(1), vanilla_execution_strategy.params.clone()); @@ -439,7 +443,7 @@ mod tests { authenticator.authenticate(space.contract_address, PROPOSE_SELECTOR, propose_calldata); let proposal_id = u256_from_felt252(1); - testing::set_block_timestamp(config.voting_delay); + testing::set_block_timestamp(config.voting_delay.into()); let proposal = space.proposals(proposal_id); assert(proposal.finalization_status == FinalizationStatus::Pending(()), 'pending'); diff --git a/starknet/src/tests/test_update_settings.cairo b/starknet/src/tests/test_update_settings.cairo new file mode 100644 index 00000000..b46caed1 --- /dev/null +++ b/starknet/src/tests/test_update_settings.cairo @@ -0,0 +1,279 @@ +#[cfg(test)] +mod tests { + use sx::space::space::{Space, ISpaceDispatcher, ISpaceDispatcherTrait}; + use sx::tests::setup::setup::setup::{setup, deploy, Config}; + use sx::types::{UpdateSettingsCalldata, UpdateSettingsCalldataImpl}; + use sx::tests::utils::strategy_trait::{StrategyImpl}; + use starknet::testing; + use starknet::info; + use starknet::contract_address_const; + use clone::Clone; + use array::{ArrayTrait, SpanTrait}; + use serde::Serde; + + fn setup_update_settings() -> (Config, ISpaceDispatcher) { + let config = setup(); + let (_, space) = deploy(@config); + + testing::set_caller_address(config.owner); + testing::set_contract_address(config.owner); + + (config, space) + } + + #[test] + #[available_gas(10000000000)] + #[should_panic(expected: ('Caller is not the owner', 'ENTRYPOINT_FAILED'))] + fn update_unauthorized() { + let (config, space) = setup_update_settings(); + let mut input = UpdateSettingsCalldataImpl::default(); + + testing::set_contract_address(contract_address_const::<'unauthorized'>()); + space.update_settings(input); + } + + #[test] + #[available_gas(10000000000)] + fn update_min_voting_duration() { + let (config, space) = setup_update_settings(); + let mut input = UpdateSettingsCalldataImpl::default(); + input.min_voting_duration = config.min_voting_duration + 1; + + space.update_settings(input.clone()); + + assert( + space.min_voting_duration() == input.min_voting_duration, + 'Min voting duration not updated' + ); + // TODO: check event once it's been added + } + + #[test] + #[available_gas(10000000000)] + #[should_panic(expected: ('Invalid duration', 'ENTRYPOINT_FAILED'))] + fn update_min_voting_duration_too_big() { + let (config, space) = setup_update_settings(); + let mut input = UpdateSettingsCalldataImpl::default(); + input.min_voting_duration = config.max_voting_duration + 1; + + space.update_settings(input.clone()); + } + + + #[test] + #[available_gas(10000000000)] + fn update_max_voting_duration() { + let (config, space) = setup_update_settings(); + let mut input = UpdateSettingsCalldataImpl::default(); + input.max_voting_duration = config.max_voting_duration + 1; + + space.update_settings(input.clone()); + + assert( + space.max_voting_duration() == input.max_voting_duration, + 'Max voting duration not updated' + ); + // TODO: check event once it's been added + } + + #[test] + #[available_gas(10000000000)] + #[should_panic(expected: ('Invalid duration', 'ENTRYPOINT_FAILED'))] + fn update_max_voting_duration_too_small() { + let (config, space) = setup_update_settings(); + let mut input = UpdateSettingsCalldataImpl::default(); + input.max_voting_duration = config.min_voting_duration - 1; + + space.update_settings(input.clone()); + // TODO: check event once it's been added + } + + #[test] + #[available_gas(10000000000)] + fn update_min_max_voting_duration_at_once() { + let (config, space) = setup_update_settings(); + let mut input = UpdateSettingsCalldataImpl::default(); + input.min_voting_duration = config.max_voting_duration + 1; + input.max_voting_duration = config.max_voting_duration + 2; + + space.update_settings(input.clone()); + assert( + space.min_voting_duration() == input.min_voting_duration, + 'Min voting duration not updated' + ); + assert( + space.max_voting_duration() == input.max_voting_duration, + 'Max voting duration not updated' + ); + // TODO: check event once it's been added + } + + #[test] + #[available_gas(10000000000)] + #[should_panic(expected: ('Invalid duration', 'ENTRYPOINT_FAILED'))] + fn update_min_max_voting_duration_at_once_invalid() { + let (config, space) = setup_update_settings(); + let mut input = UpdateSettingsCalldataImpl::default(); + input.min_voting_duration = config.max_voting_duration + 1; + input + .max_voting_duration = config + .max_voting_duration; // min is bigger than max, should fail + + space.update_settings(input.clone()); + // TODO: check event once it's been added + } + + #[test] + #[available_gas(10000000000)] + fn update_voting_delay() { + let (config, space) = setup_update_settings(); + let mut input = UpdateSettingsCalldataImpl::default(); + input.voting_delay = config.voting_delay + 1; + + space.update_settings(input.clone()); + + assert(space.voting_delay() == input.voting_delay, 'Voting delay not updated'); + // TODO: check event once it's been added + } + + #[test] + #[available_gas(10000000000)] + fn metadata_uri() { + let (config, space) = setup_update_settings(); + let mut input = UpdateSettingsCalldataImpl::default(); + let mut arr = array![]; + 'hello!'.serialize(ref arr); + input.metadata_URI = arr; + + space.update_settings(input.clone()); + // TODO: check event once it's been added + } + + #[test] + #[available_gas(10000000000)] + fn dao_uri() { + let (config, space) = setup_update_settings(); + let mut input = UpdateSettingsCalldataImpl::default(); + let mut arr = array![]; + 'hello!'.serialize(ref arr); + input.dao_URI = arr; + + space.update_settings(input.clone()); + // TODO: check event once it's been added + } + + #[test] + #[available_gas(10000000000)] + fn proposal_validation_strategy() { + let (config, space) = setup_update_settings(); + let mut input = UpdateSettingsCalldataImpl::default(); + let randomStrategy = StrategyImpl::from_address( + contract_address_const::<'randomStrategy'>() + ); + input.proposal_validation_strategy = randomStrategy; + let mut arr = array![]; + 'hello!'.serialize(ref arr); + input.proposal_validation_strategy_metadata_URI = arr; + + space.update_settings(input.clone()); + + assert( + space.proposal_validation_strategy() == input.proposal_validation_strategy, + 'Proposal strategy not updated' + ); + // TODO: check event once it's been added + } + + #[test] + #[available_gas(10000000000)] + fn add_authenticators() { + let (config, space) = setup_update_settings(); + let mut input = UpdateSettingsCalldataImpl::default(); + let auth1 = contract_address_const::<'authenticator1'>(); + let auth2 = contract_address_const::<'authenticator2'>(); + let mut arr = array![auth1, auth2]; + input.authenticators_to_add = arr; + + space.update_settings(input.clone()); + + assert(space.authenticators(auth1) == true, 'Authenticator 1 not added'); + + assert(space.authenticators(auth2) == true, 'Authenticator 2 not added'); + // TODO: check event once it's been added + } + + #[test] + #[available_gas(10000000000)] + fn remove_authenticators() { + let (config, space) = setup_update_settings(); + let mut input = UpdateSettingsCalldataImpl::default(); + let auth1 = *config.authenticators.at(0); + let mut arr = array![auth1]; + input.authenticators_to_remove = arr; + + space.update_settings(input.clone()); + + assert(space.authenticators(auth1) == false, 'Authenticator not removed'); + // TODO: check event once it's been added + } + + #[test] + #[available_gas(10000000000)] + fn add_voting_strategies() { + let (config, space) = setup_update_settings(); + let mut input = UpdateSettingsCalldataImpl::default(); + + let vs1 = StrategyImpl::from_address(contract_address_const::<'votingStrategy1'>()); + let vs2 = StrategyImpl::from_address(contract_address_const::<'votingStrategy2'>()); + + let mut arr = array![vs1.clone(), vs2.clone()]; + input.voting_strategies_to_add = arr; + + space.update_settings(input); + + assert(space.voting_strategies(1) == vs1, 'Voting strategy 1 not added'); + assert(space.voting_strategies(2) == vs2, 'Voting strategy 2 not added'); + assert(space.active_voting_strategies() == 0b111, 'Voting strategies not active'); + // TODO: check event once it's been added + // voting_strategies_metadata_URIs_to_add: Array>, + } + + + #[test] + #[available_gas(10000000000)] + fn remove_voting_strategies() { + let (config, space) = setup_update_settings(); + let mut input = UpdateSettingsCalldataImpl::default(); + + // First, add a new voting strategy + let vs1 = StrategyImpl::from_address(contract_address_const::<'votingStrategy1'>()); + let mut arr = array![vs1.clone()]; + input.voting_strategies_to_add = arr; + space.update_settings(input); + assert(space.voting_strategies(1) == vs1, 'Voting strategy 1 not added'); + assert(space.active_voting_strategies() == 0b11, 'Voting strategy not active'); + + // Now, remove the first voting strategy + let mut input = UpdateSettingsCalldataImpl::default(); + let mut arr = array![0]; + input.voting_strategies_to_remove = arr; + + space.update_settings(input); + assert(space.active_voting_strategies() == 0b10, 'strategy not removed'); + // TODO: check event once it's been added + } + + #[test] + #[available_gas(10000000000)] + #[should_panic(expected: ('No active voting strategy left', 'ENTRYPOINT_FAILED'))] + fn remove_all_voting_strategies() { + let (config, space) = setup_update_settings(); + let mut input = UpdateSettingsCalldataImpl::default(); + + // Remove the first voting strategy + let mut arr = array![0]; + input.voting_strategies_to_remove = arr; + + space.update_settings(input); + } +} diff --git a/starknet/src/tests/vote.cairo b/starknet/src/tests/vote.cairo index a66822c6..5fabd727 100644 --- a/starknet/src/tests/vote.cairo +++ b/starknet/src/tests/vote.cairo @@ -75,7 +75,7 @@ mod tests { create_proposal(authenticator, space, execution_strategy); // Increasing block timestamp pass voting delay - testing::set_block_timestamp(config.voting_delay); + testing::set_block_timestamp(config.voting_delay.into()); let mut vote_calldata = array![]; let voter = UserAddress::Starknet(contract_address_const::<0x8765>()); @@ -109,7 +109,7 @@ mod tests { create_proposal(authenticator, space, execution_strategy); // Increasing block timestamp pass voting delay - testing::set_block_timestamp(config.voting_delay); + testing::set_block_timestamp(config.voting_delay.into()); let mut vote_calldata = array![]; let voter = UserAddress::Starknet(contract_address_const::<0x8765>()); @@ -143,7 +143,7 @@ mod tests { create_proposal(authenticator, space, execution_strategy); // Increasing block timestamp by voting delay - testing::set_block_timestamp(config.voting_delay); + testing::set_block_timestamp(config.voting_delay.into()); let mut vote_calldata = array![]; let voter = UserAddress::Starknet(contract_address_const::<0x8765>()); @@ -209,7 +209,9 @@ mod tests { create_proposal(authenticator, space, execution_strategy); // Fast forward to end of voting period - testing::set_block_timestamp(config.voting_delay + config.max_voting_duration); + testing::set_block_timestamp( + config.voting_delay.into() + config.max_voting_duration.into() + ); let mut vote_calldata = array![]; let voter = UserAddress::Starknet(contract_address_const::<0x8765>()); @@ -240,7 +242,7 @@ mod tests { create_proposal(authenticator, space, execution_strategy); - testing::set_block_timestamp(config.voting_delay); + testing::set_block_timestamp(config.voting_delay.into()); space .execute( @@ -276,7 +278,9 @@ mod tests { create_proposal(authenticator, space, execution_strategy); // Fast forward to end of voting period - testing::set_block_timestamp(config.voting_delay + config.max_voting_duration); + testing::set_block_timestamp( + config.voting_delay.into() + config.max_voting_duration.into() + ); let voter = UserAddress::Starknet(contract_address_const::<0x8765>()); let proposal_id = 1_u256; @@ -304,7 +308,7 @@ mod tests { create_proposal(authenticator, space, execution_strategy); // Increasing block timestamp pass voting delay - testing::set_block_timestamp(config.voting_delay); + testing::set_block_timestamp(config.voting_delay.into()); let mut vote_calldata = array![]; let voter = UserAddress::Starknet(contract_address_const::<0x8765>()); @@ -352,7 +356,7 @@ mod tests { create_proposal(authenticator, space, execution_strategy); // Increasing block timestamp pass voting delay - testing::set_block_timestamp(config.voting_delay); + testing::set_block_timestamp(config.voting_delay.into()); let mut vote_calldata = array![]; let voter = UserAddress::Starknet(contract_address_const::<0x8765>()); diff --git a/starknet/src/tests/voting_strategies/erc20_votes.cairo b/starknet/src/tests/voting_strategies/erc20_votes.cairo index cbb33210..99a22f99 100644 --- a/starknet/src/tests/voting_strategies/erc20_votes.cairo +++ b/starknet/src/tests/voting_strategies/erc20_votes.cairo @@ -179,7 +179,7 @@ mod tests { // Advance to vote start + 1 let current = info::get_block_timestamp(); - testing::set_block_timestamp(current + config.voting_delay + 1); + testing::set_block_timestamp(current + config.voting_delay.into() + 1); let mut vote_calldata = array::ArrayTrait::::new(); let voter = *accounts.at(0); @@ -196,7 +196,7 @@ mod tests { // Vote on proposal authenticator.authenticate(space.contract_address, VOTE_SELECTOR, vote_calldata); - testing::set_block_timestamp(current + config.max_voting_duration); + testing::set_block_timestamp(current + config.max_voting_duration.into()); // Execute proposal space.execute(1_u256, vanilla_execution_strategy.params); @@ -226,7 +226,7 @@ mod tests { // Move to the exact voting period start so the strategy will revert. let current = info::get_block_timestamp(); - testing::set_block_timestamp(current + config.voting_delay); + testing::set_block_timestamp(current + config.voting_delay.into()); let mut vote_calldata = array::ArrayTrait::::new(); let voter = *accounts.at(0); @@ -276,7 +276,7 @@ mod tests { // Move to the exact voting period start + 1 let current = info::get_block_timestamp(); - testing::set_block_timestamp(current + config.voting_delay + 1); + testing::set_block_timestamp(current + config.voting_delay.into() + 1); let mut vote_calldata = array::ArrayTrait::::new(); let voter = *accounts.at(0);