mango-v4/programs/mango-v4/tests/test_serum.rs

206 lines
5.1 KiB
Rust
Raw Normal View History

#![cfg(feature = "test-bpf")]
use solana_program_test::*;
use solana_sdk::{signature::Keypair, signer::Signer, transport::TransportError};
2022-08-14 13:06:52 -07:00
use mango_v4::instructions::{Serum3OrderType, Serum3SelfTradeBehavior, Serum3Side};
use program_test::*;
mod program_test;
2022-08-26 06:59:47 -07:00
use mango_setup::*;
#[tokio::test]
async fn test_serum() -> Result<(), TransportError> {
2022-08-23 05:10:38 -07:00
let mut test_builder = TestContextBuilder::new();
test_builder.test().set_compute_max_units(95_000); // Serum3PlaceOrder needs 92.8k
let context = test_builder.start_default().await;
let solana = &context.solana.clone();
let admin = &Keypair::new();
let owner = &context.users[0].key;
let payer = &context.users[1].key;
2022-03-20 23:49:51 -07:00
let mints = &context.mints[0..2];
//
// SETUP: Create a group and an account
//
2022-08-26 06:59:47 -07:00
let GroupWithTokens { group, tokens, .. } = GroupWithTokensConfig {
2022-03-20 23:49:51 -07:00
admin,
payer,
mints,
}
.create(solana)
.await;
let base_token = &tokens[0];
let quote_token = &tokens[1];
2022-08-26 06:59:47 -07:00
let deposit_amount = 1000;
let account = create_funded_account(
&solana,
group,
owner,
0,
&context.users[1],
mints,
deposit_amount,
0,
)
2022-08-26 06:59:47 -07:00
.await;
//
2022-03-20 23:49:51 -07:00
// SETUP: Create serum market
//
2022-03-20 23:49:51 -07:00
let serum_market_cookie = context
.serum
.list_spot_market(&base_token.mint, &quote_token.mint)
.await;
//
// TEST: Register a serum market
//
let serum_market = send_tx(
solana,
Serum3RegisterMarketInstruction {
group,
admin,
serum_program: context.serum.program_id,
serum_market_external: serum_market_cookie.market,
market_index: 0,
base_bank: base_token.bank,
quote_bank: quote_token.bank,
payer,
},
)
.await
.unwrap()
.serum_market;
//
// TEST: Create an open orders account
//
let open_orders = send_tx(
solana,
Serum3CreateOpenOrdersInstruction {
account,
serum_market,
owner,
payer,
},
)
.await
.unwrap()
.open_orders;
let account_data = get_mango_account(solana, account).await;
assert_eq!(
account_data
.active_serum3_orders()
.map(|v| (v.open_orders, v.market_index))
.collect::<Vec<_>>(),
[(open_orders, 0)]
);
2022-03-14 09:21:16 -07:00
//
// TEST: Place an order
//
send_tx(
solana,
Serum3PlaceOrderInstruction {
side: Serum3Side::Bid,
limit_price: 10, // in quote_lot (10) per base lot (100)
max_base_qty: 1, // in base lot (100)
max_native_quote_qty_including_fees: 100,
self_trade_behavior: Serum3SelfTradeBehavior::DecrementTake,
order_type: Serum3OrderType::Limit,
2022-03-14 09:21:16 -07:00
client_order_id: 0,
limit: 10,
account,
owner,
serum_market,
},
)
.await
.unwrap();
check_prev_instruction_post_health(&solana, account).await;
2022-03-20 23:49:51 -07:00
let native0 = account_position(solana, account, base_token.bank).await;
let native1 = account_position(solana, account, quote_token.bank).await;
assert_eq!(native0, 1000);
assert_eq!(native1, 900);
2022-03-19 04:11:56 -07:00
// get the order id
let open_orders_bytes = solana.get_account_data(open_orders).await.unwrap();
let open_orders_data: &serum_dex::state::OpenOrders = bytemuck::from_bytes(
&open_orders_bytes[5..5 + std::mem::size_of::<serum_dex::state::OpenOrders>()],
);
let order_id = open_orders_data.orders[0];
assert!(order_id != 0);
//
// TEST: Cancel the order
//
send_tx(
solana,
Serum3CancelOrderInstruction {
side: Serum3Side::Bid,
2022-03-19 04:11:56 -07:00
order_id,
account,
owner,
serum_market,
},
)
.await
.unwrap();
//
// TEST: Settle, moving the freed up funds back
//
send_tx(
solana,
Serum3SettleFundsInstruction {
account,
owner,
serum_market,
},
)
.await
.unwrap();
2022-03-20 23:49:51 -07:00
let native0 = account_position(solana, account, base_token.bank).await;
let native1 = account_position(solana, account, quote_token.bank).await;
2022-03-19 04:11:56 -07:00
assert_eq!(native0, 1000);
assert_eq!(native1, 1000);
// close oo account
// TODO: custom program error: 0x2a TooManyOpenOrders https://github.com/project-serum/serum-dex/blob/master/dex/src/error.rs#L88
// send_tx(
// solana,
// Serum3CloseOpenOrdersInstruction {
// account,
// serum_market,
// owner,
// sol_destination: payer.pubkey(),
// },
// )
// .await
// .unwrap();
// deregister serum3 market
send_tx(
solana,
Serum3DeregisterMarketInstruction {
group,
admin,
serum_market_external: serum_market_cookie.market,
sol_destination: payer.pubkey(),
},
)
.await
.unwrap();
Ok(())
}