#[cfg(test)]
mod tests {
use crate::accounts::{fetch_all_vault, fetch_tuna_config, fetch_tuna_spot_position};
use crate::instructions::{CreateMarketInstructionArgs, OpenTunaSpotPositionInstructionArgs};
use crate::modify_tuna_spot_position_fusion::{modify_tuna_spot_position_fusion_instructions, ModifyTunaSpotPositionArgs};
use crate::tests::fusion::swap_exact_in;
use crate::tests::*;
use crate::types::{MarketMaker, PoolToken};
use crate::{
close_tuna_spot_position_instructions, get_tuna_config_address, get_tuna_spot_position_address,
liquidate_tuna_spot_position_fusion_instructions, open_tuna_spot_position_instructions, HUNDRED_PERCENT, LEVERAGE_ONE,
};
use fusionamm_client::fetch_fusion_pool;
use rstest::rstest;
use serial_test::serial;
use solana_keypair::Keypair;
use solana_program_test::tokio;
use solana_signer::Signer;
fn test_market_args() -> CreateMarketInstructionArgs {
CreateMarketInstructionArgs {
address_lookup_table: Default::default(),
max_leverage: (LEVERAGE_ONE * 1020) / 100,
protocol_fee: 1000, protocol_fee_on_collateral: 1000, liquidation_fee: 10000, liquidation_threshold: 920000, oracle_price_deviation_threshold: HUNDRED_PERCENT / 2, disabled: false,
borrow_limit_a: 0,
borrow_limit_b: 0,
max_swap_slippage: 0,
rebalance_protocol_fee: 0,
spot_position_size_limit_a: 1000_000_000_000,
spot_position_size_limit_b: 100000_000_000,
}
}
#[rstest]
#[case(false)]
#[case(true)]
#[serial]
fn test_open_increase_decrease_close_position(#[case] permissionless: bool) {
let rt = tokio::runtime::Runtime::new().unwrap();
rt.block_on(async {
let signer = Keypair::new();
let ctx = RpcContext::new(&signer, fusion::get_fusion_pool_config_accounts(&signer.pubkey())).await;
let test_market = setup_test_market(
&ctx,
test_market_args(),
MarketMaker::Fusion,
TestMarketArgs {
permissionless,
..TestMarketArgs::default()
},
)
.await
.unwrap();
let instructions = open_tuna_spot_position_instructions(
&ctx.rpc,
&ctx.signer.pubkey(),
&test_market.pool,
OpenTunaSpotPositionInstructionArgs {
position_token: PoolToken::A,
collateral_token: PoolToken::A,
},
)
.unwrap();
ctx.send_transaction(instructions).unwrap();
ctx.send_transaction(
modify_tuna_spot_position_fusion_instructions(
&ctx.rpc,
&ctx.signer.pubkey(),
&test_market.pool,
None,
ModifyTunaSpotPositionArgs {
decrease_percent: 0,
collateral_amount: 1_000_000_000,
borrow_amount: 1_000_000_000,
required_swap_amount: 0,
},
)
.unwrap(),
)
.unwrap();
ctx.send_transaction(
modify_tuna_spot_position_fusion_instructions(
&ctx.rpc,
&ctx.signer.pubkey(),
&test_market.pool,
None,
ModifyTunaSpotPositionArgs {
decrease_percent: HUNDRED_PERCENT,
collateral_amount: 0,
borrow_amount: 0,
required_swap_amount: 0,
},
)
.unwrap(),
)
.unwrap();
ctx.send_transaction(close_tuna_spot_position_instructions(&ctx.rpc, &ctx.signer.pubkey(), &test_market.pool).unwrap())
.unwrap();
});
}
#[rstest]
#[case(false)]
#[case(true)]
#[serial]
fn test_liquidate_position(#[case] permissionless: bool) {
let rt = tokio::runtime::Runtime::new().unwrap();
rt.block_on(async {
let signer = Keypair::new();
let ctx = RpcContext::new(&signer, fusion::get_fusion_pool_config_accounts(&signer.pubkey())).await;
let test_market = setup_test_market(
&ctx,
test_market_args(),
MarketMaker::Fusion,
TestMarketArgs {
permissionless,
..TestMarketArgs::default()
},
)
.await
.unwrap();
let pool = fetch_fusion_pool(&ctx.rpc, &test_market.pool).unwrap();
let tuna_config = fetch_tuna_config(&ctx.rpc, &get_tuna_config_address().0).unwrap();
let mut instructions = open_tuna_spot_position_instructions(
&ctx.rpc,
&ctx.signer.pubkey(),
&test_market.pool,
OpenTunaSpotPositionInstructionArgs {
position_token: PoolToken::A,
collateral_token: PoolToken::A,
},
)
.unwrap();
let mut increase_ixs = modify_tuna_spot_position_fusion_instructions(
&ctx.rpc,
&ctx.signer.pubkey(),
&test_market.pool,
Some(PoolToken::A),
ModifyTunaSpotPositionArgs {
decrease_percent: 0,
collateral_amount: 1_000_000_000,
borrow_amount: 1_500_000_000,
required_swap_amount: 0,
},
)
.unwrap();
instructions.append(&mut increase_ixs);
ctx.send_transaction(instructions).unwrap();
swap_exact_in(&ctx, &pool.address, 500000000000, &pool.data.token_mint_a, None)
.await
.unwrap();
let tuna_position_address = get_tuna_spot_position_address(&signer.pubkey(), &test_market.pool).0;
let tuna_position = fetch_tuna_spot_position(&ctx.rpc, &tuna_position_address).unwrap();
let vaults = fetch_all_vault(&ctx.rpc, &[test_market.vault_a, test_market.vault_b]).unwrap();
ctx.send_transaction(liquidate_tuna_spot_position_fusion_instructions(
&ctx.signer.pubkey(),
&tuna_position.data,
&tuna_config.data,
&vaults[0].address,
&vaults[0].data,
&vaults[1].address,
&vaults[1].data,
&pool.data,
&test_market.token_program_a,
&test_market.token_program_b,
None,
))
.unwrap();
});
}
}