From 2d37c20ecef06584d8b4111b3f5cb80574068857 Mon Sep 17 00:00:00 2001 From: Nenad Date: Thu, 13 Jun 2024 17:20:22 +0200 Subject: [PATCH] add test for withdraw --- .../crowdfunding/src/campaign.cairo | 7 +- .../crowdfunding/src/mock_upgrade.cairo | 10 ++- .../applications/crowdfunding/src/tests.cairo | 83 +++++++++++++++++++ 3 files changed, 94 insertions(+), 6 deletions(-) diff --git a/listings/applications/crowdfunding/src/campaign.cairo b/listings/applications/crowdfunding/src/campaign.cairo index 8e9bf9f3..0e272e65 100644 --- a/listings/applications/crowdfunding/src/campaign.cairo +++ b/listings/applications/crowdfunding/src/campaign.cairo @@ -35,7 +35,7 @@ pub trait ICampaign { fn start(ref self: TContractState, duration: u64); fn refund(ref self: TContractState, contributor: ContractAddress, reason: ByteArray); fn upgrade(ref self: TContractState, impl_hash: ClassHash, new_duration: Option); - fn withdraw(ref self: TContractState); + fn withdraw(ref self: TContractState, reason: ByteArray); } #[starknet::contract] @@ -136,6 +136,7 @@ pub mod Campaign { #[key] pub contributor: ContractAddress, pub amount: u256, + pub reason: ByteArray, } pub mod Errors { @@ -330,7 +331,7 @@ pub mod Campaign { self.emit(Event::Upgraded(Upgraded { implementation: impl_hash })); } - fn withdraw(ref self: ContractState) { + fn withdraw(ref self: ContractState, reason: ByteArray) { assert(self.status.read() != Status::DRAFT, Errors::STILL_DRAFT); assert(self.status.read() != Status::SUCCESSFUL, Errors::ENDED); assert(self.status.read() != Status::CLOSED, Errors::CLOSED); @@ -340,7 +341,7 @@ pub mod Campaign { let contributor = get_caller_address(); let amount = self._refund(contributor); - self.emit(Event::Withdrawn(Withdrawn { contributor, amount })); + self.emit(Event::Withdrawn(Withdrawn { contributor, amount, reason })); } } diff --git a/listings/applications/crowdfunding/src/mock_upgrade.cairo b/listings/applications/crowdfunding/src/mock_upgrade.cairo index 53c5f2e3..300bdff0 100644 --- a/listings/applications/crowdfunding/src/mock_upgrade.cairo +++ b/listings/applications/crowdfunding/src/mock_upgrade.cairo @@ -36,6 +36,7 @@ pub mod MockUpgrade { status: Status } + #[event] #[derive(Drop, starknet::Event)] pub enum Event { @@ -70,6 +71,7 @@ pub mod MockUpgrade { #[derive(Drop, starknet::Event)] pub struct Closed { pub reason: ByteArray, + pub status: Status, } #[derive(Drop, starknet::Event)] @@ -95,6 +97,7 @@ pub mod MockUpgrade { #[key] pub contributor: ContractAddress, pub amount: u256, + pub reason: ByteArray, } #[constructor] @@ -157,8 +160,9 @@ pub mod MockUpgrade { } self._refund_all(reason.clone()); + let status = self.status.read(); - self.emit(Event::Closed(Closed { reason })); + self.emit(Event::Closed(Closed { reason, status })); } fn contribute(ref self: ContractState, amount: u256) { @@ -265,7 +269,7 @@ pub mod MockUpgrade { self.emit(Event::Upgraded(Upgraded { implementation: impl_hash })); } - fn withdraw(ref self: ContractState) { + fn withdraw(ref self: ContractState, reason: ByteArray) { assert(self.status.read() != Status::DRAFT, Errors::STILL_DRAFT); assert(self.status.read() != Status::SUCCESSFUL, Errors::ENDED); assert(self.status.read() != Status::CLOSED, Errors::CLOSED); @@ -281,7 +285,7 @@ pub mod MockUpgrade { let success = self.token.read().transfer(contributor, amount); assert(success, Errors::TRANSFER_FAILED); - self.emit(Event::Withdrawn(Withdrawn { contributor, amount })); + self.emit(Event::Withdrawn(Withdrawn { contributor, amount, reason })); } } diff --git a/listings/applications/crowdfunding/src/tests.cairo b/listings/applications/crowdfunding/src/tests.cairo index 0c286ded..efb052b1 100644 --- a/listings/applications/crowdfunding/src/tests.cairo +++ b/listings/applications/crowdfunding/src/tests.cairo @@ -387,3 +387,86 @@ fn test_close() { ] ); } + +#[test] +fn test_refund() { + // setup + let duration: u64 = 60; + let (campaign, token) = deploy_with_token( + declare("Campaign").unwrap(), declare("ERC20").unwrap() + ); + let mut spy = spy_events(SpyOn::One(campaign.contract_address)); + let creator = contract_address_const::<'creator'>(); + let contributor = contract_address_const::<'contributor_1'>(); + let amount: u256 = 3000; + let prev_balance = token.balance_of(contributor); + + // donate + start_cheat_caller_address(campaign.contract_address, creator); + campaign.start(duration); + start_cheat_caller_address(campaign.contract_address, contributor); + campaign.contribute(amount); + assert_eq!(campaign.get_details().total_contributions, amount); + assert_eq!(campaign.get_contribution(contributor), amount); + assert_eq!(token.balance_of(contributor), prev_balance - amount); + + // refund + start_cheat_caller_address(campaign.contract_address, creator); + campaign.refund(contributor, "testing"); + assert_eq!(campaign.get_details().total_contributions, 0); + assert_eq!(campaign.get_contribution(contributor), 0); + assert_eq!(token.balance_of(contributor), prev_balance); + + spy + .assert_emitted( + @array![ + ( + campaign.contract_address, + Campaign::Event::Refunded( + Campaign::Refunded { contributor, amount, reason: "testing" } + ) + ) + ] + ); +} + +#[test] +fn test_withdraw() { + // setup + let duration: u64 = 60; + let (campaign, token) = deploy_with_token( + declare("Campaign").unwrap(), declare("ERC20").unwrap() + ); + let mut spy = spy_events(SpyOn::One(campaign.contract_address)); + let creator = contract_address_const::<'creator'>(); + let contributor = contract_address_const::<'contributor_1'>(); + let amount: u256 = 3000; + let prev_balance = token.balance_of(contributor); + start_cheat_caller_address(campaign.contract_address, creator); + campaign.start(duration); + + // donate + start_cheat_caller_address(campaign.contract_address, contributor); + campaign.contribute(amount); + assert_eq!(campaign.get_details().total_contributions, amount); + assert_eq!(campaign.get_contribution(contributor), amount); + assert_eq!(token.balance_of(contributor), prev_balance - amount); + + // withdraw + campaign.withdraw("testing"); + assert_eq!(campaign.get_details().total_contributions, 0); + assert_eq!(campaign.get_contribution(contributor), 0); + assert_eq!(token.balance_of(contributor), prev_balance); + + spy + .assert_emitted( + @array![ + ( + campaign.contract_address, + Campaign::Event::Withdrawn( + Campaign::Withdrawn { contributor, amount, reason: "testing" } + ) + ) + ] + ); +}