148 lines
4.6 KiB
Rust
148 lines
4.6 KiB
Rust
//! Exchange program
|
|
|
|
use crate::exchange_state::*;
|
|
use crate::id;
|
|
use serde_derive::{Deserialize, Serialize};
|
|
use solana_sdk::instruction::{AccountMeta, Instruction};
|
|
use solana_sdk::pubkey::Pubkey;
|
|
|
|
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
|
|
pub struct TradeRequestInfo {
|
|
/// Direction of trade
|
|
pub direction: Direction,
|
|
|
|
/// Token pair to trade
|
|
pub pair: TokenPair,
|
|
|
|
/// Number of tokens to exchange; refers to the primary or the secondary depending on the direction
|
|
pub tokens: u64,
|
|
|
|
/// The price ratio the primary price over the secondary price. The primary price is fixed
|
|
/// and equal to the variable `SCALER`.
|
|
pub price: u64,
|
|
|
|
/// Token account to deposit tokens on successful swap
|
|
pub dst_account: Pubkey,
|
|
}
|
|
|
|
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
|
|
pub enum ExchangeInstruction {
|
|
/// New token account
|
|
/// key 0 - Signer
|
|
/// key 1 - New token account
|
|
AccountRequest,
|
|
|
|
/// Transfer tokens between two accounts
|
|
/// key 0 - Account to transfer tokens to
|
|
/// key 1 - Account to transfer tokens from. This can be the exchange program itself,
|
|
/// the exchange has a limitless number of tokens it can transfer.
|
|
TransferRequest(Token, u64),
|
|
|
|
/// Trade request
|
|
/// key 0 - Signer
|
|
/// key 1 - Account in which to record the swap
|
|
/// key 2 - Token account associated with this trade
|
|
TradeRequest(TradeRequestInfo),
|
|
|
|
/// Trade cancellation
|
|
/// key 0 - Signer
|
|
/// key 1 -Ttrade order to cancel
|
|
TradeCancellation,
|
|
|
|
/// Trade swap request
|
|
/// key 0 - Signer
|
|
/// key 1 - Account in which to record the swap
|
|
/// key 2 - 'To' trade order
|
|
/// key 3 - `From` trade order
|
|
/// key 4 - Token account associated with the To Trade
|
|
/// key 5 - Token account associated with From trade
|
|
/// key 6 - Token account in which to deposit the brokers profit from the swap.
|
|
SwapRequest,
|
|
}
|
|
impl ExchangeInstruction {
|
|
pub fn new_account_request(owner: &Pubkey, new: &Pubkey) -> Instruction {
|
|
let account_metas = vec![
|
|
AccountMeta::new(*owner, true),
|
|
AccountMeta::new(*new, false),
|
|
];
|
|
Instruction::new(id(), &ExchangeInstruction::AccountRequest, account_metas)
|
|
}
|
|
|
|
pub fn new_transfer_request(
|
|
owner: &Pubkey,
|
|
to: &Pubkey,
|
|
from: &Pubkey,
|
|
token: Token,
|
|
tokens: u64,
|
|
) -> Instruction {
|
|
let account_metas = vec![
|
|
AccountMeta::new(*owner, true),
|
|
AccountMeta::new(*to, false),
|
|
AccountMeta::new(*from, false),
|
|
];
|
|
Instruction::new(
|
|
id(),
|
|
&ExchangeInstruction::TransferRequest(token, tokens),
|
|
account_metas,
|
|
)
|
|
}
|
|
|
|
pub fn new_trade_request(
|
|
owner: &Pubkey,
|
|
trade: &Pubkey,
|
|
direction: Direction,
|
|
pair: TokenPair,
|
|
tokens: u64,
|
|
price: u64,
|
|
src_account: &Pubkey,
|
|
dst_account: &Pubkey,
|
|
) -> Instruction {
|
|
let account_metas = vec![
|
|
AccountMeta::new(*owner, true),
|
|
AccountMeta::new(*trade, false),
|
|
AccountMeta::new(*src_account, false),
|
|
];
|
|
Instruction::new(
|
|
id(),
|
|
&ExchangeInstruction::TradeRequest(TradeRequestInfo {
|
|
direction,
|
|
pair,
|
|
tokens,
|
|
price,
|
|
dst_account: *dst_account,
|
|
}),
|
|
account_metas,
|
|
)
|
|
}
|
|
|
|
pub fn new_trade_cancellation(owner: &Pubkey, trade: &Pubkey, account: &Pubkey) -> Instruction {
|
|
let account_metas = vec![
|
|
AccountMeta::new(*owner, true),
|
|
AccountMeta::new(*trade, false),
|
|
AccountMeta::new(*account, false),
|
|
];
|
|
Instruction::new(id(), &ExchangeInstruction::TradeCancellation, account_metas)
|
|
}
|
|
|
|
pub fn new_swap_request(
|
|
owner: &Pubkey,
|
|
swap: &Pubkey,
|
|
to_trade: &Pubkey,
|
|
from_trade: &Pubkey,
|
|
to_trade_account: &Pubkey,
|
|
from_trade_account: &Pubkey,
|
|
profit_account: &Pubkey,
|
|
) -> Instruction {
|
|
let account_metas = vec![
|
|
AccountMeta::new(*owner, true),
|
|
AccountMeta::new(*swap, false),
|
|
AccountMeta::new(*to_trade, false),
|
|
AccountMeta::new(*from_trade, false),
|
|
AccountMeta::new(*to_trade_account, false),
|
|
AccountMeta::new(*from_trade_account, false),
|
|
AccountMeta::new(*profit_account, false),
|
|
];
|
|
Instruction::new(id(), &ExchangeInstruction::SwapRequest, account_metas)
|
|
}
|
|
}
|