2022-03-18 02:08:53 -07:00
|
|
|
use anchor_lang::prelude::*;
|
2022-03-24 09:29:30 -07:00
|
|
|
use fixed::types::I80F48;
|
2022-03-18 02:08:53 -07:00
|
|
|
|
2022-09-29 05:13:28 -07:00
|
|
|
use crate::error::*;
|
2022-03-23 00:34:23 -07:00
|
|
|
use crate::state::*;
|
2022-08-12 07:05:32 -07:00
|
|
|
use crate::util::fill_from_str;
|
2022-03-18 02:08:53 -07:00
|
|
|
|
|
|
|
#[derive(Accounts)]
|
2022-03-18 23:28:37 -07:00
|
|
|
#[instruction(perp_market_index: PerpMarketIndex)]
|
2022-03-31 23:01:56 -07:00
|
|
|
pub struct PerpCreateMarket<'info> {
|
2022-03-18 02:08:53 -07:00
|
|
|
#[account(
|
|
|
|
has_one = admin,
|
2022-08-01 03:56:29 -07:00
|
|
|
constraint = group.load()?.perps_supported()
|
2022-03-18 02:08:53 -07:00
|
|
|
)]
|
|
|
|
pub group: AccountLoader<'info, Group>,
|
|
|
|
pub admin: Signer<'info>,
|
|
|
|
|
2022-06-22 03:45:42 -07:00
|
|
|
/// CHECK: The oracle can be one of several different account types
|
2022-03-18 02:08:53 -07:00
|
|
|
pub oracle: UncheckedAccount<'info>,
|
2022-03-18 02:33:22 -07:00
|
|
|
|
2022-03-18 02:08:53 -07:00
|
|
|
#[account(
|
|
|
|
init,
|
2022-08-13 10:30:35 -07:00
|
|
|
seeds = [b"PerpMarket".as_ref(), group.key().as_ref(), perp_market_index.to_le_bytes().as_ref()],
|
2022-03-18 02:08:53 -07:00
|
|
|
bump,
|
|
|
|
payer = payer,
|
2022-03-18 02:33:22 -07:00
|
|
|
space = 8 + std::mem::size_of::<PerpMarket>(),
|
2022-03-18 02:08:53 -07:00
|
|
|
)]
|
|
|
|
pub perp_market: AccountLoader<'info, PerpMarket>,
|
2022-03-21 12:29:28 -07:00
|
|
|
|
|
|
|
/// Accounts are initialised by client,
|
|
|
|
/// anchor discriminator is set first when ix exits,
|
|
|
|
#[account(zero)]
|
|
|
|
pub bids: AccountLoader<'info, BookSide>,
|
|
|
|
#[account(zero)]
|
|
|
|
pub asks: AccountLoader<'info, BookSide>,
|
2022-03-24 06:40:08 -07:00
|
|
|
#[account(zero)]
|
|
|
|
pub event_queue: AccountLoader<'info, EventQueue>,
|
2022-03-22 23:53:45 -07:00
|
|
|
|
2022-03-18 02:08:53 -07:00
|
|
|
#[account(mut)]
|
|
|
|
pub payer: Signer<'info>,
|
|
|
|
|
|
|
|
pub system_program: Program<'info, System>,
|
|
|
|
}
|
|
|
|
|
2022-03-24 09:29:30 -07:00
|
|
|
#[allow(clippy::too_many_arguments)]
|
2022-03-31 23:01:56 -07:00
|
|
|
pub fn perp_create_market(
|
|
|
|
ctx: Context<PerpCreateMarket>,
|
2022-09-29 05:13:28 -07:00
|
|
|
settle_token_index: TokenIndex,
|
2022-03-18 23:28:37 -07:00
|
|
|
perp_market_index: PerpMarketIndex,
|
2022-05-06 05:19:49 -07:00
|
|
|
name: String,
|
2022-06-18 07:38:46 -07:00
|
|
|
oracle_config: OracleConfig,
|
2022-09-21 00:42:45 -07:00
|
|
|
base_decimals: u8,
|
2022-03-18 02:08:53 -07:00
|
|
|
quote_lot_size: i64,
|
|
|
|
base_lot_size: i64,
|
2022-03-24 11:15:46 -07:00
|
|
|
maint_asset_weight: f32,
|
|
|
|
init_asset_weight: f32,
|
|
|
|
maint_liab_weight: f32,
|
|
|
|
init_liab_weight: f32,
|
2022-03-24 09:29:30 -07:00
|
|
|
liquidation_fee: f32,
|
|
|
|
maker_fee: f32,
|
|
|
|
taker_fee: f32,
|
2022-05-16 06:34:56 -07:00
|
|
|
min_funding: f32,
|
2022-05-17 06:06:29 -07:00
|
|
|
max_funding: f32,
|
2022-05-17 01:07:24 -07:00
|
|
|
impact_quantity: i64,
|
2022-09-12 06:25:50 -07:00
|
|
|
group_insurance_fund: bool,
|
|
|
|
trusted_market: bool,
|
2022-09-22 09:55:12 -07:00
|
|
|
fee_penalty: f32,
|
2022-09-29 03:59:55 -07:00
|
|
|
settle_fee_flat: f32,
|
|
|
|
settle_fee_amount_threshold: f32,
|
|
|
|
settle_fee_fraction_low_health: f32,
|
2022-03-18 02:08:53 -07:00
|
|
|
) -> Result<()> {
|
2022-09-29 05:13:28 -07:00
|
|
|
// Settlement tokens that aren't USDC aren't fully implemented, the main missing steps are:
|
|
|
|
// - In health: the perp health needs to be adjusted by the settlement token weights.
|
|
|
|
// Otherwise settling perp pnl could decrease health.
|
|
|
|
// - In settle pnl and settle fees: use the settle oracle to convert the pnl from USD to token.
|
|
|
|
// - In perp bankruptcy: fix the assumption that the insurance fund has the same mint as
|
|
|
|
// the settlement token.
|
|
|
|
require_msg!(
|
|
|
|
settle_token_index == QUOTE_TOKEN_INDEX,
|
|
|
|
"settlement tokens != USDC are not fully implemented"
|
|
|
|
);
|
|
|
|
|
2022-03-18 02:08:53 -07:00
|
|
|
let mut perp_market = ctx.accounts.perp_market.load_init()?;
|
|
|
|
*perp_market = PerpMarket {
|
|
|
|
group: ctx.accounts.group.key(),
|
2022-09-29 05:13:28 -07:00
|
|
|
settle_token_index,
|
|
|
|
perp_market_index,
|
|
|
|
group_insurance_fund: if group_insurance_fund { 1 } else { 0 },
|
|
|
|
trusted_market: if trusted_market { 1 } else { 0 },
|
|
|
|
name: fill_from_str(&name)?,
|
2022-03-18 02:08:53 -07:00
|
|
|
oracle: ctx.accounts.oracle.key(),
|
2022-06-18 07:38:46 -07:00
|
|
|
oracle_config,
|
2022-03-18 02:08:53 -07:00
|
|
|
bids: ctx.accounts.bids.key(),
|
|
|
|
asks: ctx.accounts.asks.key(),
|
2022-03-22 23:53:45 -07:00
|
|
|
event_queue: ctx.accounts.event_queue.key(),
|
2022-03-22 03:19:12 -07:00
|
|
|
quote_lot_size,
|
|
|
|
base_lot_size,
|
2022-03-24 09:29:30 -07:00
|
|
|
maint_asset_weight: I80F48::from_num(maint_asset_weight),
|
|
|
|
init_asset_weight: I80F48::from_num(init_asset_weight),
|
|
|
|
maint_liab_weight: I80F48::from_num(maint_liab_weight),
|
|
|
|
init_liab_weight: I80F48::from_num(init_liab_weight),
|
|
|
|
liquidation_fee: I80F48::from_num(liquidation_fee),
|
|
|
|
maker_fee: I80F48::from_num(maker_fee),
|
|
|
|
taker_fee: I80F48::from_num(taker_fee),
|
2022-05-17 01:07:24 -07:00
|
|
|
min_funding: I80F48::from_num(min_funding),
|
2022-05-17 06:06:29 -07:00
|
|
|
max_funding: I80F48::from_num(max_funding),
|
2022-06-02 01:36:04 -07:00
|
|
|
impact_quantity,
|
2022-05-16 06:34:56 -07:00
|
|
|
long_funding: I80F48::ZERO,
|
|
|
|
short_funding: I80F48::ZERO,
|
|
|
|
funding_last_updated: Clock::get()?.unix_timestamp,
|
2022-03-28 12:13:16 -07:00
|
|
|
open_interest: 0,
|
2022-03-18 02:08:53 -07:00
|
|
|
seq_num: 0,
|
2022-03-25 01:46:38 -07:00
|
|
|
fees_accrued: I80F48::ZERO,
|
2022-09-05 07:18:40 -07:00
|
|
|
fees_settled: I80F48::ZERO,
|
2022-06-18 07:38:46 -07:00
|
|
|
bump: *ctx.bumps.get("perp_market").ok_or(MangoError::SomeError)?,
|
2022-09-21 00:42:45 -07:00
|
|
|
base_decimals,
|
2022-08-01 09:46:45 -07:00
|
|
|
registration_time: Clock::get()?.unix_timestamp,
|
2022-08-01 07:53:30 -07:00
|
|
|
padding1: Default::default(),
|
|
|
|
padding2: Default::default(),
|
2022-09-22 09:55:12 -07:00
|
|
|
fee_penalty,
|
2022-09-29 03:59:55 -07:00
|
|
|
settle_fee_flat,
|
|
|
|
settle_fee_amount_threshold,
|
|
|
|
settle_fee_fraction_low_health,
|
|
|
|
reserved: [0; 92],
|
2022-03-18 02:08:53 -07:00
|
|
|
};
|
|
|
|
|
2022-03-18 23:28:37 -07:00
|
|
|
let mut bids = ctx.accounts.bids.load_init()?;
|
2022-03-21 12:29:28 -07:00
|
|
|
bids.book_side_type = BookSideType::Bids;
|
2022-03-18 23:28:37 -07:00
|
|
|
|
2022-03-21 12:29:28 -07:00
|
|
|
let mut asks = ctx.accounts.asks.load_init()?;
|
|
|
|
asks.book_side_type = BookSideType::Asks;
|
2022-03-18 23:28:37 -07:00
|
|
|
|
2022-03-18 02:08:53 -07:00
|
|
|
Ok(())
|
|
|
|
}
|