diff --git a/starknet/src/execution_strategies/simple_quorum.cairo b/starknet/src/execution_strategies/simple_quorum.cairo index 1053ec2d..c9491b05 100644 --- a/starknet/src/execution_strategies/simple_quorum.cairo +++ b/starknet/src/execution_strategies/simple_quorum.cairo @@ -19,6 +19,11 @@ mod SimpleQuorumExecutionStrategy { self._quorum.write(quorum); } + #[internal] + fn quorum(self: @ContractState) -> u256 { + self._quorum.read() + } + #[internal] fn get_proposal_status( self: @ContractState, diff --git a/starknet/src/execution_strategies/vanilla.cairo b/starknet/src/execution_strategies/vanilla.cairo index 1bb2d631..23b34126 100644 --- a/starknet/src/execution_strategies/vanilla.cairo +++ b/starknet/src/execution_strategies/vanilla.cairo @@ -1,14 +1,25 @@ #[starknet::contract] mod VanillaExecutionStrategy { - use sx::interfaces::IExecutionStrategy; + use sx::interfaces::{IExecutionStrategy, IQuorum}; use sx::types::{Proposal, ProposalStatus}; use sx::execution_strategies::simple_quorum::SimpleQuorumExecutionStrategy; + #[storage] struct Storage { _num_executed: felt252 } + #[external(v0)] + impl QuorumImpl of IQuorum { + fn quorum(self: @ContractState) -> u256 { + let mut state: SimpleQuorumExecutionStrategy::ContractState = + SimpleQuorumExecutionStrategy::unsafe_new_contract_state(); + + SimpleQuorumExecutionStrategy::quorum(@state) + } + } + #[external(v0)] impl VanillaExecutionStrategy of IExecutionStrategy { fn execute( diff --git a/starknet/src/interfaces.cairo b/starknet/src/interfaces.cairo index 3b37529f..d0f49df1 100644 --- a/starknet/src/interfaces.cairo +++ b/starknet/src/interfaces.cairo @@ -2,6 +2,7 @@ mod i_voting_strategy; mod i_execution_strategy; mod i_proposal_validation_strategy; mod i_account; +mod i_quorum; use i_voting_strategy::{IVotingStrategy, IVotingStrategyDispatcher, IVotingStrategyDispatcherTrait}; use i_execution_strategy::{ @@ -15,3 +16,4 @@ use i_account::{ AccountABI, AccountABIDispatcher, AccountABIDispatcherTrait, AccountCamelABI, AccountCamelABIDispatcher, AccountCamelABIDispatcherTrait }; +use i_quorum::{IQuorum, IQuorumDispatcher, IQuorumDispatcherTrait}; diff --git a/starknet/src/interfaces/i_quorum.cairo b/starknet/src/interfaces/i_quorum.cairo new file mode 100644 index 00000000..df84c46a --- /dev/null +++ b/starknet/src/interfaces/i_quorum.cairo @@ -0,0 +1,4 @@ +#[starknet::interface] +trait IQuorum { + fn quorum(self: @TContractState) -> u256; +} diff --git a/starknet/src/space/space.cairo b/starknet/src/space/space.cairo index c6f36e81..be2536ba 100644 --- a/starknet/src/space/space.cairo +++ b/starknet/src/space/space.cairo @@ -90,7 +90,7 @@ mod Space { types::{ UserAddress, Choice, FinalizationStatus, Strategy, IndexedStrategy, Proposal, PackedProposal, IndexedStrategyTrait, IndexedStrategyImpl, UpdateSettingsCalldata, - NoUpdateU32, NoUpdateStrategy, NoUpdateArray + NoUpdateTrait, NoUpdateString, }, utils::{ reinitializable::{Reinitializable}, ReinitializableImpl, bits::BitSetter, @@ -610,8 +610,7 @@ mod Space { let _min_voting_duration = input.min_voting_duration; let _max_voting_duration = input.max_voting_duration; - if NoUpdateU32::should_update(@_max_voting_duration) - && NoUpdateU32::should_update(@_min_voting_duration) { + if _max_voting_duration.should_update() && _min_voting_duration.should_update() { // Check that min and max voting durations are valid // We don't use the internal `_set_min_voting_duration` and `_set_max_voting_duration` functions because // it would revert when `_min_voting_duration > max_voting_duration` (when the new `_min` is @@ -637,7 +636,7 @@ mod Space { } ) ); - } else if NoUpdateU32::should_update(@_min_voting_duration) { + } else if _min_voting_duration.should_update() { _set_min_voting_duration(ref self, input.min_voting_duration); self .emit( @@ -647,7 +646,7 @@ mod Space { } ) ); - } else if NoUpdateU32::should_update(@_max_voting_duration) { + } else if _max_voting_duration.should_update() { _set_max_voting_duration(ref self, input.max_voting_duration); self .emit( @@ -659,7 +658,7 @@ mod Space { ); } - if NoUpdateU32::should_update(@input.voting_delay) { + if input.voting_delay.should_update() { _set_voting_delay(ref self, input.voting_delay); self @@ -670,20 +669,7 @@ mod Space { ); } - if NoUpdateArray::should_update((@input).metadata_URI) { - self - .emit( - Event::MetadataUriUpdated( - MetadataUriUpdated { metadata_URI: input.metadata_URI.span() } - ) - ); - } - - if NoUpdateArray::should_update((@input).dao_URI) { - self.emit(Event::DaoUriUpdated(DaoUriUpdated { dao_URI: input.dao_URI.span() })); - } - - if NoUpdateStrategy::should_update((@input).proposal_validation_strategy) { + if input.proposal_validation_strategy.should_update() { _set_proposal_validation_strategy( ref self, input.proposal_validation_strategy.clone() ); @@ -702,7 +688,7 @@ mod Space { ); } - if NoUpdateArray::should_update((@input).authenticators_to_add) { + if input.authenticators_to_add.should_update() { _add_authenticators(ref self, input.authenticators_to_add.span()); self .emit( @@ -714,7 +700,7 @@ mod Space { ); } - if NoUpdateArray::should_update((@input).authenticators_to_remove) { + if input.authenticators_to_remove.should_update() { _remove_authenticators(ref self, input.authenticators_to_remove.span()); self .emit( @@ -726,7 +712,7 @@ mod Space { ); } - if NoUpdateArray::should_update((@input).voting_strategies_to_add) { + if input.voting_strategies_to_add.should_update() { _add_voting_strategies(ref self, input.voting_strategies_to_add.span()); self .emit( @@ -741,7 +727,7 @@ mod Space { ); } - if NoUpdateArray::should_update((@input).voting_strategies_to_remove) { + if input.voting_strategies_to_remove.should_update() { _remove_voting_strategies(ref self, input.voting_strategies_to_remove.span()); self .emit( @@ -752,6 +738,21 @@ mod Space { ) ); } + + // TODO: test once #506 is merged + if NoUpdateString::should_update((@input).metadata_URI) { + self + .emit( + Event::MetadataUriUpdated( + MetadataUriUpdated { metadata_URI: input.metadata_URI.span() } + ) + ); + } + + // TODO: test once #506 is merged + if NoUpdateString::should_update((@input).dao_URI) { + self.emit(Event::DaoUriUpdated(DaoUriUpdated { dao_URI: input.dao_URI.span() })); + } } fn vote_registry(self: @ContractState, proposal_id: u256, voter: UserAddress) -> bool { 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/execution_strategies/vanilla.cairo b/starknet/src/tests/execution_strategies/vanilla.cairo index 795ca46a..c118df4d 100644 --- a/starknet/src/tests/execution_strategies/vanilla.cairo +++ b/starknet/src/tests/execution_strategies/vanilla.cairo @@ -1,6 +1,9 @@ #[cfg(test)] mod tests { + use sx::interfaces::{IQuorum, IQuorumDispatcher, IQuorumDispatcherTrait}; use sx::execution_strategies::vanilla::{VanillaExecutionStrategy}; + use sx::execution_strategies::simple_quorum::SimpleQuorumExecutionStrategy; + use starknet::syscalls::{deploy_syscall}; #[test] #[available_gas(10000000)] @@ -14,4 +17,24 @@ mod tests { assert(strategy_type == 'SimpleQuorumVanilla', 'invalid strategy type'); } + + #[test] + #[available_gas(10000000)] + fn get_quorum() { + let quorum = 42_u256; + let mut constructor_calldata: Array = array![]; + quorum.serialize(ref constructor_calldata); + + let (contract, _) = deploy_syscall( + VanillaExecutionStrategy::TEST_CLASS_HASH.try_into().unwrap(), + 0, + constructor_calldata.span(), + false, + ) + .unwrap(); + + let strat = IQuorumDispatcher { contract_address: contract, }; + + assert(strat.quorum() == quorum, 'invalid quorum'); + } } diff --git a/starknet/src/tests/setup/setup.cairo b/starknet/src/tests/setup/setup.cairo index 3d060936..e082ec9f 100644 --- a/starknet/src/tests/setup/setup.cairo +++ b/starknet/src/tests/setup/setup.cairo @@ -23,9 +23,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, @@ -38,9 +38,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 @@ -99,9 +99,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 4c458c36..e0fe07a3 100644 --- a/starknet/src/tests/test_space.cairo +++ b/starknet/src/tests/test_space.cairo @@ -364,7 +364,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>()); @@ -380,7 +380,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); @@ -477,7 +479,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>()); @@ -493,7 +495,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()); @@ -531,7 +535,9 @@ mod tests { // Create Proposal authenticator.authenticate(space.contract_address, PROPOSE_SELECTOR, propose_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(1, array!['random', 'stuff']); @@ -568,7 +574,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'); @@ -647,7 +653,9 @@ mod tests { // Create Proposal authenticator.authenticate(space.contract_address, PROPOSE_SELECTOR, propose_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(1, array![]); @@ -845,7 +853,7 @@ mod tests { authenticator.authenticate(space.contract_address, PROPOSE_SELECTOR, propose_calldata); // Skip voting delay - testing::set_block_timestamp(config.voting_delay); + testing::set_block_timestamp(config.voting_delay.into()); // Try to update Proposal let mut update_calldata = array::ArrayTrait::::new(); 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 f5fe4d80..eeff5845 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>()); @@ -110,7 +110,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>()); @@ -145,7 +145,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>()); @@ -212,7 +212,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>()); @@ -243,7 +245,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( @@ -279,7 +281,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; @@ -307,7 +311,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>()); @@ -355,7 +359,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 c0c281f3..f96c6279 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); diff --git a/starknet/src/types.cairo b/starknet/src/types.cairo index a5662b4b..e1237da8 100644 --- a/starknet/src/types.cairo +++ b/starknet/src/types.cairo @@ -23,4 +23,5 @@ mod update_settings_calldata; use update_settings_calldata::{ UpdateSettingsCalldata, UpdateSettingsCalldataImpl, UpdateSettingsCalldataTrait, NoUpdateArray, NoUpdateContractAddress, NoUpdateFelt252, NoUpdateStrategy, NoUpdateTrait, NoUpdateU32, + NoUpdateString, }; diff --git a/starknet/src/types/update_settings_calldata.cairo b/starknet/src/types/update_settings_calldata.cairo index 3c6588c7..da73883e 100644 --- a/starknet/src/types/update_settings_calldata.cairo +++ b/starknet/src/types/update_settings_calldata.cairo @@ -79,6 +79,21 @@ impl NoUpdateStrategy of NoUpdateTrait { } } +impl NoUpdateString of NoUpdateTrait> { + fn no_update() -> Array { + array!['No update'] + } + + fn should_update(self: @Array) -> bool { + match self.get(0) { + Option::Some(e) => { + *e.unbox() == 'No update' + }, + Option::None => false, + } + } +} + // TODO: find a way for "Strings" impl NoUpdateArray of NoUpdateTrait> { fn no_update() -> Array {