feat: миграция smart-updown на anchor 0.31.1 + solana 2.x (SBPFv3)
- anchor-lang 0.31.1 вместо 2.0-rc/anchor-next (git) - Address -> Pubkey (state/events/instructions) - убран #[discrim], добавлен #[derive(InitSpace)] + space=8+INIT_SPACE - тесты переписаны на solana-program-test 2.x (10 passed) - сборка SBPFv3 через cargo build-sbf --tools-version v1.57 - deploy успешен в нашу сеть (agave 4.2.2, SBPFv3)
This commit is contained in:
@@ -2,8 +2,8 @@ use anchor_lang::prelude::*;
|
||||
|
||||
#[event]
|
||||
pub struct BetCreated {
|
||||
pub bet: Address,
|
||||
pub bettor: Address,
|
||||
pub bet: Pubkey,
|
||||
pub bettor: Pubkey,
|
||||
pub side: u64,
|
||||
pub amount: u64,
|
||||
pub bet_time: i64,
|
||||
@@ -13,7 +13,7 @@ pub struct BetCreated {
|
||||
|
||||
#[event]
|
||||
pub struct BetClosed {
|
||||
pub bet: Address,
|
||||
pub bet: Pubkey,
|
||||
pub exit_price: u64,
|
||||
pub user_won: bool,
|
||||
pub payout: u64,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use anchor_lang::{prelude::*, Lamports};
|
||||
use anchor_lang::prelude::*;
|
||||
|
||||
use crate::{
|
||||
constants::{
|
||||
@@ -12,33 +12,33 @@ use crate::{
|
||||
|
||||
#[derive(Accounts)]
|
||||
#[instruction(id: u64, exit_price: u64)]
|
||||
pub struct CloseBet {
|
||||
pub relayer: Signer,
|
||||
pub struct CloseBet<'info> {
|
||||
pub relayer: Signer<'info>,
|
||||
#[account(
|
||||
mut,
|
||||
seeds = [BET_SEED, id.to_le_bytes()],
|
||||
seeds = [BET_SEED, &id.to_le_bytes()],
|
||||
bump
|
||||
)]
|
||||
pub bet: Account<Bet>,
|
||||
pub bet: Account<'info, Bet>,
|
||||
#[account(
|
||||
mut,
|
||||
seeds = [GLOBAL_SEED],
|
||||
bump
|
||||
)]
|
||||
pub global: Account<Global>,
|
||||
pub global: Account<'info, Global>,
|
||||
/// CHECK: recipient must be the bet's bettor and is validated in the handler.
|
||||
#[account(mut)]
|
||||
pub bettor: SystemAccount,
|
||||
pub clock: Sysvar<Clock>,
|
||||
pub bettor: SystemAccount<'info>,
|
||||
pub clock: Sysvar<'info, Clock>,
|
||||
}
|
||||
|
||||
pub fn handler(ctx: &mut Context<CloseBet>, id: u64, exit_price: u64) -> Result<()> {
|
||||
require!(
|
||||
anchor_lang::address_eq(ctx.accounts.relayer.address(), &ctx.accounts.global.relayer),
|
||||
ctx.accounts.relayer.key() == ctx.accounts.global.relayer,
|
||||
SmartUpdownError::NotRelayer
|
||||
);
|
||||
require!(
|
||||
anchor_lang::address_eq(ctx.accounts.bettor.address(), &ctx.accounts.bet.bettor),
|
||||
ctx.accounts.bettor.key() == ctx.accounts.bet.bettor,
|
||||
SmartUpdownError::NotRelayer
|
||||
);
|
||||
require!(
|
||||
@@ -59,24 +59,24 @@ pub fn handler(ctx: &mut Context<CloseBet>, id: u64, exit_price: u64) -> Result<
|
||||
let user_won = (side == SIDE_UP && exit_price > entry)
|
||||
|| (side == SIDE_DOWN && exit_price < entry);
|
||||
|
||||
let payout;
|
||||
if user_won {
|
||||
let multiplier = ctx.accounts.global.multiplier_bps;
|
||||
let payout_amount =
|
||||
(amount as u128)
|
||||
.checked_mul(multiplier as u128)
|
||||
.unwrap()
|
||||
.checked_div(BPS_DIVISOR as u128)
|
||||
.unwrap() as u64;
|
||||
require!(
|
||||
ctx.accounts.global.view().lamports() >= payout_amount,
|
||||
SmartUpdownError::InsufficientVault
|
||||
);
|
||||
payout = payout_amount;
|
||||
ctx.accounts.global.sub_lamports(payout)?;
|
||||
ctx.accounts.bettor.add_lamports(payout)?;
|
||||
ctx.accounts.bet.status = STATUS_PAYOUT_DONE;
|
||||
} else {
|
||||
let payout;
|
||||
if user_won {
|
||||
let multiplier = ctx.accounts.global.multiplier_bps;
|
||||
let payout_amount =
|
||||
(amount as u128)
|
||||
.checked_mul(multiplier as u128)
|
||||
.unwrap()
|
||||
.checked_div(BPS_DIVISOR as u128)
|
||||
.unwrap() as u64;
|
||||
require!(
|
||||
ctx.accounts.global.get_lamports() >= payout_amount,
|
||||
SmartUpdownError::InsufficientVault
|
||||
);
|
||||
payout = payout_amount;
|
||||
ctx.accounts.global.sub_lamports(payout)?;
|
||||
ctx.accounts.bettor.add_lamports(payout)?;
|
||||
ctx.accounts.bet.status = STATUS_PAYOUT_DONE;
|
||||
} else {
|
||||
payout = 0;
|
||||
ctx.accounts.bet.status = STATUS_HOUSE_WON;
|
||||
}
|
||||
@@ -84,7 +84,7 @@ pub fn handler(ctx: &mut Context<CloseBet>, id: u64, exit_price: u64) -> Result<
|
||||
ctx.accounts.bet.exit_price = exit_price;
|
||||
|
||||
emit!(BetClosed {
|
||||
bet: *ctx.accounts.bet.address(),
|
||||
bet: ctx.accounts.bet.key(),
|
||||
exit_price,
|
||||
user_won,
|
||||
payout,
|
||||
|
||||
@@ -9,24 +9,25 @@ use crate::{
|
||||
|
||||
#[derive(Accounts)]
|
||||
#[instruction(id: u64, side: u64, amount: u64, entry_price: u64)]
|
||||
pub struct CreateBet {
|
||||
pub struct CreateBet<'info> {
|
||||
#[account(mut)]
|
||||
pub bettor: Signer,
|
||||
pub bettor: Signer<'info>,
|
||||
#[account(
|
||||
mut,
|
||||
seeds = [GLOBAL_SEED],
|
||||
bump
|
||||
)]
|
||||
pub global: Account<Global>,
|
||||
pub global: Account<'info, Global>,
|
||||
#[account(
|
||||
init,
|
||||
payer = bettor,
|
||||
seeds = [BET_SEED, id.to_le_bytes()],
|
||||
space = 8 + Bet::INIT_SPACE,
|
||||
seeds = [BET_SEED, &id.to_le_bytes()],
|
||||
bump
|
||||
)]
|
||||
pub bet: Account<Bet>,
|
||||
pub clock: Sysvar<Clock>,
|
||||
pub system_program: Program<System>,
|
||||
pub bet: Account<'info, Bet>,
|
||||
pub clock: Sysvar<'info, Clock>,
|
||||
pub system_program: Program<'info, System>,
|
||||
}
|
||||
|
||||
pub fn handler(
|
||||
@@ -52,8 +53,8 @@ pub fn handler(
|
||||
);
|
||||
|
||||
let now = ctx.accounts.clock.unix_timestamp;
|
||||
let bettor_address = *ctx.accounts.bettor.address();
|
||||
let bet_address = *ctx.accounts.bet.address();
|
||||
let bettor_address = ctx.accounts.bettor.key();
|
||||
let bet_address = ctx.accounts.bet.key();
|
||||
let expiry_seconds = ctx.accounts.global.expiry_seconds;
|
||||
|
||||
{
|
||||
@@ -71,12 +72,15 @@ pub fn handler(
|
||||
ctx.accounts.global.counter = ctx.accounts.global.counter.checked_add(1).unwrap();
|
||||
|
||||
{
|
||||
let cpi_accounts = system_program::Transfer {
|
||||
from: ctx.accounts.bettor.cpi_handle_mut(),
|
||||
to: ctx.accounts.global.cpi_handle_mut(),
|
||||
let cpi_accounts = anchor_lang::system_program::Transfer {
|
||||
from: ctx.accounts.bettor.to_account_info(),
|
||||
to: ctx.accounts.global.to_account_info(),
|
||||
};
|
||||
let cpi_ctx = CpiContext::new(ctx.accounts.system_program.address(), cpi_accounts);
|
||||
system_program::transfer(cpi_ctx, amount)?;
|
||||
let cpi_ctx = CpiContext::new(
|
||||
ctx.accounts.system_program.to_account_info(),
|
||||
cpi_accounts,
|
||||
);
|
||||
anchor_lang::system_program::transfer(cpi_ctx, amount)?;
|
||||
}
|
||||
|
||||
emit!(BetCreated {
|
||||
|
||||
@@ -3,17 +3,18 @@ use anchor_lang::prelude::*;
|
||||
use crate::{constants::GLOBAL_SEED, state::Global};
|
||||
|
||||
#[derive(Accounts)]
|
||||
pub struct Initialize {
|
||||
pub struct Initialize<'info> {
|
||||
#[account(mut)]
|
||||
pub admin: Signer,
|
||||
pub admin: Signer<'info>,
|
||||
#[account(
|
||||
init,
|
||||
payer = admin,
|
||||
space = 8 + Global::INIT_SPACE,
|
||||
seeds = [GLOBAL_SEED],
|
||||
bump
|
||||
)]
|
||||
pub global: Account<Global>,
|
||||
pub system_program: Program<System>,
|
||||
pub global: Account<'info, Global>,
|
||||
pub system_program: Program<'info, System>,
|
||||
}
|
||||
|
||||
pub fn handler(
|
||||
@@ -24,8 +25,8 @@ pub fn handler(
|
||||
expiry_seconds: i64,
|
||||
) -> Result<()> {
|
||||
let global = &mut ctx.accounts.global;
|
||||
global.admin = *ctx.accounts.admin.address();
|
||||
global.relayer = *ctx.accounts.admin.address();
|
||||
global.admin = ctx.accounts.admin.key();
|
||||
global.relayer = ctx.accounts.admin.key();
|
||||
global.counter = 0;
|
||||
global.min_amount = min_amount;
|
||||
global.max_amount = max_amount;
|
||||
|
||||
@@ -7,19 +7,19 @@ use crate::{
|
||||
};
|
||||
|
||||
#[derive(Accounts)]
|
||||
pub struct Update {
|
||||
pub admin: Signer,
|
||||
pub struct Update<'info> {
|
||||
pub admin: Signer<'info>,
|
||||
#[account(
|
||||
mut,
|
||||
seeds = [GLOBAL_SEED],
|
||||
bump
|
||||
)]
|
||||
pub global: Account<Global>,
|
||||
pub global: Account<'info, Global>,
|
||||
}
|
||||
|
||||
pub fn handler(
|
||||
ctx: &mut Context<Update>,
|
||||
new_relayer: Address,
|
||||
new_relayer: Pubkey,
|
||||
min_amount: u64,
|
||||
max_amount: u64,
|
||||
multiplier_bps: u64,
|
||||
@@ -27,7 +27,7 @@ pub fn handler(
|
||||
expiry_seconds: i64,
|
||||
) -> Result<()> {
|
||||
require!(
|
||||
anchor_lang::address_eq(ctx.accounts.admin.address(), &ctx.accounts.global.admin),
|
||||
ctx.accounts.admin.key() == ctx.accounts.global.admin,
|
||||
SmartUpdownError::NotAdmin
|
||||
);
|
||||
let global = &mut ctx.accounts.global;
|
||||
|
||||
@@ -14,41 +14,37 @@ declare_id!("9ALsnxXNzDBv3mokngCHbruRTWUZiWR7pf7vswS1fCpf");
|
||||
pub mod smart_updown {
|
||||
use super::*;
|
||||
|
||||
#[discrim = 0]
|
||||
pub fn initialize(
|
||||
ctx: &mut Context<Initialize>,
|
||||
mut ctx: Context<Initialize>,
|
||||
min_amount: u64,
|
||||
max_amount: u64,
|
||||
multiplier_bps: u64,
|
||||
expiry_seconds: i64,
|
||||
) -> Result<()> {
|
||||
initialize::handler(ctx, min_amount, max_amount, multiplier_bps, expiry_seconds)
|
||||
initialize::handler(&mut ctx, min_amount, max_amount, multiplier_bps, expiry_seconds)
|
||||
}
|
||||
|
||||
#[discrim = 1]
|
||||
pub fn create_bet(
|
||||
ctx: &mut Context<CreateBet>,
|
||||
mut ctx: Context<CreateBet>,
|
||||
id: u64,
|
||||
side: u64,
|
||||
amount: u64,
|
||||
entry_price: u64,
|
||||
) -> Result<()> {
|
||||
create_bet::handler(ctx, id, side, amount, entry_price)
|
||||
create_bet::handler(&mut ctx, id, side, amount, entry_price)
|
||||
}
|
||||
|
||||
#[discrim = 2]
|
||||
pub fn close_bet(
|
||||
ctx: &mut Context<CloseBet>,
|
||||
mut ctx: Context<CloseBet>,
|
||||
id: u64,
|
||||
exit_price: u64,
|
||||
) -> Result<()> {
|
||||
close_bet::handler(ctx, id, exit_price)
|
||||
close_bet::handler(&mut ctx, id, exit_price)
|
||||
}
|
||||
|
||||
#[discrim = 3]
|
||||
pub fn update(
|
||||
ctx: &mut Context<Update>,
|
||||
new_relayer: Address,
|
||||
mut ctx: Context<Update>,
|
||||
new_relayer: Pubkey,
|
||||
min_amount: u64,
|
||||
max_amount: u64,
|
||||
multiplier_bps: u64,
|
||||
@@ -56,7 +52,7 @@ pub mod smart_updown {
|
||||
expiry_seconds: i64,
|
||||
) -> Result<()> {
|
||||
update::handler(
|
||||
ctx,
|
||||
&mut ctx,
|
||||
new_relayer,
|
||||
min_amount,
|
||||
max_amount,
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
use anchor_lang::prelude::*;
|
||||
|
||||
#[account]
|
||||
#[derive(InitSpace)]
|
||||
pub struct Global {
|
||||
pub counter: u64,
|
||||
pub min_amount: u64,
|
||||
@@ -8,11 +9,12 @@ pub struct Global {
|
||||
pub multiplier_bps: u64,
|
||||
pub expiry_seconds: i64,
|
||||
pub paused: u64,
|
||||
pub admin: Address,
|
||||
pub relayer: Address,
|
||||
pub admin: Pubkey,
|
||||
pub relayer: Pubkey,
|
||||
}
|
||||
|
||||
#[account]
|
||||
#[derive(InitSpace)]
|
||||
pub struct Bet {
|
||||
pub amount: u64,
|
||||
pub bet_time: i64,
|
||||
@@ -21,5 +23,5 @@ pub struct Bet {
|
||||
pub exit_price: u64,
|
||||
pub side: u64,
|
||||
pub status: u64,
|
||||
pub bettor: Address,
|
||||
pub bettor: Pubkey,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user