Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions contracts/reward-pool/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,13 @@ pub struct RewardDistributed {
pub amount: i128,
}

#[contractevent]
pub struct PoolFunded {
#[topic]
pub donor: Address,
pub amount: i128,
}

#[contractimpl]
impl RewardPool {
/// Initializes the RewardPool contract with admin and token addresses.
Expand Down Expand Up @@ -149,6 +156,37 @@ impl RewardPool {
}
.publish(&env);
}

/// Funds the reward pool with tokens from a donor.
///
/// # Arguments
/// * `donor` - The address donating the tokens
/// * `amount` - The amount of tokens to donate
///
/// # Panics
/// * If contract is not initialized
/// * If donor authentication fails
/// * If token transfer fails
pub fn fund_pool(env: Env, donor: Address, amount: i128) {
// 1. donor.require_auth()
donor.require_auth();

// 2. Fetch 'Token_Address' from Instance storage
let token_id: Address = env
.storage()
.instance()
.get(&DataKey::Token)
.expect("Not initialized");

// 3. Initialize token::Client::new(&env, &Token_Address)
let token_client = token::Client::new(&env, &token_id);

// 4. Call token_client.transfer(&donor, &env.current_contract_address(), &amount)
token_client.transfer(&donor, env.current_contract_address(), &amount);

// 5. Emit PoolFunded event
PoolFunded { donor, amount }.publish(&env);
}
}

mod test;
133 changes: 133 additions & 0 deletions contracts/reward-pool/src/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -313,3 +313,136 @@ fn test_distribute_reward_multiple_spenders() {

assert_eq!(token_client.balance(&learner), 150);
}

// ── fund_pool Tests ───────────────────────────────────────────────────────────

#[test]
fn test_fund_pool_success() {
let (env, client) = setup();
let admin = Address::generate(&env);
let donor = Address::generate(&env);
let token_id = env.register_stellar_asset_contract_v2(admin.clone());

// Initialize the reward pool
client.initialize(&admin, &token_id.address());

// Mint tokens to the donor
let token_client = token::StellarAssetClient::new(&env, &token_id.address());
token_client.mint(&donor, &1000);

// Fund the pool
client.fund_pool(&donor, &500);

// Verify donor's balance decreased
assert_eq!(token_client.balance(&donor), 500);

// Verify contract's balance increased
assert_eq!(token_client.balance(&client.address), 500);
}

#[test]
fn test_fund_pool_emits_event() {
let (env, client) = setup();
let admin = Address::generate(&env);
let donor = Address::generate(&env);
let token_id = env.register_stellar_asset_contract_v2(admin.clone());

client.initialize(&admin, &token_id.address());

let token_client = token::StellarAssetClient::new(&env, &token_id.address());
token_client.mint(&donor, &1000);

client.fund_pool(&donor, &300);

// Verify event was emitted
let last_event = env.events().all().last().unwrap();

let mut data_map = Map::new(&env);
data_map.set(Symbol::new(&env, "amount"), 300i128);
let expected_event: (Address, Vec<Val>, Val) = (
client.address,
(Symbol::new(&env, "pool_funded"), &donor).into_val(&env),
data_map.into_val(&env),
);

assert_eq!(
vec![&env, last_event.clone()],
vec![&env, expected_event.clone()]
);
}

#[test]
#[should_panic(expected = "Not initialized")]
fn test_fund_pool_not_initialized() {
let (env, client) = setup();
let donor = Address::generate(&env);

// Try to fund without initializing - should panic
client.fund_pool(&donor, &100);
}

#[test]
fn test_fund_pool_multiple_donors() {
let (env, client) = setup();
let admin = Address::generate(&env);
let donor1 = Address::generate(&env);
let donor2 = Address::generate(&env);
let token_id = env.register_stellar_asset_contract_v2(admin.clone());

client.initialize(&admin, &token_id.address());

let token_client = token::StellarAssetClient::new(&env, &token_id.address());
token_client.mint(&donor1, &1000);
token_client.mint(&donor2, &1000);

// Multiple donors fund the pool
client.fund_pool(&donor1, &500);
client.fund_pool(&donor2, &300);

// Verify balances
assert_eq!(token_client.balance(&donor1), 500);
assert_eq!(token_client.balance(&donor2), 700);
assert_eq!(token_client.balance(&client.address), 800);
}

#[test]
fn test_fund_pool_multiple_times() {
let (env, client) = setup();
let admin = Address::generate(&env);
let donor = Address::generate(&env);
let token_id = env.register_stellar_asset_contract_v2(admin.clone());

client.initialize(&admin, &token_id.address());

let token_client = token::StellarAssetClient::new(&env, &token_id.address());
token_client.mint(&donor, &2000);

// Donor funds multiple times
client.fund_pool(&donor, &500);
client.fund_pool(&donor, &300);
client.fund_pool(&donor, &200);

// Verify balances
assert_eq!(token_client.balance(&donor), 1000);
assert_eq!(token_client.balance(&client.address), 1000);
}

#[test]
fn test_fund_pool_zero_amount() {
let (env, client) = setup();
let admin = Address::generate(&env);
let donor = Address::generate(&env);
let token_id = env.register_stellar_asset_contract_v2(admin.clone());

client.initialize(&admin, &token_id.address());

let token_client = token::StellarAssetClient::new(&env, &token_id.address());
token_client.mint(&donor, &1000);

// Fund with zero amount (should succeed)
client.fund_pool(&donor, &0);

// Verify balances unchanged
assert_eq!(token_client.balance(&donor), 1000);
assert_eq!(token_client.balance(&client.address), 0);
}
Loading