@@ -16,7 +16,7 @@ use crate::math::constants::{
16
16
use crate :: math:: lp:: calculate_settle_lp_metrics;
17
17
use crate :: math:: position:: swap_direction_to_close_position;
18
18
use crate :: math:: repeg;
19
- use crate :: state:: oracle:: { OraclePriceData , PrelaunchOracle } ;
19
+ use crate :: state:: oracle:: { MMOraclePriceData , OraclePriceData , PrelaunchOracle } ;
20
20
use crate :: state:: oracle_map:: OracleMap ;
21
21
use crate :: state:: perp_market:: { AMMLiquiditySplit , PerpMarket , AMM } ;
22
22
use crate :: state:: perp_market_map:: PerpMarketMap ;
@@ -40,6 +40,7 @@ use crate::test_utils::get_hardcoded_pyth_price;
40
40
use crate :: QUOTE_PRECISION_I64 ;
41
41
use anchor_lang:: prelude:: { AccountLoader , Clock } ;
42
42
use anchor_lang:: Owner ;
43
+ use solana_program:: clock;
43
44
use solana_program:: pubkey:: Pubkey ;
44
45
use std:: str:: FromStr ;
45
46
@@ -540,6 +541,9 @@ fn amm_pred_market_example() {
540
541
delay : 1 ,
541
542
has_sufficient_number_of_data_points : true ,
542
543
} ;
544
+ let mm_oracle_price_data = perp_market
545
+ . get_mm_oracle_price_data ( oracle_price_data, clock_slot)
546
+ . unwrap ( ) ;
543
547
544
548
let ( max_bids, max_asks) = calculate_market_open_bids_asks ( & perp_market. amm ) . unwrap ( ) ;
545
549
perp_market. amm . curve_update_intensity = 99 ;
@@ -550,7 +554,7 @@ fn amm_pred_market_example() {
550
554
assert_eq ! ( perp_market. amm. sqrt_k, 56_649_660_613_272 ) ;
551
555
552
556
let ( optimal_peg, fee_budget, _check_lower_bound) =
553
- repeg:: calculate_optimal_peg_and_budget ( & perp_market, & oracle_price_data ) . unwrap ( ) ;
557
+ repeg:: calculate_optimal_peg_and_budget ( & perp_market, & mm_oracle_price_data ) . unwrap ( ) ;
554
558
555
559
assert_eq ! ( perp_market. amm. terminal_quote_asset_reserve, 56405211622548 ) ;
556
560
assert_eq ! ( perp_market. amm. quote_asset_reserve, 56933567973708 ) ;
@@ -581,7 +585,7 @@ fn amm_pred_market_example() {
581
585
582
586
let cost = _update_amm (
583
587
& mut perp_market,
584
- & oracle_price_data ,
588
+ & mm_oracle_price_data ,
585
589
& state,
586
590
now,
587
591
clock_slot,
@@ -678,9 +682,12 @@ fn amm_perp_ref_offset() {
678
682
delay : 1 ,
679
683
has_sufficient_number_of_data_points : true ,
680
684
} ;
685
+ let mm_oracle_price_data = perp_market
686
+ . get_mm_oracle_price_data ( oracle_price_data, clock_slot)
687
+ . unwrap ( ) ;
681
688
let cost = _update_amm (
682
689
& mut perp_market,
683
- & oracle_price_data ,
690
+ & mm_oracle_price_data ,
684
691
& state,
685
692
now,
686
693
clock_slot,
@@ -705,6 +712,47 @@ fn amm_perp_ref_offset() {
705
712
assert_eq ! ( perp_market. amm. ask_base_asset_reserve, 4672813088646692 ) ;
706
713
707
714
crate :: validation:: perp_market:: validate_perp_market ( & perp_market) . unwrap ( ) ;
715
+
716
+ // Update MM oracle and reference price offset stays the same and is applied to the MM oracle
717
+ perp_market. amm . mm_oracle_price = 7200000 ;
718
+ perp_market. amm . mm_oracle_slot = clock_slot;
719
+ let mm_oracle_price_data = perp_market
720
+ . get_mm_oracle_price_data ( oracle_price_data, clock_slot)
721
+ . unwrap ( ) ;
722
+
723
+ let _ = _update_amm (
724
+ & mut perp_market,
725
+ & mm_oracle_price_data,
726
+ & state,
727
+ now,
728
+ clock_slot,
729
+ ) ;
730
+ let reserve_price_mm_offset = perp_market. amm . reserve_price ( ) . unwrap ( ) ;
731
+ let ( b2, a2) = perp_market
732
+ . amm
733
+ . bid_ask_price ( reserve_price_mm_offset)
734
+ . unwrap ( ) ;
735
+ assert_eq ! ( perp_market. amm. reference_price_offset, 132 ) ;
736
+ assert_eq ! ( reserve_price_mm_offset, 7199999 ) ;
737
+ assert_eq ! ( b2, 7197349 ) ;
738
+ assert_eq ! ( a2, 7204578 ) ;
739
+
740
+ // Uses the original oracle if the slot is old, ignoring MM oracle
741
+ perp_market. amm . mm_oracle_price = 7200000 ;
742
+ perp_market. amm . mm_oracle_slot = clock_slot - 100 ;
743
+ let mm_oracle_price = perp_market
744
+ . get_mm_oracle_price_data ( oracle_price_data, clock_slot)
745
+ . unwrap ( ) ;
746
+
747
+ let _ = _update_amm ( & mut perp_market, & mm_oracle_price, & state, now, clock_slot) ;
748
+ let reserve_price_mm_offset_3 = perp_market. amm . reserve_price ( ) . unwrap ( ) ;
749
+ let ( b3, a3) = perp_market
750
+ . amm
751
+ . bid_ask_price ( reserve_price_mm_offset_3)
752
+ . unwrap ( ) ;
753
+ assert_eq ! ( reserve_price_mm_offset_3, r) ;
754
+ assert_eq ! ( b3, b) ;
755
+ assert_eq ! ( a3, a) ;
708
756
}
709
757
710
758
#[ test]
@@ -1131,15 +1179,11 @@ fn amm_split_large_k_with_rebase() {
1131
1179
delay : 14 ,
1132
1180
has_sufficient_number_of_data_points : true ,
1133
1181
} ;
1182
+ let mm_oracle_price = perp_market
1183
+ . get_mm_oracle_price_data ( oracle_price_data, clock_slot)
1184
+ . unwrap ( ) ;
1134
1185
1135
- let cost = _update_amm (
1136
- & mut perp_market,
1137
- & oracle_price_data,
1138
- & state,
1139
- now,
1140
- clock_slot,
1141
- )
1142
- . unwrap ( ) ;
1186
+ let cost = _update_amm ( & mut perp_market, & mm_oracle_price, & state, now, clock_slot) . unwrap ( ) ;
1143
1187
assert_eq ! ( cost, -3017938 ) ;
1144
1188
1145
1189
assert_eq ! ( perp_market. amm. quote_asset_amount_per_lp, 12535655660 ) ;
@@ -2238,10 +2282,13 @@ fn update_amm_near_boundary() {
2238
2282
println ! ( "perp_market: {:?}" , perp_market. amm. last_update_slot) ;
2239
2283
2240
2284
let oracle_price_data = oracle_map. get_price_data ( & perp_market. oracle_id ( ) ) . unwrap ( ) ;
2285
+ let mm_oracle_price_data = perp_market
2286
+ . get_mm_oracle_price_data ( * oracle_price_data, slot)
2287
+ . unwrap ( ) ;
2241
2288
2242
2289
let state = State :: default ( ) ;
2243
2290
2244
- let cost = _update_amm ( & mut perp_market, oracle_price_data , & state, now, slot) . unwrap ( ) ;
2291
+ let cost = _update_amm ( & mut perp_market, & mm_oracle_price_data , & state, now, slot) . unwrap ( ) ;
2245
2292
2246
2293
assert_eq ! ( cost, 18803837952 ) ;
2247
2294
}
@@ -2280,10 +2327,13 @@ fn update_amm_near_boundary2() {
2280
2327
println ! ( "perp_market: {:?}" , perp_market. amm. last_update_slot) ;
2281
2328
2282
2329
let oracle_price_data = oracle_map. get_price_data ( & perp_market. oracle_id ( ) ) . unwrap ( ) ;
2283
-
2330
+ let mm_oracle_price_data = perp_market
2331
+ . get_mm_oracle_price_data ( * oracle_price_data, slot)
2332
+ . unwrap ( ) ;
2284
2333
let state = State :: default ( ) ;
2285
2334
2286
- let cost: i128 = _update_amm ( & mut perp_market, oracle_price_data, & state, now, slot) . unwrap ( ) ;
2335
+ let cost: i128 =
2336
+ _update_amm ( & mut perp_market, & mm_oracle_price_data, & state, now, slot) . unwrap ( ) ;
2287
2337
assert ! ( perp_market. amm. last_oracle_valid) ;
2288
2338
assert_eq ! ( cost, 2987010 ) ;
2289
2339
}
@@ -2322,10 +2372,13 @@ fn recenter_amm_1() {
2322
2372
println ! ( "perp_market: {:?}" , perp_market. amm. last_update_slot) ;
2323
2373
2324
2374
let oracle_price_data = oracle_map. get_price_data ( & perp_market. oracle_id ( ) ) . unwrap ( ) ;
2375
+ let mm_oracle_price_data = perp_market
2376
+ . get_mm_oracle_price_data ( * oracle_price_data, slot)
2377
+ . unwrap ( ) ;
2325
2378
2326
2379
let state = State :: default ( ) ;
2327
2380
2328
- let cost = _update_amm ( & mut perp_market, oracle_price_data , & state, now, slot) . unwrap ( ) ;
2381
+ let cost = _update_amm ( & mut perp_market, & mm_oracle_price_data , & state, now, slot) . unwrap ( ) ;
2329
2382
2330
2383
assert_eq ! ( cost, 2987010 ) ;
2331
2384
@@ -2422,10 +2475,15 @@ fn recenter_amm_2() {
2422
2475
let oracle_price_data = oracle_map
2423
2476
. get_price_data ( & ( oracle_price_key, OracleSource :: Pyth ) )
2424
2477
. unwrap ( ) ;
2478
+ let mm_oracle_price_data = MMOraclePriceData {
2479
+ mm_oracle_price : oracle_price_data. price ,
2480
+ mm_oracle_delay : oracle_price_data. delay + 1 ,
2481
+ oracle_price_data : * oracle_price_data,
2482
+ } ;
2425
2483
2426
2484
let state = State :: default ( ) ;
2427
2485
2428
- let cost = _update_amm ( & mut perp_market, oracle_price_data , & state, now, slot) . unwrap ( ) ;
2486
+ let cost = _update_amm ( & mut perp_market, & mm_oracle_price_data , & state, now, slot) . unwrap ( ) ;
2429
2487
2430
2488
assert_eq ! ( cost, 0 ) ;
2431
2489
@@ -2551,10 +2609,15 @@ fn test_move_amm() {
2551
2609
let oracle_price_data = oracle_map
2552
2610
. get_price_data ( & ( oracle_price_key, OracleSource :: Pyth ) )
2553
2611
. unwrap ( ) ;
2612
+ let mm_oracle_price_data = MMOraclePriceData {
2613
+ mm_oracle_price : oracle_price_data. price ,
2614
+ mm_oracle_delay : oracle_price_data. delay + 1 ,
2615
+ oracle_price_data : * oracle_price_data,
2616
+ } ;
2554
2617
2555
2618
let state = State :: default ( ) ;
2556
2619
2557
- let cost = _update_amm ( & mut perp_market, oracle_price_data , & state, now, slot) . unwrap ( ) ;
2620
+ let cost = _update_amm ( & mut perp_market, & mm_oracle_price_data , & state, now, slot) . unwrap ( ) ;
2558
2621
2559
2622
assert_eq ! ( cost, 0 ) ;
2560
2623
0 commit comments