use std::str::FromStr; use anchor_lang::prelude::*; use crate::{error::BettingError, *}; pub fn close(ctx: Context, winner:Pubkey, userid:String)->Result<()>{ let bet_vault = &mut ctx.accounts.bet_vault; require!( bet_vault.owner == winner || bet_vault.joiner == winner || bet_vault.owner_id == userid || bet_vault.joiner_id == userid, BettingError::InvalidWinner ); let fee_collector_pubkey = Pubkey::from_str(FEE_COLLECTOR).map_err(|_| BettingError::InvalidFeeCollector)?; require_keys_eq!( ctx.accounts.fee_wallet.key(), fee_collector_pubkey, BettingError::InvalidFeeCollector ); // Calculate the 5% fee let total_lamports = **bet_vault.to_account_info().lamports.borrow(); msg!("Total lamports: {}", total_lamports); let fee = total_lamports / 40; // 2.5% let referrer_fee = total_lamports / 80; //1.25% for each referrer msg!("Fee: {}, Referrer fee: {}", fee, referrer_fee); msg!("Total to be sent: {}", fee + referrer_fee + referrer_fee); // Verify we have enough funds for all transfers let total_transfer = fee.checked_add(referrer_fee) .and_then(|sum| sum.checked_add(referrer_fee)) .ok_or(BettingError::InsufficientFunds)?; require!( total_transfer <= total_lamports, BettingError::InsufficientFunds ); // Transfer referrer fees **bet_vault.to_account_info().try_borrow_mut_lamports()? -= referrer_fee; **ctx.accounts.owner_referrer.try_borrow_mut_lamports()? += referrer_fee; msg!("After owner referrer transfer - Vault balance: {}", **bet_vault.to_account_info().lamports.borrow()); **bet_vault.to_account_info().try_borrow_mut_lamports()? -= referrer_fee; **ctx.accounts.joiner_referrer.try_borrow_mut_lamports()? += referrer_fee; msg!("After joiner referrer transfer - Vault balance: {}", **bet_vault.to_account_info().lamports.borrow()); **bet_vault.to_account_info().try_borrow_mut_lamports()? -= fee; **ctx.accounts.fee_wallet.to_account_info().try_borrow_mut_lamports()? += fee; msg!("After fee transfer - Vault balance: {}", **bet_vault.to_account_info().lamports.borrow()); // Transfer remaining balance to winner let remaining_balance = **bet_vault.to_account_info().lamports.borrow(); **bet_vault.to_account_info().try_borrow_mut_lamports()? -= remaining_balance; **ctx.accounts.winner.try_borrow_mut_lamports()? += remaining_balance; msg!("After winner transfer - Vault balance: {}", **bet_vault.to_account_info().lamports.borrow()); let bets_list = &mut ctx.accounts.bets_list; // Remove the bet_vault public key from the list bets_list.bets.retain(|&bet| bet != bet_vault.key()); msg!("Bet {} closed by {}", bet_vault.key(), winner); Ok(()) } #[derive(Accounts)] pub struct CloseBet<'info>{ #[account(mut)] pub bets_list: Account<'info, BetsList>, #[account(mut)] pub bet_vault: Account<'info, BetVault>, /// CHECK: This is validated against the FEE_COLLECTOR constant. #[account(mut)] pub fee_wallet: AccountInfo<'info>, #[account(mut)] pub winner: SystemAccount<'info>, #[account(mut)] pub payer: Signer<'info>, /// CHECK: No constraints are applied to this account. #[account(mut)] pub owner_referrer: AccountInfo<'info>, /// CHECK: No constraints are applied to this account. #[account(mut)] pub joiner_referrer: AccountInfo<'info>, pub system_program: Program<'info, System> }