2022-03-28 12:13:16 -07:00
|
|
|
use anchor_lang::prelude::*;
|
|
|
|
use bytemuck::cast_ref;
|
|
|
|
|
2022-06-08 04:43:12 -07:00
|
|
|
use crate::accounts_zerocopy::*;
|
2022-03-28 12:13:16 -07:00
|
|
|
use crate::error::MangoError;
|
2022-05-18 08:16:14 -07:00
|
|
|
use crate::state::EventQueue;
|
2022-06-08 04:43:12 -07:00
|
|
|
use crate::state::{EventType, FillEvent, Group, MangoAccount, OutEvent, PerpMarket};
|
2022-03-28 12:13:16 -07:00
|
|
|
|
2022-06-30 05:35:05 -07:00
|
|
|
use crate::logs::{emit_perp_balances, FillLog};
|
|
|
|
|
2022-03-28 12:13:16 -07:00
|
|
|
#[derive(Accounts)]
|
2022-03-31 23:01:56 -07:00
|
|
|
pub struct PerpConsumeEvents<'info> {
|
2022-03-28 12:13:16 -07:00
|
|
|
pub group: AccountLoader<'info, Group>,
|
2022-03-31 00:25:47 -07:00
|
|
|
|
2022-03-28 12:13:16 -07:00
|
|
|
#[account(
|
|
|
|
mut,
|
2022-03-31 00:25:47 -07:00
|
|
|
has_one = group,
|
|
|
|
)]
|
2022-03-28 12:13:16 -07:00
|
|
|
pub perp_market: AccountLoader<'info, PerpMarket>,
|
2022-03-31 00:25:47 -07:00
|
|
|
|
|
|
|
#[account(mut)]
|
2022-05-18 08:16:14 -07:00
|
|
|
pub event_queue: AccountLoader<'info, EventQueue>,
|
2022-03-28 12:13:16 -07:00
|
|
|
}
|
|
|
|
|
2022-03-31 23:01:56 -07:00
|
|
|
pub fn perp_consume_events(ctx: Context<PerpConsumeEvents>, limit: usize) -> Result<()> {
|
2022-03-28 12:13:16 -07:00
|
|
|
let limit = std::cmp::min(limit, 8);
|
|
|
|
|
2022-03-31 00:25:47 -07:00
|
|
|
let mut perp_market = ctx.accounts.perp_market.load_mut()?;
|
2022-03-28 12:13:16 -07:00
|
|
|
let mut event_queue = ctx.accounts.event_queue.load_mut()?;
|
2022-03-31 00:25:47 -07:00
|
|
|
let mango_account_ais = &ctx.remaining_accounts;
|
2022-03-28 12:13:16 -07:00
|
|
|
|
|
|
|
for _ in 0..limit {
|
|
|
|
let event = match event_queue.peek_front() {
|
|
|
|
None => break,
|
|
|
|
Some(e) => e,
|
|
|
|
};
|
|
|
|
|
2022-03-31 00:25:47 -07:00
|
|
|
match EventType::try_from(event.event_type).map_err(|_| error!(MangoError::SomeError))? {
|
2022-03-28 12:13:16 -07:00
|
|
|
EventType::Fill => {
|
|
|
|
let fill: &FillEvent = cast_ref(event);
|
|
|
|
|
|
|
|
// handle self trade separately because of rust borrow checker
|
|
|
|
if fill.maker == fill.taker {
|
|
|
|
let mut ma = match mango_account_ais.iter().find(|ai| ai.key == &fill.maker) {
|
|
|
|
None => {
|
|
|
|
msg!("Unable to find account {}", fill.maker.to_string());
|
|
|
|
return Ok(());
|
|
|
|
}
|
2022-03-31 00:25:47 -07:00
|
|
|
Some(account_info) => account_info.load_mut::<MangoAccount>()?,
|
2022-03-28 12:13:16 -07:00
|
|
|
};
|
2022-03-31 00:25:47 -07:00
|
|
|
|
2022-04-02 02:21:41 -07:00
|
|
|
ma.perps.execute_maker(
|
|
|
|
perp_market.perp_market_index,
|
|
|
|
&mut perp_market,
|
|
|
|
fill,
|
|
|
|
)?;
|
|
|
|
ma.perps.execute_taker(
|
|
|
|
perp_market.perp_market_index,
|
|
|
|
&mut perp_market,
|
|
|
|
fill,
|
|
|
|
)?;
|
2022-06-30 05:35:05 -07:00
|
|
|
emit_perp_balances(
|
|
|
|
fill.maker,
|
|
|
|
perp_market.perp_market_index as u64,
|
|
|
|
fill.price,
|
|
|
|
&ma.perps.accounts[perp_market.perp_market_index as usize],
|
|
|
|
&perp_market,
|
|
|
|
);
|
2022-03-28 12:13:16 -07:00
|
|
|
} else {
|
|
|
|
let mut maker = match mango_account_ais.iter().find(|ai| ai.key == &fill.maker)
|
|
|
|
{
|
|
|
|
None => {
|
|
|
|
msg!("Unable to find maker account {}", fill.maker.to_string());
|
|
|
|
return Ok(());
|
|
|
|
}
|
2022-03-31 00:25:47 -07:00
|
|
|
Some(account_info) => account_info.load_mut::<MangoAccount>()?,
|
2022-03-28 12:13:16 -07:00
|
|
|
};
|
|
|
|
let mut taker = match mango_account_ais.iter().find(|ai| ai.key == &fill.taker)
|
|
|
|
{
|
|
|
|
None => {
|
|
|
|
msg!("Unable to find taker account {}", fill.taker.to_string());
|
|
|
|
return Ok(());
|
|
|
|
}
|
2022-03-31 00:25:47 -07:00
|
|
|
Some(account_info) => account_info.load_mut::<MangoAccount>()?,
|
2022-03-28 12:13:16 -07:00
|
|
|
};
|
|
|
|
|
2022-04-02 02:21:41 -07:00
|
|
|
maker.perps.execute_maker(
|
2022-04-01 03:22:03 -07:00
|
|
|
perp_market.perp_market_index,
|
|
|
|
&mut perp_market,
|
|
|
|
fill,
|
|
|
|
)?;
|
2022-04-02 02:21:41 -07:00
|
|
|
taker.perps.execute_taker(
|
2022-04-01 03:22:03 -07:00
|
|
|
perp_market.perp_market_index,
|
|
|
|
&mut perp_market,
|
|
|
|
fill,
|
|
|
|
)?;
|
2022-06-30 05:35:05 -07:00
|
|
|
emit_perp_balances(
|
|
|
|
fill.maker,
|
|
|
|
perp_market.perp_market_index as u64,
|
|
|
|
fill.price,
|
|
|
|
&maker.perps.accounts[perp_market.perp_market_index as usize],
|
|
|
|
&perp_market,
|
|
|
|
);
|
|
|
|
emit_perp_balances(
|
|
|
|
fill.taker,
|
|
|
|
perp_market.perp_market_index as u64,
|
|
|
|
fill.price,
|
|
|
|
&taker.perps.accounts[perp_market.perp_market_index as usize],
|
|
|
|
&perp_market,
|
|
|
|
);
|
2022-03-31 00:25:47 -07:00
|
|
|
}
|
2022-06-30 05:35:05 -07:00
|
|
|
emit!(FillLog {
|
|
|
|
mango_group: ctx.accounts.group.key(),
|
|
|
|
market_index: perp_market.perp_market_index,
|
|
|
|
taker_side: fill.taker_side as u8,
|
|
|
|
maker_slot: fill.maker_slot,
|
|
|
|
market_fees_applied: fill.market_fees_applied,
|
|
|
|
maker_out: fill.maker_out,
|
|
|
|
timestamp: fill.timestamp,
|
|
|
|
seq_num: fill.seq_num,
|
|
|
|
maker: fill.maker,
|
|
|
|
maker_order_id: fill.maker_order_id,
|
|
|
|
maker_client_order_id: fill.maker_client_order_id,
|
|
|
|
maker_fee: fill.maker_fee.to_bits(),
|
|
|
|
maker_timestamp: fill.maker_timestamp,
|
|
|
|
taker: fill.taker,
|
|
|
|
taker_order_id: fill.taker_order_id,
|
|
|
|
taker_client_order_id: fill.taker_client_order_id,
|
|
|
|
taker_fee: fill.taker_fee.to_bits(),
|
|
|
|
price: fill.price,
|
|
|
|
quantity: fill.quantity,
|
|
|
|
});
|
2022-03-28 12:13:16 -07:00
|
|
|
}
|
|
|
|
EventType::Out => {
|
|
|
|
let out: &OutEvent = cast_ref(event);
|
|
|
|
|
|
|
|
let mut ma = match mango_account_ais.iter().find(|ai| ai.key == &out.owner) {
|
|
|
|
None => {
|
|
|
|
msg!("Unable to find account {}", out.owner.to_string());
|
|
|
|
return Ok(());
|
|
|
|
}
|
2022-03-31 00:25:47 -07:00
|
|
|
Some(account_info) => account_info.load_mut::<MangoAccount>()?,
|
2022-03-28 12:13:16 -07:00
|
|
|
};
|
|
|
|
|
2022-04-02 02:21:41 -07:00
|
|
|
ma.perps
|
2022-04-01 03:22:03 -07:00
|
|
|
.remove_order(out.owner_slot as usize, out.quantity)?;
|
2022-03-28 12:13:16 -07:00
|
|
|
}
|
|
|
|
EventType::Liquidate => {
|
|
|
|
// This is purely for record keeping. Can be removed if program logs are superior
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// consume this event
|
|
|
|
event_queue.pop_front()?;
|
|
|
|
}
|
|
|
|
Ok(())
|
|
|
|
}
|