Programs: fix for audit v0.25.0 (#970)
* Programs: remove anchor close has it is done manually anyway * Programs: fix a bug where a pegged order might be skipped even if it was valid
This commit is contained in:
parent
f7bb4955d3
commit
905cc01414
|
@ -13,10 +13,7 @@ pub struct GroupChangeInsuranceFund<'info> {
|
||||||
pub group: AccountLoader<'info, Group>,
|
pub group: AccountLoader<'info, Group>,
|
||||||
pub admin: Signer<'info>,
|
pub admin: Signer<'info>,
|
||||||
|
|
||||||
#[account(
|
#[account(mut)]
|
||||||
mut,
|
|
||||||
close = payer,
|
|
||||||
)]
|
|
||||||
pub insurance_vault: Account<'info, TokenAccount>,
|
pub insurance_vault: Account<'info, TokenAccount>,
|
||||||
|
|
||||||
#[account(mut)]
|
#[account(mut)]
|
||||||
|
|
|
@ -238,6 +238,7 @@ impl BookSide {
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use bytemuck::Zeroable;
|
use bytemuck::Zeroable;
|
||||||
|
use std::collections::HashSet;
|
||||||
|
|
||||||
fn new_order_tree(order_tree_type: OrderTreeType) -> OrderTreeNodes {
|
fn new_order_tree(order_tree_type: OrderTreeType) -> OrderTreeNodes {
|
||||||
let mut ot = OrderTreeNodes::zeroed();
|
let mut ot = OrderTreeNodes::zeroed();
|
||||||
|
@ -281,8 +282,11 @@ mod tests {
|
||||||
.insert_leaf(&mut root_pegged, &new_leaf(key))
|
.insert_leaf(&mut root_pegged, &new_leaf(key))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
let mut pegged_prices = vec![];
|
||||||
|
|
||||||
while root_pegged.leaf_count < 100 {
|
while root_pegged.leaf_count < 100 {
|
||||||
let price_data: u64 = oracle_pegged_price_data(rng.gen_range(-20..20));
|
let price = rng.gen_range(-20..20);
|
||||||
|
let price_data: u64 = oracle_pegged_price_data(price);
|
||||||
let seq_num: u64 = rng.gen_range(0..1000);
|
let seq_num: u64 = rng.gen_range(0..1000);
|
||||||
let key = new_node_key(side, price_data, seq_num);
|
let key = new_node_key(side, price_data, seq_num);
|
||||||
if keys.contains(&key) {
|
if keys.contains(&key) {
|
||||||
|
@ -292,6 +296,7 @@ mod tests {
|
||||||
order_tree
|
order_tree
|
||||||
.insert_leaf(&mut root_pegged, &new_leaf(key))
|
.insert_leaf(&mut root_pegged, &new_leaf(key))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
pegged_prices.push(price);
|
||||||
}
|
}
|
||||||
|
|
||||||
while root_fixed.leaf_count < 100 {
|
while root_fixed.leaf_count < 100 {
|
||||||
|
@ -332,6 +337,12 @@ mod tests {
|
||||||
total += 1;
|
total += 1;
|
||||||
}
|
}
|
||||||
assert!(total >= 101); // some oracle peg orders could be skipped
|
assert!(total >= 101); // some oracle peg orders could be skipped
|
||||||
|
|
||||||
|
let skipped_pegged_orders = pegged_prices
|
||||||
|
.iter()
|
||||||
|
.filter(|x| oracle_price_lots + **x <= 0)
|
||||||
|
.count();
|
||||||
|
assert_eq!(total, 200 - skipped_pegged_orders);
|
||||||
if oracle_price_lots > 20 {
|
if oracle_price_lots > 20 {
|
||||||
assert_eq!(total, 200);
|
assert_eq!(total, 200);
|
||||||
}
|
}
|
||||||
|
@ -340,15 +351,31 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn bookside_iteration_random() {
|
fn bookside_iteration_random() {
|
||||||
|
for i in 0..10 {
|
||||||
bookside_iteration_random_helper(Side::Bid);
|
bookside_iteration_random_helper(Side::Bid);
|
||||||
bookside_iteration_random_helper(Side::Ask);
|
bookside_iteration_random_helper(Side::Ask);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn bookside_setup() -> BookSide {
|
fn bookside_setup() -> BookSide {
|
||||||
|
bookside_setup_advanced(
|
||||||
|
&[(100, 0), (120, 5)],
|
||||||
|
&[(-10, 0, 100), (-15, 0, -1), (-20, 7, 95)],
|
||||||
|
Side::Bid,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn bookside_setup_advanced(
|
||||||
|
fixed: &[(i64, u16)],
|
||||||
|
pegged: &[(i64, u16, i64)],
|
||||||
|
side: Side,
|
||||||
|
) -> BookSide {
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
|
|
||||||
let side = Side::Bid;
|
let order_tree_type = match side {
|
||||||
let order_tree_type = OrderTreeType::Bids;
|
Side::Bid => OrderTreeType::Bids,
|
||||||
|
Side::Ask => OrderTreeType::Asks,
|
||||||
|
};
|
||||||
|
|
||||||
let order_tree = RefCell::new(new_order_tree(order_tree_type));
|
let order_tree = RefCell::new(new_order_tree(order_tree_type));
|
||||||
let mut root_fixed = OrderTreeRoot::zeroed();
|
let mut root_fixed = OrderTreeRoot::zeroed();
|
||||||
|
@ -381,11 +408,12 @@ mod tests {
|
||||||
.unwrap();
|
.unwrap();
|
||||||
};
|
};
|
||||||
|
|
||||||
add_fixed(100, 0);
|
for (price, tif) in fixed {
|
||||||
add_fixed(120, 5);
|
add_fixed(*price, *tif);
|
||||||
add_pegged(-10, 0, 100);
|
}
|
||||||
add_pegged(-15, 0, -1);
|
for (price_offset, tif, limit) in pegged {
|
||||||
add_pegged(-20, 7, 95);
|
add_pegged(*price_offset, *tif, *limit);
|
||||||
|
}
|
||||||
|
|
||||||
BookSide {
|
BookSide {
|
||||||
roots: [root_fixed, root_pegged],
|
roots: [root_fixed, root_pegged],
|
||||||
|
@ -458,4 +486,26 @@ mod tests {
|
||||||
assert_eq!(p, 120);
|
assert_eq!(p, 120);
|
||||||
assert_eq!(order_prices(0, 100), Vec::<i64>::new());
|
assert_eq!(order_prices(0, 100), Vec::<i64>::new());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn bookside_iterate_when_first_peg_is_skipped() {
|
||||||
|
use std::cell::RefCell;
|
||||||
|
|
||||||
|
let bookside = RefCell::new(bookside_setup_advanced(
|
||||||
|
&[],
|
||||||
|
&[(-100, 0, 50), (-20, 0, 50), (-30, 0, 50)],
|
||||||
|
Side::Ask,
|
||||||
|
));
|
||||||
|
|
||||||
|
let order_prices = |now_ts: u64, oracle: i64| -> Vec<i64> {
|
||||||
|
bookside
|
||||||
|
.borrow()
|
||||||
|
.iter_valid(now_ts, oracle)
|
||||||
|
.map(|it| it.price_lots)
|
||||||
|
.collect()
|
||||||
|
};
|
||||||
|
|
||||||
|
assert_eq!(order_prices(0, 200), vec![100, 170, 180]);
|
||||||
|
assert_eq!(order_prices(0, 100), vec![70, 80]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -170,7 +170,8 @@ impl<'a> Iterator for BookSideIter<'a> {
|
||||||
if oracle_pegged_price(self.oracle_price_lots, o_node, side).0 != OrderState::Skipped {
|
if oracle_pegged_price(self.oracle_price_lots, o_node, side).0 != OrderState::Skipped {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
o_peek = self.oracle_pegged_iter.next()
|
self.oracle_pegged_iter.next();
|
||||||
|
o_peek = self.oracle_pegged_iter.peek();
|
||||||
}
|
}
|
||||||
|
|
||||||
let f_peek = self.fixed_iter.peek();
|
let f_peek = self.fixed_iter.peek();
|
||||||
|
|
Loading…
Reference in New Issue