diff --git a/contracts/bounty/src/lib.rs b/contracts/bounty/src/lib.rs index bc5f37f..d5b0ecd 100644 --- a/contracts/bounty/src/lib.rs +++ b/contracts/bounty/src/lib.rs @@ -29,6 +29,32 @@ impl BountyContract { env.storage().persistent().set(&key, &bounty); } + pub fn claim_bounty( + env: Env, + token: Address, + maintainer: Address, + contributor: Address, + issue_id: Symbol, + ) { + maintainer.require_auth(); + + let key = (symbol_short!("bounty"), issue_id); + let mut bounty: Map = env + .storage() + .persistent() + .get(&key) + .unwrap_or(Map::new(&env)); + let amount = bounty + .get(maintainer.clone()) + .unwrap_or_else(|| panic!("No bounty exists for this issue and maintainer")); + + let client = token::Client::new(&env, &token); + client.transfer(&env.current_contract_address(), &contributor, &amount); + + bounty.remove(maintainer); + env.storage().persistent().set(&key, &bounty); + } + pub fn cancel_bounty(env: Env, token: Address, maintainer: Address, amount: i128) { maintainer.require_auth(); let client = token::Client::new(&env, &token); diff --git a/contracts/bounty/src/test.rs b/contracts/bounty/src/test.rs index 269a643..d30feeb 100644 --- a/contracts/bounty/src/test.rs +++ b/contracts/bounty/src/test.rs @@ -1,39 +1,16 @@ #![cfg(test)] use super::{BountyContract, BountyContractClient}; -use soroban_sdk::testutils::Address as _; use soroban_sdk::{symbol_short, token, Address, Env}; +use soroban_sdk::testutils::Address as _; #[test] -fn tip_transfers_tokens_from_sender_to_receiver() { - let env = Env::default(); - env.mock_all_auths(); - - let sender = Address::generate(&env); - let receiver = Address::generate(&env); - let token_admin = Address::generate(&env); - - let token_address = env.register_stellar_asset_contract_v2(token_admin); - let token = token::Client::new(&env, &token_address.address()); - let token_admin_client = token::StellarAssetClient::new(&env, &token_address.address()); - - token_admin_client.mint(&sender, &1_000); - - let contract_id = env.register(BountyContract, ()); - let client = BountyContractClient::new(&env, &contract_id); - - client.tip(&token_address.address(), &sender, &receiver, &250); - - assert_eq!(token.balance(&sender), 750); - assert_eq!(token.balance(&receiver), 250); -} - -#[test] -fn create_bounty_locks_maintainer_funds_in_contract() { +fn claim_bounty_releases_locked_balance_and_clears_bounty() { let env = Env::default(); env.mock_all_auths(); let maintainer = Address::generate(&env); + let contributor = Address::generate(&env); let token_admin = Address::generate(&env); let token_address = env.register_stellar_asset_contract_v2(token_admin); @@ -45,36 +22,21 @@ fn create_bounty_locks_maintainer_funds_in_contract() { let contract_id = env.register(BountyContract, ()); let client = BountyContractClient::new(&env, &contract_id); - client.create_bounty(&token_address.address(), &maintainer, &symbol_short!("iss1"), &300); + let issue_id = symbol_short!("iss1"); + client.create_bounty(&token_address.address(), &maintainer, &issue_id, &300); - assert_eq!(token.balance(&maintainer), 200); + assert_eq!(token.balance(&maintainer), 700); assert_eq!(token.balance(&contract_id), 300); -} -#[test] -#[should_panic(expected = "Bounty already exists for this issue and maintainer")] -fn create_bounty_rejects_duplicate_issue_for_same_maintainer() { - let env = Env::default(); - env.mock_all_auths(); - - let maintainer = Address::generate(&env); - let token_admin = Address::generate(&env); + client.claim_bounty(&token_address.address(), &maintainer, &contributor, &issue_id); - let token_address = env.register_stellar_asset_contract_v2(token_admin); - let token_admin_client = token::StellarAssetClient::new(&env, &token_address.address()); - - token_admin_client.mint(&maintainer, &1_000); - - let contract_id = env.register(BountyContract, ()); - let client = BountyContractClient::new(&env, &contract_id); - - let issue_id = symbol_short!("iss2"); - client.create_bounty(&token_address.address(), &maintainer, &issue_id, &100); - client.create_bounty(&token_address.address(), &maintainer, &issue_id, &150); + assert_eq!(token.balance(&contract_id), 0); + assert_eq!(token.balance(&contributor), 300); } #[test] -fn cancel_bounty_returns_funds_to_maintainer() { +#[should_panic(expected = "No bounty exists for this issue and maintainer")] +fn claim_bounty_cannot_be_executed_twice() { let env = Env::default(); env.mock_all_auths();