PlaceSerumOrder: More account validation
This commit is contained in:
parent
6b342ffeb9
commit
28a26e66da
|
@ -111,10 +111,8 @@ pub struct PlaceSerumOrder<'info> {
|
||||||
pub account: AccountLoader<'info, MangoAccount>,
|
pub account: AccountLoader<'info, MangoAccount>,
|
||||||
pub owner: Signer<'info>,
|
pub owner: Signer<'info>,
|
||||||
|
|
||||||
#[account(
|
// Validated inline
|
||||||
mut,
|
#[account(mut)]
|
||||||
//constraint = open_orders in account.spot_open_orders_map
|
|
||||||
)]
|
|
||||||
pub open_orders: UncheckedAccount<'info>,
|
pub open_orders: UncheckedAccount<'info>,
|
||||||
|
|
||||||
#[account(
|
#[account(
|
||||||
|
@ -123,12 +121,12 @@ pub struct PlaceSerumOrder<'info> {
|
||||||
has_one = serum_market_external,
|
has_one = serum_market_external,
|
||||||
)]
|
)]
|
||||||
pub serum_market: AccountLoader<'info, SerumMarket>,
|
pub serum_market: AccountLoader<'info, SerumMarket>,
|
||||||
|
|
||||||
// TODO: limit?
|
|
||||||
pub serum_program: UncheckedAccount<'info>,
|
pub serum_program: UncheckedAccount<'info>,
|
||||||
#[account(mut)]
|
#[account(mut)]
|
||||||
pub serum_market_external: UncheckedAccount<'info>,
|
pub serum_market_external: UncheckedAccount<'info>,
|
||||||
|
|
||||||
|
// These accounts are forwarded directly to the serum cpi call
|
||||||
|
// and are validated there.
|
||||||
#[account(mut)]
|
#[account(mut)]
|
||||||
pub market_bids: UncheckedAccount<'info>,
|
pub market_bids: UncheckedAccount<'info>,
|
||||||
#[account(mut)]
|
#[account(mut)]
|
||||||
|
@ -142,11 +140,12 @@ pub struct PlaceSerumOrder<'info> {
|
||||||
#[account(mut)]
|
#[account(mut)]
|
||||||
pub market_quote_vault: UncheckedAccount<'info>,
|
pub market_quote_vault: UncheckedAccount<'info>,
|
||||||
|
|
||||||
// TODO: everything; do we need to pass both, or just payer?
|
// TODO: do we need to pass both, or just payer?
|
||||||
// TODO: if we potentially settle immediately, they all need to be mut?
|
// TODO: if we potentially settle immediately, they all need to be mut?
|
||||||
// TODO: Can we reduce the number of accounts by requiring the banks
|
// TODO: Can we reduce the number of accounts by requiring the banks
|
||||||
// to be in the remainingAccounts (where they need to be anyway, for
|
// to be in the remainingAccounts (where they need to be anyway, for
|
||||||
// health checks)
|
// health checks - but they need to be mut)
|
||||||
|
// Validated inline
|
||||||
#[account(mut)]
|
#[account(mut)]
|
||||||
pub quote_bank: AccountLoader<'info, Bank>,
|
pub quote_bank: AccountLoader<'info, Bank>,
|
||||||
#[account(mut)]
|
#[account(mut)]
|
||||||
|
@ -164,12 +163,53 @@ pub fn place_serum_order(
|
||||||
ctx: Context<PlaceSerumOrder>,
|
ctx: Context<PlaceSerumOrder>,
|
||||||
order: NewOrderInstructionData,
|
order: NewOrderInstructionData,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
|
let account = ctx.accounts.account.load()?;
|
||||||
|
let serum_market = ctx.accounts.serum_market.load()?;
|
||||||
|
|
||||||
|
// Validate open_orders
|
||||||
|
require!(
|
||||||
|
account
|
||||||
|
.serum_open_orders_map
|
||||||
|
.find(serum_market.market_index)
|
||||||
|
.ok_or(error!(MangoError::SomeError))?
|
||||||
|
.open_orders
|
||||||
|
== ctx.accounts.open_orders.key(),
|
||||||
|
MangoError::SomeError
|
||||||
|
);
|
||||||
|
|
||||||
|
// Validate banks and vaults
|
||||||
|
let quote_bank = ctx.accounts.quote_bank.load()?;
|
||||||
|
require!(
|
||||||
|
quote_bank.vault == ctx.accounts.quote_vault.key(),
|
||||||
|
MangoError::SomeError
|
||||||
|
);
|
||||||
|
require!(
|
||||||
|
quote_bank.token_index == serum_market.quote_token_index,
|
||||||
|
MangoError::SomeError
|
||||||
|
);
|
||||||
|
let base_bank = ctx.accounts.base_bank.load()?;
|
||||||
|
require!(
|
||||||
|
base_bank.vault == ctx.accounts.base_vault.key(),
|
||||||
|
MangoError::SomeError
|
||||||
|
);
|
||||||
|
require!(
|
||||||
|
base_bank.token_index == serum_market.base_token_index,
|
||||||
|
MangoError::SomeError
|
||||||
|
);
|
||||||
|
|
||||||
|
// TODO: pre-health check
|
||||||
|
// TODO: track vault balance before
|
||||||
|
|
||||||
|
//
|
||||||
|
// Place the order
|
||||||
|
//
|
||||||
|
|
||||||
// unwrap our newtype
|
// unwrap our newtype
|
||||||
let order = order.0;
|
let order = order.0;
|
||||||
|
|
||||||
let order_payer_token_account = match order.side {
|
let order_payer_token_account = match order.side {
|
||||||
Side::Ask => ctx.accounts.base_vault.to_account_info(),
|
|
||||||
Side::Bid => ctx.accounts.quote_vault.to_account_info(),
|
Side::Bid => ctx.accounts.quote_vault.to_account_info(),
|
||||||
|
Side::Ask => ctx.accounts.base_vault.to_account_info(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let context = CpiContext::new(
|
let context = CpiContext::new(
|
||||||
|
@ -208,7 +248,12 @@ pub fn place_serum_order(
|
||||||
order.limit,
|
order.limit,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
// TODO: immediately call settle_funds?
|
||||||
|
// TODO: track vault balance after, apply to user position
|
||||||
|
|
||||||
|
//
|
||||||
// Health check
|
// Health check
|
||||||
|
//
|
||||||
let account = ctx.accounts.account.load()?;
|
let account = ctx.accounts.account.load()?;
|
||||||
let health = compute_health(&account, &ctx.remaining_accounts)?;
|
let health = compute_health(&account, &ctx.remaining_accounts)?;
|
||||||
msg!("health: {}", health);
|
msg!("health: {}", health);
|
||||||
|
|
|
@ -69,6 +69,10 @@ fn compute_health_detail(
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Serum open orders
|
// TODO: Serum open orders
|
||||||
|
// - for each active serum market, pass the OpenOrders in order
|
||||||
|
// - store the base_token_index and quote_token_index in the account, so we don't
|
||||||
|
// need to also pass SerumMarket
|
||||||
|
// - find the bank and oracle for base and quote, and add appropriately
|
||||||
|
|
||||||
Ok(cm!(assets - liabilities))
|
Ok(cm!(assets - liabilities))
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue