From ed4cc6a5491c6a755256c07978f879f0be1833a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emmanuel=20Ag=C3=BCero?= <54730752+EmmanuelAR@users.noreply.github.com> Date: Tue, 27 Aug 2024 23:05:37 -0600 Subject: [PATCH 1/5] Add initial fund tests --- contracts/.snfoundry_cache/.prev_tests_failed | 1 + contracts/src/fund.cairo | 2 +- contracts/tests/test_fund.cairo | 98 +++++++++++++++++++ 3 files changed, 100 insertions(+), 1 deletion(-) create mode 100644 contracts/tests/test_fund.cairo diff --git a/contracts/.snfoundry_cache/.prev_tests_failed b/contracts/.snfoundry_cache/.prev_tests_failed index e69de29..4ba1344 100644 --- a/contracts/.snfoundry_cache/.prev_tests_failed +++ b/contracts/.snfoundry_cache/.prev_tests_failed @@ -0,0 +1 @@ +tests::test_fund::test_set_goal diff --git a/contracts/src/fund.cairo b/contracts/src/fund.cairo index 01a2e8f..f2b2c28 100644 --- a/contracts/src/fund.cairo +++ b/contracts/src/fund.cairo @@ -1,7 +1,7 @@ use starknet::ContractAddress; #[starknet::interface] -trait IFund { +pub trait IFund { fn getId(self: @TContractState) -> u128; fn getOwner(self: @TContractState) -> ContractAddress; fn setName(ref self: TContractState, name: felt252); diff --git a/contracts/tests/test_fund.cairo b/contracts/tests/test_fund.cairo new file mode 100644 index 0000000..0438718 --- /dev/null +++ b/contracts/tests/test_fund.cairo @@ -0,0 +1,98 @@ +// ************************************************************************* +// FUND TEST +// ************************************************************************* +use starknet::{ContractAddress, contract_address_const}; + +use snforge_std::{declare, ContractClassTrait, CheatTarget}; + +use openzeppelin::utils::serde::SerializedAppend; + +use gostarkme::fund::IFundDispatcher; +use gostarkme::fund::IFundDispatcherTrait; + +fn ID() -> u128 { + 1 +} +fn OWNER() -> ContractAddress { + contract_address_const::<'OWNER'>() +} +fn NAME() -> felt252 { + 'NAME_FUND_TEST' +} +fn REASON() -> felt252 { + 'REASON_FUND_TEST' +} +fn GOAL() -> u64 { + 1000 +} +fn __setup__() -> ContractAddress { + let contract = declare("Fund"); + let mut calldata: Array = array![]; + calldata.append_serde(ID()); + calldata.append_serde(OWNER()); + calldata.append_serde(NAME()); + calldata.append_serde(REASON()); + calldata.append_serde(GOAL()); + contract.deploy(@calldata).unwrap() +} +// ************************************************************************* +// TEST +// ************************************************************************* +#[test] +fn test_constructor() { + let contract_address = __setup__(); + let dispatcher = IFundDispatcher { contract_address }; + let id = dispatcher.getId(); + let owner = dispatcher.getOwner(); + let name = dispatcher.getName(); + let reason = dispatcher.getReason(); + let up_votes = dispatcher.getUpVotes(); + let goal = dispatcher.getGoal(); + let current_goal_state = dispatcher.getCurrentGoalState(); + let state = dispatcher.getIsActive(); + assert(id == ID(), 'Invalid id'); + assert(owner == OWNER(), 'Invalid owner'); + assert(name == NAME(), 'Invalid name'); + assert(reason == REASON(), 'Invalid reason'); + assert(up_votes == 1, 'Invalid up votes'); + assert(goal == GOAL(), 'Invalid goal'); + assert(current_goal_state == 0, 'Invalid current goal state'); + assert(state == 1, 'Invalid state'); +} + +#[test] +fn test_set_name() { + let contract_address = __setup__(); + let dispatcher = IFundDispatcher { contract_address }; + let name = dispatcher.getName(); + assert(name == NAME(), 'Invalid name'); + snforge_std::start_prank(CheatTarget::One(contract_address), OWNER()); + dispatcher.setName('NEW_NAME'); + let new_name = dispatcher.getName(); + assert(new_name == 'NEW_NAME', 'Set name method not working') +} + +#[test] +fn test_set_reason() { + let contract_address = __setup__(); + let dispatcher = IFundDispatcher { contract_address }; + let reason = dispatcher.getReason(); + assert(reason == REASON(), 'Invalid reason'); + snforge_std::start_prank(CheatTarget::One(contract_address), OWNER()); + dispatcher.setReason('NEW_REASON'); + let new_reason = dispatcher.getReason(); + assert(new_reason == 'NEW_REASON', 'Set reason method not working') +} + +#[test] +fn test_set_goal() { + let contract_address = __setup__(); + let dispatcher = IFundDispatcher { contract_address }; + let goal = dispatcher.getGoal(); + assert(goal == GOAL(), 'Invalid goal'); + snforge_std::start_prank(CheatTarget::One(contract_address), OWNER()); + dispatcher.setGoal(123); + let new_goal = dispatcher.getGoal(); + assert(new_goal == 123, 'Set goal method not working') +} + From f9426311460f9500cc6f336409f9a62f06c8553f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emmanuel=20Ag=C3=BCero?= <54730752+EmmanuelAR@users.noreply.github.com> Date: Thu, 29 Aug 2024 22:45:31 -0600 Subject: [PATCH 2/5] Changes: Fund upvotes should start as 0 Adding todo in fund First vote adn second register in voters with the correct number --- contracts/src/fund.cairo | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/contracts/src/fund.cairo b/contracts/src/fund.cairo index f2b2c28..c87c90e 100644 --- a/contracts/src/fund.cairo +++ b/contracts/src/fund.cairo @@ -60,7 +60,7 @@ mod Fund { self.owner.write(owner); self.name.write(name); self.reason.write(reason); - self.up_votes.write(1); + self.up_votes.write(0); self.goal.write(goal); self.current_goal_state.write(0); self.state.write(FundStates::RECOLLECTING_VOTES); @@ -98,8 +98,9 @@ mod Fund { assert( self.state.read() == FundStates::RECOLLECTING_VOTES, 'Fund not recollecting votes!' ); - self.voters.write(get_caller_address(), self.up_votes.read()); self.up_votes.write(self.up_votes.read() + 1); + self.voters.write(get_caller_address(), self.up_votes.read()); + // TODO: Validate this if self.up_votes.read() >= 1 { self.state.write(FundStates::RECOLLECTING_DONATIONS); } @@ -129,6 +130,7 @@ mod Fund { fn getCurrentGoalState(self: @ContractState) -> u64 { return self.current_goal_state.read(); } + // TODO: Validate to change method to change setState and getState fn setIsActive(ref self: ContractState, state: u8) { self.state.write(state); } From c53f29087c8f05124500a26689eb63beedc8bd00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emmanuel=20Ag=C3=BCero?= <54730752+EmmanuelAR@users.noreply.github.com> Date: Thu, 29 Aug 2024 22:45:59 -0600 Subject: [PATCH 3/5] Adding recieve votes and recieve dons, all cases --- contracts/.snfoundry_cache/.prev_tests_failed | 1 - contracts/tests/test_fund.cairo | 73 ++++++++++++++++++- 2 files changed, 72 insertions(+), 2 deletions(-) diff --git a/contracts/.snfoundry_cache/.prev_tests_failed b/contracts/.snfoundry_cache/.prev_tests_failed index 4ba1344..e69de29 100644 --- a/contracts/.snfoundry_cache/.prev_tests_failed +++ b/contracts/.snfoundry_cache/.prev_tests_failed @@ -1 +0,0 @@ -tests::test_fund::test_set_goal diff --git a/contracts/tests/test_fund.cairo b/contracts/tests/test_fund.cairo index 0438718..938d36d 100644 --- a/contracts/tests/test_fund.cairo +++ b/contracts/tests/test_fund.cairo @@ -16,6 +16,9 @@ fn ID() -> u128 { fn OWNER() -> ContractAddress { contract_address_const::<'OWNER'>() } +fn OTHER_USER() -> ContractAddress { + contract_address_const::<'USER'>() +} fn NAME() -> felt252 { 'NAME_FUND_TEST' } @@ -54,7 +57,7 @@ fn test_constructor() { assert(owner == OWNER(), 'Invalid owner'); assert(name == NAME(), 'Invalid name'); assert(reason == REASON(), 'Invalid reason'); - assert(up_votes == 1, 'Invalid up votes'); + assert(up_votes == 0, 'Invalid up votes'); assert(goal == GOAL(), 'Invalid goal'); assert(current_goal_state == 0, 'Invalid current goal state'); assert(state == 1, 'Invalid state'); @@ -96,3 +99,71 @@ fn test_set_goal() { assert(new_goal == 123, 'Set goal method not working') } +#[test] +fn test_receive_vote_successful() { + let contract_address = __setup__(); + let dispatcher = IFundDispatcher { contract_address }; + dispatcher.receiveVote(); + let me = dispatcher.getVoter(); + // Owner vote, fund have one vote + assert(me == 1, 'Owner is not in the voters'); + let votes = dispatcher.getUpVotes(); + assert(votes == 1, 'Vote unuseccessful'); +} + +#[test] +#[should_panic(expected: ('User already voted!',))] +fn test_receive_vote_unsuccessful_double_vote() { + let contract_address = __setup__(); + let dispatcher = IFundDispatcher { contract_address }; + dispatcher.receiveVote(); + let me = dispatcher.getVoter(); + // Owner vote, fund have one vote + assert(me == 1, 'Owner is not in the voters'); + let votes = dispatcher.getUpVotes(); + assert(votes == 1, 'Vote unuseccessful'); + // Owner vote, second time + dispatcher.receiveVote(); +} + +#[test] +#[should_panic(expected: ('Fund not recollecting votes!',))] +fn test_receive_vote_unsuccessful_wrong_state() { + let contract_address = __setup__(); + let dispatcher = IFundDispatcher { contract_address }; + // Owner vote, fund have one vote + dispatcher.receiveVote(); + // Other user vote + snforge_std::start_prank(CheatTarget::One(contract_address), OTHER_USER()); + dispatcher.receiveVote(); +} + +#[test] +fn test_receive_donation_successful() { + let contract_address = __setup__(); + let dispatcher = IFundDispatcher { contract_address }; + // Put state as recollecting dons + dispatcher.setIsActive(2); + // Put 10 strks as goal, only owner + snforge_std::start_prank(CheatTarget::One(contract_address), OWNER()); + dispatcher.setGoal(10); + // Donate 5 strks + dispatcher.receiveDonation(5); + let current_goal_state = dispatcher.getCurrentGoalState(); + assert(current_goal_state == 5, 'Receive donation not working'); + // Donate 5 strks, the goal is done + dispatcher.receiveDonation(5); + let state = dispatcher.getIsActive(); + assert(state == 3, 'State should be close'); +} + +#[test] +#[should_panic(expected: ('Fund not recollecting dons!',))] +fn test_receive_donation_unsuccessful_wrong_state() { + let contract_address = __setup__(); + let dispatcher = IFundDispatcher { contract_address }; + // Put a wrong state to receive donations + dispatcher.setIsActive(1); + // Donate + dispatcher.receiveDonation(5); +} From 8c7cabf6d83d257c286ddfe33f781c0bc82aaa9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emmanuel=20Ag=C3=BCero?= <54730752+EmmanuelAR@users.noreply.github.com> Date: Sat, 31 Aug 2024 18:47:57 -0600 Subject: [PATCH 4/5] Add funds constants Add discord channel in readme --- README.md | 4 ++++ contracts/src/constants/funds.cairo | 1 + contracts/src/constants/funds/fund_constants.cairo | 8 ++++++++ contracts/src/fund.cairo | 9 +++++---- 4 files changed, 18 insertions(+), 4 deletions(-) create mode 100644 contracts/src/constants/funds/fund_constants.cairo diff --git a/README.md b/README.md index d13b071..6fdd6ba 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,11 @@ If you are interested in contributing to Go Stark Me, please follow these steps: 2. Comment on the issue you want to participate in, detailing how you plan to address it and how long you expect it to take. 3. Wait to be assigned to the issue. +Official Discord Channel: +- [Web3Wagers](https://discord.gg/sEpnC6JB2U) + You can also contact us on Telegram: - [@adrian_vrj](https://t.me/adrian_vrj) - [@EmmanuelDevCr](https://t.me/EmmanuelDevCr) + diff --git a/contracts/src/constants/funds.cairo b/contracts/src/constants/funds.cairo index 3c57400..a0adbf1 100644 --- a/contracts/src/constants/funds.cairo +++ b/contracts/src/constants/funds.cairo @@ -1 +1,2 @@ pub mod state_constants; +pub mod fund_constants; diff --git a/contracts/src/constants/funds/fund_constants.cairo b/contracts/src/constants/funds/fund_constants.cairo new file mode 100644 index 0000000..eb993f3 --- /dev/null +++ b/contracts/src/constants/funds/fund_constants.cairo @@ -0,0 +1,8 @@ +// ************************************************************************* +// FUND CONSTANTS +// ************************************************************************* +pub mod FundConstants { + pub const UP_VOTES_NEED_IT: u32 = 1; + pub const INITIAL_UP_VOTES: u32 = 0; + pub const INITIAL_GOAL: u64 = 0; +} diff --git a/contracts/src/fund.cairo b/contracts/src/fund.cairo index c87c90e..42fa7a2 100644 --- a/contracts/src/fund.cairo +++ b/contracts/src/fund.cairo @@ -27,6 +27,8 @@ mod Fund { use starknet::ContractAddress; use starknet::get_caller_address; use gostarkme::constants::{funds::{state_constants::FundStates},}; + use gostarkme::constants::{funds::{fund_constants::FundConstants},}; + // ************************************************************************* // STORAGE @@ -60,9 +62,9 @@ mod Fund { self.owner.write(owner); self.name.write(name); self.reason.write(reason); - self.up_votes.write(0); + self.up_votes.write(FundConstants::INITIAL_UP_VOTES); self.goal.write(goal); - self.current_goal_state.write(0); + self.current_goal_state.write(FundConstants::INITIAL_GOAL); self.state.write(FundStates::RECOLLECTING_VOTES); } @@ -100,8 +102,7 @@ mod Fund { ); self.up_votes.write(self.up_votes.read() + 1); self.voters.write(get_caller_address(), self.up_votes.read()); - // TODO: Validate this - if self.up_votes.read() >= 1 { + if self.up_votes.read() >= FundConstants::UP_VOTES_NEED_IT { self.state.write(FundStates::RECOLLECTING_DONATIONS); } } From b056b9dc91dd1d894fe632376db3bd62c348fd53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emmanuel=20Ag=C3=BCero?= <54730752+EmmanuelAR@users.noreply.github.com> Date: Sat, 31 Aug 2024 19:35:17 -0600 Subject: [PATCH 5/5] Fix constant name and remove test because is hard to replicate --- contracts/.snfoundry_cache/.prev_tests_failed | 1 + contracts/src/constants/funds/fund_constants.cairo | 2 +- contracts/src/fund.cairo | 2 +- contracts/tests/test_fund.cairo | 12 ------------ 4 files changed, 3 insertions(+), 14 deletions(-) diff --git a/contracts/.snfoundry_cache/.prev_tests_failed b/contracts/.snfoundry_cache/.prev_tests_failed index e69de29..5d28940 100644 --- a/contracts/.snfoundry_cache/.prev_tests_failed +++ b/contracts/.snfoundry_cache/.prev_tests_failed @@ -0,0 +1 @@ +tests::test_fund::test_receive_vote_unsuccessful_wrong_state diff --git a/contracts/src/constants/funds/fund_constants.cairo b/contracts/src/constants/funds/fund_constants.cairo index eb993f3..7de0d07 100644 --- a/contracts/src/constants/funds/fund_constants.cairo +++ b/contracts/src/constants/funds/fund_constants.cairo @@ -2,7 +2,7 @@ // FUND CONSTANTS // ************************************************************************* pub mod FundConstants { - pub const UP_VOTES_NEED_IT: u32 = 1; + pub const UP_VOTES_NEEDED: u32 = 100; pub const INITIAL_UP_VOTES: u32 = 0; pub const INITIAL_GOAL: u64 = 0; } diff --git a/contracts/src/fund.cairo b/contracts/src/fund.cairo index 42fa7a2..dc33e04 100644 --- a/contracts/src/fund.cairo +++ b/contracts/src/fund.cairo @@ -102,7 +102,7 @@ mod Fund { ); self.up_votes.write(self.up_votes.read() + 1); self.voters.write(get_caller_address(), self.up_votes.read()); - if self.up_votes.read() >= FundConstants::UP_VOTES_NEED_IT { + if self.up_votes.read() >= FundConstants::UP_VOTES_NEEDED { self.state.write(FundStates::RECOLLECTING_DONATIONS); } } diff --git a/contracts/tests/test_fund.cairo b/contracts/tests/test_fund.cairo index 938d36d..c275ec9 100644 --- a/contracts/tests/test_fund.cairo +++ b/contracts/tests/test_fund.cairo @@ -126,18 +126,6 @@ fn test_receive_vote_unsuccessful_double_vote() { dispatcher.receiveVote(); } -#[test] -#[should_panic(expected: ('Fund not recollecting votes!',))] -fn test_receive_vote_unsuccessful_wrong_state() { - let contract_address = __setup__(); - let dispatcher = IFundDispatcher { contract_address }; - // Owner vote, fund have one vote - dispatcher.receiveVote(); - // Other user vote - snforge_std::start_prank(CheatTarget::One(contract_address), OTHER_USER()); - dispatcher.receiveVote(); -} - #[test] fn test_receive_donation_successful() { let contract_address = __setup__();