duelfi_bets_anchor/programs/bets/src/instructions/close_bet.rs
2025-05-20 15:47:01 +00:00

94 lines
3.5 KiB
Rust

use std::str::FromStr;
use anchor_lang::prelude::*;
use crate::{error::BettingError, *};
pub fn close(ctx: Context<CloseBet>, 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>
}