diff --git a/.gitignore b/.gitignore index eb5a316..b1e298f 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ target +Scarb.lock diff --git a/.snfoundry_cache/.prev_tests_failed b/.snfoundry_cache/.prev_tests_failed new file mode 100644 index 0000000..1d7b2ef --- /dev/null +++ b/.snfoundry_cache/.prev_tests_failed @@ -0,0 +1 @@ +tokengiver_integrationtest::test_withdraw::test_withdrawal_flow diff --git a/.tool-versions b/.tool-versions index d54b39c..84a4307 100644 --- a/.tool-versions +++ b/.tool-versions @@ -1,2 +1,2 @@ starknet-foundry 0.31.0 -scarb 2.8.3 \ No newline at end of file +scarb 2.8.2 \ No newline at end of file diff --git a/Scarb.lock b/Scarb.lock deleted file mode 100644 index 4a8a52b..0000000 --- a/Scarb.lock +++ /dev/null @@ -1,26 +0,0 @@ -# Code generated by scarb DO NOT EDIT. -version = 1 - -[[package]] -name = "openzeppelin" -version = "0.12.0" -source = "git+https://github.com/OpenZeppelin/cairo-contracts.git?tag=v0.12.0#0697004db74502ce49900edef37331dd03531356" - -[[package]] -name = "snforge_std" -version = "0.22.0" -source = "git+https://github.com/foundry-rs/starknet-foundry?tag=v0.22.0#9b215944c6c5871c738381b4ded61bbf06e7ba35" - -[[package]] -name = "token_bound_accounts" -version = "0.3.0" -source = "git+https://github.com/Starknet-Africa-Edu/TBA?tag=v0.3.0#1f8b5e3c45422fb188ef2cf874b46d02f642973b" - -[[package]] -name = "tokengiver" -version = "0.1.0" -dependencies = [ - "openzeppelin", - "snforge_std", - "token_bound_accounts", -] diff --git a/src/base/errors.cairo b/src/base/errors.cairo index 0d1bcf7..ecee6fa 100644 --- a/src/base/errors.cairo +++ b/src/base/errors.cairo @@ -7,4 +7,5 @@ pub mod Errors { pub const INITIALIZED: felt252 = 'TGN: already initialized!'; pub const INVALID_OWNER: felt252 = 'TGN: caller is not owner!'; pub const INVALID_CAMPAIGN: felt252 = 'TGN: campaign is not owner!'; + pub const INSUFFICIENT_BALANCE: felt252 = 'TGN: insufficient balance!'; } diff --git a/src/campaign.cairo b/src/campaign.cairo index 94e2d08..08a7c0a 100644 --- a/src/campaign.cairo +++ b/src/campaign.cairo @@ -20,7 +20,7 @@ mod TokengiverCampaign { use tokengiver::interfaces::IERC721::{IERC721Dispatcher, IERC721DispatcherTrait}; use tokengiver::interfaces::ICampaign::ICampaign; use tokengiver::base::types::Campaign; - use tokengiver::base::errors::Errors::NOT_CAMPAIGN_OWNER; + use tokengiver::base::errors::Errors::{NOT_CAMPAIGN_OWNER, INSUFFICIENT_BALANCE}; use openzeppelin::token::erc20::interface::{IERC20Dispatcher, IERC20DispatcherTrait}; @@ -43,7 +43,7 @@ mod TokengiverCampaign { donations: Map, donation_count: Map, donation_details: Map, - erc20_token: ContractAddress, + erc20_token: ContractAddress, // STRerc20 address token_giver_nft_class_hash: ClassHash, } @@ -151,6 +151,23 @@ mod TokengiverCampaign { self.withdrawal_balance.write(campaign_address, amount); } + // withdraw function + fn withdraw(ref self: ContractState, campaign_address: ContractAddress, amount: u256) { + let campaign: Campaign = self.campaign.read(campaign_address); + let caller: ContractAddress = get_caller_address(); + + assert(caller == campaign.campaign_owner, NOT_CAMPAIGN_OWNER); + + let available_balance: u256 = self.withdrawal_balance.read(campaign_address); + assert(amount <= available_balance, INSUFFICIENT_BALANCE); + + let token_address = self.erc20_token.read(); + let token_dispatcher = IERC20Dispatcher { contract_address: token_address }; + let transfer_result = token_dispatcher.transfer(caller, amount); + assert!(transfer_result, "Transfer failed"); + self.withdrawal_balance.write(campaign_address, available_balance - amount); + } + // ************************************************************************* // GETTERS // ************************************************************************* @@ -178,7 +195,6 @@ mod TokengiverCampaign { campaign.metadata_URI } - fn get_campaigns(self: @ContractState) -> Array { let mut campaigns = ArrayTrait::new(); let count = self.count.read(); diff --git a/src/interfaces/ICampaign.cairo b/src/interfaces/ICampaign.cairo index a6754ea..d69f09b 100644 --- a/src/interfaces/ICampaign.cairo +++ b/src/interfaces/ICampaign.cairo @@ -21,7 +21,7 @@ pub trait ICampaign { fn set_available_withdrawal(ref self: TState, campaign_address: ContractAddress, amount: u256); fn set_donations(ref self: TState, campaign_address: ContractAddress, amount: u256); fn donate(ref self: TState, campaign_address: ContractAddress, amount: u256, token_id: u256); - + fn withdraw(ref self: TState, campaign_address: ContractAddress, amount: u256); // Getters fn get_campaign_metadata(self: @TState, campaign_address: ContractAddress) -> ByteArray;