Skip to main content

percli_program/instructions/
trade.rs

1use anchor_lang::prelude::*;
2
3use crate::error::{from_risk_error, PercolatorError};
4use crate::instructions::events;
5use crate::state::{engine_from_account_data, header_from_account_data, MARKET_ACCOUNT_SIZE};
6
7#[derive(Accounts)]
8pub struct Trade<'info> {
9    /// Matcher authority — must match the matcher stored in the market header.
10    pub signer: Signer<'info>,
11
12    /// CHECK: Validated via owner, discriminator, and size.
13    #[account(
14        mut,
15        owner = crate::ID @ PercolatorError::AccountNotFound,
16        constraint = market.data_len() >= MARKET_ACCOUNT_SIZE @ PercolatorError::AccountNotFound,
17    )]
18    pub market: UncheckedAccount<'info>,
19}
20
21pub fn handler(
22    ctx: Context<Trade>,
23    account_a: u16,
24    account_b: u16,
25    size_q: i128,
26    exec_price: u64,
27    funding_rate: i64,
28) -> Result<()> {
29    require!(account_a != account_b, PercolatorError::InvalidMatchingEngine);
30
31    let market = &ctx.accounts.market;
32    let mut data = market.try_borrow_mut_data()?;
33
34    require!(&data[0..8] == b"percmrkt", PercolatorError::AccountNotFound);
35
36    // Verify signer is the designated matcher authority
37    let header = header_from_account_data(&data)?;
38    require!(
39        header.matcher == ctx.accounts.signer.key(),
40        PercolatorError::Unauthorized
41    );
42
43    let engine = engine_from_account_data(&mut data);
44    let oracle_price = engine.last_oracle_price;
45    let clock = Clock::get()?;
46
47    engine
48        .execute_trade_not_atomic(
49            account_a,
50            account_b,
51            oracle_price,
52            clock.slot,
53            size_q,
54            exec_price,
55            funding_rate,
56        )
57        .map_err(from_risk_error)?;
58
59    emit!(events::TradeExecuted {
60        matcher: ctx.accounts.signer.key(),
61        account_a,
62        account_b,
63        size_q,
64        exec_price,
65    });
66
67    Ok(())
68}