reward dist
This commit is contained in:
parent
364b01c2d3
commit
3a9fa10f43
|
|
@ -34,3 +34,9 @@ pub enum LeaderboardError {
|
||||||
#[msg("Not active")]
|
#[msg("Not active")]
|
||||||
NotActive,
|
NotActive,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[error_code]
|
||||||
|
pub enum ArithmeticError {
|
||||||
|
#[msg("Arithmetic error")]
|
||||||
|
ArithmeticError,
|
||||||
|
}
|
||||||
|
|
@ -1,8 +1,7 @@
|
||||||
use anchor_lang::prelude::*;
|
use anchor_lang::prelude::*;
|
||||||
use anchor_spl::{associated_token::AssociatedToken, token::{transfer_checked, TransferChecked}, token_interface::{TokenAccount, TokenInterface}};
|
use anchor_spl::{associated_token::AssociatedToken, token::{transfer_checked, TransferChecked}, token_interface::{TokenAccount, TokenInterface}};
|
||||||
use crate::{error::BettingError, *};
|
use crate::*;
|
||||||
use crate::constants::TICKET_SALE_VAULT_ADDRESS;
|
|
||||||
use std::str::FromStr;
|
|
||||||
|
|
||||||
pub fn buy(ctx: Context<BuyTickets>, amount: u64) -> Result<()> {
|
pub fn buy(ctx: Context<BuyTickets>, amount: u64) -> Result<()> {
|
||||||
|
|
||||||
|
|
@ -10,7 +9,7 @@ pub fn buy(ctx: Context<BuyTickets>, amount: u64) -> Result<()> {
|
||||||
|
|
||||||
let ix = anchor_lang::solana_program::system_instruction::transfer(
|
let ix = anchor_lang::solana_program::system_instruction::transfer(
|
||||||
&ctx.accounts.payer.key(),
|
&ctx.accounts.payer.key(),
|
||||||
&ctx.accounts.ticket_sale_vault.key(),
|
&ctx.accounts.ticket_leaderboard_list.key(),
|
||||||
transfer_amount
|
transfer_amount
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -18,7 +17,7 @@ pub fn buy(ctx: Context<BuyTickets>, amount: u64) -> Result<()> {
|
||||||
&ix,
|
&ix,
|
||||||
&[
|
&[
|
||||||
ctx.accounts.payer.to_account_info(),
|
ctx.accounts.payer.to_account_info(),
|
||||||
ctx.accounts.ticket_sale_vault.to_account_info(),
|
ctx.accounts.ticket_leaderboard_list.to_account_info(),
|
||||||
],
|
],
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
|
@ -49,14 +48,6 @@ pub struct BuyTickets<'info>{
|
||||||
#[account(mut)]
|
#[account(mut)]
|
||||||
pub payer: Signer<'info>,
|
pub payer: Signer<'info>,
|
||||||
|
|
||||||
|
|
||||||
/// CHECK: The vault that receives SOL payments for tickets
|
|
||||||
#[account(
|
|
||||||
mut,
|
|
||||||
address = Pubkey::from_str(TICKET_SALE_VAULT_ADDRESS).unwrap() @ BettingError::InvalidTicketSaleVault
|
|
||||||
)]
|
|
||||||
pub ticket_sale_vault: AccountInfo<'info>,
|
|
||||||
|
|
||||||
#[account(
|
#[account(
|
||||||
mut,
|
mut,
|
||||||
seeds = [TICKET_LEADERBOARD_LIST_SEED],
|
seeds = [TICKET_LEADERBOARD_LIST_SEED],
|
||||||
|
|
|
||||||
|
|
@ -51,3 +51,6 @@ pub use enter_leaderboard::*;
|
||||||
|
|
||||||
pub mod remove_leaderboard;
|
pub mod remove_leaderboard;
|
||||||
pub use remove_leaderboard::*;
|
pub use remove_leaderboard::*;
|
||||||
|
|
||||||
|
pub mod reward_leaderboard;
|
||||||
|
pub use reward_leaderboard::*;
|
||||||
109
programs/bets/src/instructions/reward_leaderboard.rs
Normal file
109
programs/bets/src/instructions/reward_leaderboard.rs
Normal file
|
|
@ -0,0 +1,109 @@
|
||||||
|
use anchor_lang::prelude::*;
|
||||||
|
use anchor_spl::{associated_token::AssociatedToken, token::{transfer_checked, TransferChecked}, token_interface::{TokenAccount, TokenInterface}};
|
||||||
|
use crate::{error::ArithmeticError, *};
|
||||||
|
|
||||||
|
pub fn reward(ctx:Context<RewardLeaderboard>, id:u64)->Result<()>{
|
||||||
|
|
||||||
|
let leaderboard = &mut ctx.accounts.ticket_leaderboard;
|
||||||
|
|
||||||
|
let ticket_leaderboard_vault = &ctx.accounts.ticket_leaderboard_vault;
|
||||||
|
let ticket_leaderboard_list_vault = &ctx.accounts.ticket_leaderboard_list_vault;
|
||||||
|
let winner = &ctx.accounts.winner;
|
||||||
|
|
||||||
|
// Get the token balance in the ticket_leaderboard vault
|
||||||
|
let token_balance = ticket_leaderboard_vault.amount;
|
||||||
|
|
||||||
|
// Calculate SOL reward: each token is worth 0.1 SOL (100,000,000 lamports)
|
||||||
|
let sol_reward = match token_balance.checked_mul(100_000_000) {
|
||||||
|
Some(reward) => reward,
|
||||||
|
None => return Err(Error::from(ArithmeticError::ArithmeticError)),
|
||||||
|
};
|
||||||
|
|
||||||
|
// Transfer SOL from ticket_leaderboard_list to winner
|
||||||
|
let ix = anchor_lang::solana_program::system_instruction::transfer(
|
||||||
|
&ctx.accounts.ticket_leaderboard_list.key(),
|
||||||
|
&winner.key(),
|
||||||
|
sol_reward
|
||||||
|
);
|
||||||
|
|
||||||
|
anchor_lang::solana_program::program::invoke(
|
||||||
|
&ix,
|
||||||
|
&[
|
||||||
|
ctx.accounts.ticket_leaderboard_list.to_account_info(),
|
||||||
|
winner.to_account_info(),
|
||||||
|
],
|
||||||
|
)?;
|
||||||
|
|
||||||
|
// Transfer all tokens from ticket_leaderboard vault to ticket_leaderboard_list vault
|
||||||
|
let cpi_program = ctx.accounts.token_program.to_account_info();
|
||||||
|
let cpi_accounts = TransferChecked {
|
||||||
|
from: ticket_leaderboard_vault.to_account_info(),
|
||||||
|
to: ticket_leaderboard_list_vault.to_account_info(),
|
||||||
|
authority: leaderboard.to_account_info(),
|
||||||
|
mint: ctx.accounts.token_mint.to_account_info(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let seeds = &[
|
||||||
|
TICKET_LEADERBOARD_SEED,
|
||||||
|
&id.to_le_bytes()[..],
|
||||||
|
&[ctx.bumps.ticket_leaderboard][..]
|
||||||
|
];
|
||||||
|
let signer_seeds = &[&seeds[..]];
|
||||||
|
|
||||||
|
let cpi_ctx = CpiContext::new_with_signer(cpi_program, cpi_accounts, signer_seeds);
|
||||||
|
transfer_checked(cpi_ctx, token_balance, ctx.accounts.token_mint.decimals)?;
|
||||||
|
|
||||||
|
leaderboard.is_over = true;
|
||||||
|
|
||||||
|
msg!("Successfully rewarded winner with {} SOL and transferred {} tokens to leaderboard list",
|
||||||
|
sol_reward as f64 / 1_000_000_000.0, token_balance);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Accounts)]
|
||||||
|
#[instruction(id:u64)]
|
||||||
|
pub struct RewardLeaderboard<'info>{
|
||||||
|
#[account(mut)]
|
||||||
|
pub payer: Signer<'info>,
|
||||||
|
|
||||||
|
/// CHECK: The winner account
|
||||||
|
#[account(mut)]
|
||||||
|
pub winner: AccountInfo<'info>,
|
||||||
|
|
||||||
|
#[account(
|
||||||
|
mut,
|
||||||
|
seeds = [TICKET_LEADERBOARD_LIST_SEED],
|
||||||
|
bump
|
||||||
|
)]
|
||||||
|
pub ticket_leaderboard_list: Account<'info, TicketLeaderboardList>,
|
||||||
|
|
||||||
|
#[account(
|
||||||
|
mut,
|
||||||
|
seeds = [TICKET_LEADERBOARD_SEED, id.to_le_bytes().as_ref()],
|
||||||
|
bump
|
||||||
|
)]
|
||||||
|
pub ticket_leaderboard: Account<'info, TicketLeaderboard>,
|
||||||
|
|
||||||
|
#[account(
|
||||||
|
mut,
|
||||||
|
associated_token::mint = token_mint,
|
||||||
|
associated_token::authority = ticket_leaderboard,
|
||||||
|
associated_token::token_program = token_program
|
||||||
|
)]
|
||||||
|
pub ticket_leaderboard_vault: InterfaceAccount<'info, TokenAccount>,
|
||||||
|
|
||||||
|
#[account(
|
||||||
|
mut,
|
||||||
|
associated_token::mint = token_mint,
|
||||||
|
associated_token::authority = ticket_leaderboard_list,
|
||||||
|
associated_token::token_program = token_program
|
||||||
|
)]
|
||||||
|
pub ticket_leaderboard_list_vault: InterfaceAccount<'info, TokenAccount>,
|
||||||
|
|
||||||
|
pub token_mint: InterfaceAccount<'info, anchor_spl::token_interface::Mint>,
|
||||||
|
|
||||||
|
pub system_program: Program<'info, System>,
|
||||||
|
pub token_program: Interface<'info, TokenInterface>,
|
||||||
|
pub associated_token_program: Program<'info, AssociatedToken>,
|
||||||
|
}
|
||||||
|
|
@ -83,5 +83,9 @@ pub mod bets {
|
||||||
remove_leaderboard::remove(ctx, id)
|
remove_leaderboard::remove(ctx, id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn reward_leaderboard(ctx:Context<RewardLeaderboard>, id:u64)->Result<()>{
|
||||||
|
reward_leaderboard::reward(ctx, id)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user