11//! Program state processor
22
33use crate :: {
4- self as spl_token_lending,
4+ self as spl_token_lending, emit_log_event ,
55 error:: LendingError ,
66 instruction:: LendingInstruction ,
7- logs:: { emit_log_event, PythOraclePriceUpdate , SwitchboardV1OraclePriceUpdate } ,
7+ logs:: {
8+ LogEventType , PythError , PythOraclePriceUpdate , SwitchboardError ,
9+ SwitchboardV1OraclePriceUpdate ,
10+ } ,
811 math:: { Decimal , Rate , TryAdd , TryDiv , TryMul , TrySub , WAD } ,
912 pyth,
1013 state:: {
@@ -2153,15 +2156,24 @@ fn get_pyth_price(pyth_price_info: &AccountInfo, clock: &Clock) -> Result<Decima
21532156 . map_err ( |_| ProgramError :: InvalidAccountData ) ?;
21542157
21552158 if pyth_price. ptype != pyth:: PriceType :: Price {
2156- msg ! ( "Oracle price type is invalid {}" , pyth_price. ptype as u8 ) ;
2159+ emit_log_event ! ( & PythError {
2160+ event_type: LogEventType :: PythOraclePriceUpdateType ,
2161+ oracle_pubkey: * pyth_price_info. key,
2162+ error_message: format!( "Oracle price type is invalid: {}" , pyth_price. ptype as u8 ) ,
2163+ } ) ;
2164+
21572165 return Err ( LendingError :: InvalidOracleConfig . into ( ) ) ;
21582166 }
21592167
21602168 if pyth_price. agg . status != pyth:: PriceStatus :: Trading {
2161- msg ! (
2162- "Oracle price status is invalid: {}" ,
2163- pyth_price. agg. status as u8
2164- ) ;
2169+ emit_log_event ! ( & PythError {
2170+ event_type: LogEventType :: PythOraclePriceUpdateType ,
2171+ oracle_pubkey: * pyth_price_info. key,
2172+ error_message: format!(
2173+ "Oracle price status is invalid: {}" ,
2174+ pyth_price. agg. status as u8
2175+ ) ,
2176+ } ) ;
21652177 return Err ( LendingError :: InvalidOracleConfig . into ( ) ) ;
21662178 }
21672179
@@ -2170,12 +2182,20 @@ fn get_pyth_price(pyth_price_info: &AccountInfo, clock: &Clock) -> Result<Decima
21702182 . checked_sub ( pyth_price. valid_slot )
21712183 . ok_or ( LendingError :: MathOverflow ) ?;
21722184 if slots_elapsed >= STALE_AFTER_SLOTS_ELAPSED {
2173- msg ! ( "Pyth oracle price is stale" ) ;
2185+ emit_log_event ! ( & PythError {
2186+ event_type: LogEventType :: PythOraclePriceUpdateType ,
2187+ oracle_pubkey: * pyth_price_info. key,
2188+ error_message: format!( "Pyth oracle price is stale: {} slots old." , slots_elapsed) ,
2189+ } ) ;
21742190 return Err ( LendingError :: InvalidOracleConfig . into ( ) ) ;
21752191 }
21762192
21772193 let price: u64 = pyth_price. agg . price . try_into ( ) . map_err ( |_| {
2178- msg ! ( "Oracle price cannot be negative" ) ;
2194+ emit_log_event ! ( & PythError {
2195+ event_type: LogEventType :: PythOraclePriceUpdateType ,
2196+ oracle_pubkey: * pyth_price_info. key,
2197+ error_message: "Oracle price cannot be negative" . to_string( ) ,
2198+ } ) ;
21792199 LendingError :: InvalidOracleConfig
21802200 } ) ?;
21812201
@@ -2186,11 +2206,15 @@ fn get_pyth_price(pyth_price_info: &AccountInfo, clock: &Clock) -> Result<Decima
21862206 // 100/confidence_ratio = maximum size of confidence range as a percent of price
21872207 // confidence_ratio of 10 filters out pyth prices with conf > 10% of price
21882208 if conf. checked_mul ( confidence_ratio) . unwrap ( ) > price {
2189- msg ! (
2190- "Oracle price confidence is too wide. price: {}, conf: {}" ,
2191- price,
2192- conf,
2193- ) ;
2209+ emit_log_event ! ( & PythError {
2210+ event_type: LogEventType :: PythOraclePriceUpdateType ,
2211+ oracle_pubkey: * pyth_price_info. key,
2212+ error_message: format!(
2213+ "Oracle price confidence is too wide. price: {}, conf: {}" ,
2214+ price, conf
2215+ ) ,
2216+ } ) ;
2217+
21942218 return Err ( LendingError :: InvalidOracleConfig . into ( ) ) ;
21952219 }
21962220
@@ -2215,10 +2239,11 @@ fn get_pyth_price(pyth_price_info: &AccountInfo, clock: &Clock) -> Result<Decima
22152239 . ok_or ( LendingError :: MathOverflow ) ?;
22162240 Decimal :: from ( price) . try_div ( decimals) ?
22172241 } ;
2218- emit_log_event ( & PythOraclePriceUpdate {
2242+ emit_log_event ! ( & PythOraclePriceUpdate {
2243+ event_type: LogEventType :: PythOraclePriceUpdateType ,
22192244 oracle_pubkey: * pyth_price_info. key,
22202245 price: market_price,
2221- conf : conf,
2246+ confidence : conf,
22222247 published_slot: pyth_price. valid_slot,
22232248 } ) ;
22242249
@@ -2238,7 +2263,11 @@ fn get_switchboard_price(
22382263 let account_buf = switchboard_feed_info. try_borrow_data ( ) ?;
22392264 // first byte type discriminator
22402265 if account_buf[ 0 ] != SwitchboardAccountType :: TYPE_AGGREGATOR as u8 {
2241- msg ! ( "switchboard address not of type aggregator" ) ;
2266+ emit_log_event ! ( & SwitchboardError {
2267+ event_type: LogEventType :: SwitchboardErrorType ,
2268+ oracle_pubkey: * switchboard_feed_info. key,
2269+ error_message: "Switchboard feed is not of type aggregator" . to_string( ) ,
2270+ } ) ;
22422271 return Err ( LendingError :: InvalidAccountInput . into ( ) ) ;
22432272 }
22442273
@@ -2254,7 +2283,11 @@ fn get_switchboard_price(
22542283 . checked_sub ( open_slot)
22552284 . ok_or ( LendingError :: MathOverflow ) ?;
22562285 if slots_elapsed >= STALE_AFTER_SLOTS_ELAPSED {
2257- msg ! ( "Switchboard oracle price is stale" ) ;
2286+ emit_log_event ! ( & SwitchboardError {
2287+ event_type: LogEventType :: SwitchboardErrorType ,
2288+ oracle_pubkey: * switchboard_feed_info. key,
2289+ error_message: format!( "Oracle price is stale by {} slots" , slots_elapsed) ,
2290+ } ) ;
22582291 return Err ( LendingError :: InvalidOracleConfig . into ( ) ) ;
22592292 }
22602293
@@ -2266,7 +2299,8 @@ fn get_switchboard_price(
22662299 let price = ( ( price_quotient as f64 ) * price_float) as u128 ;
22672300
22682301 let market_price = Decimal :: from ( price) . try_div ( price_quotient) ?;
2269- emit_log_event ( & SwitchboardV1OraclePriceUpdate {
2302+ emit_log_event ! ( & SwitchboardV1OraclePriceUpdate {
2303+ event_type: LogEventType :: SwitchboardV1OraclePriceUpdateType ,
22702304 oracle_pubkey: * switchboard_feed_info. key,
22712305 price: market_price,
22722306 published_slot: open_slot,
0 commit comments