Skip to main content

percli_program/instructions/
settle.rs

1use anchor_lang::prelude::*;
2
3use crate::error::{from_risk_error, PercolatorError};
4use crate::state::{engine_from_account_data, MARKET_ACCOUNT_SIZE};
5
6#[derive(Accounts)]
7pub struct Settle<'info> {
8    pub user: Signer<'info>,
9
10    /// CHECK: Validated via owner, discriminator, and size.
11    #[account(
12        mut,
13        owner = crate::ID @ PercolatorError::AccountNotFound,
14        constraint = market.data_len() == MARKET_ACCOUNT_SIZE @ PercolatorError::AccountNotFound,
15    )]
16    pub market: UncheckedAccount<'info>,
17}
18
19pub fn handler(ctx: Context<Settle>, account_idx: u16, funding_rate: i64) -> Result<()> {
20    let market = &ctx.accounts.market;
21    let mut data = market.try_borrow_mut_data()?;
22
23    require!(&data[0..8] == b"percmrkt", PercolatorError::AccountNotFound);
24
25    let engine = engine_from_account_data(&mut data);
26
27    // Verify signer owns this account
28    let account_owner = engine.accounts[account_idx as usize].owner;
29    require!(
30        account_owner == ctx.accounts.user.key().to_bytes(),
31        PercolatorError::Unauthorized
32    );
33
34    let oracle_price = engine.last_oracle_price;
35    let clock = Clock::get()?;
36
37    engine
38        .settle_account_not_atomic(account_idx, oracle_price, clock.slot, funding_rate)
39        .map_err(from_risk_error)?;
40
41    Ok(())
42}