@@ -129,7 +129,7 @@ contract PythLazerTest is Test {
129129 }
130130
131131 /// @notice Build a property with given ID and encoded value bytes
132- /// @param propertyId The property ID (0-8 )
132+ /// @param propertyId The property ID (0-9 )
133133 /// @param valueBytes The encoded value (int64/uint64 = 8 bytes, uint16/int16 = 2 bytes)
134134 function buildProperty (
135135 uint8 propertyId ,
@@ -139,6 +139,7 @@ contract PythLazerTest is Test {
139139 if (propertyId >= 6 && propertyId <= 8 ) {
140140 return abi.encodePacked (propertyId, uint8 (1 ), valueBytes);
141141 } else {
142+ // MarketSession (9) and other properties don't need the exists flag
142143 return abi.encodePacked (propertyId, valueBytes);
143144 }
144145 }
@@ -171,9 +172,9 @@ contract PythLazerTest is Test {
171172 return abi.encodePacked (value);
172173 }
173174
174- /// @notice Test parsing single feed with all 9 properties
175+ /// @notice Test parsing single feed with all 10 properties
175176 function test_parseUpdate_singleFeed_allProperties () public pure {
176- bytes [] memory properties = new bytes [](9 );
177+ bytes [] memory properties = new bytes [](10 );
177178 properties[0 ] = buildProperty (0 , encodeInt64 (100000000 )); // price
178179 properties[1 ] = buildProperty (1 , encodeInt64 (99000000 )); // bestBid
179180 properties[2 ] = buildProperty (2 , encodeInt64 (101000000 )); // bestAsk
@@ -183,6 +184,7 @@ contract PythLazerTest is Test {
183184 properties[6 ] = buildProperty (6 , encodeInt64 (123456 )); // fundingRate
184185 properties[7 ] = buildProperty (7 , encodeUint64 (1234567890 )); // fundingTimestamp
185186 properties[8 ] = buildProperty (8 , encodeUint64 (3600 )); // fundingRateInterval
187+ properties[9 ] = buildProperty (9 , encodeInt16 (0 )); // marketSession (0 = REGULAR)
186188
187189 bytes [] memory feeds = new bytes [](1 );
188190 feeds[0 ] = buildFeedDataMulti (1 , properties); // feedId = 1
@@ -216,6 +218,7 @@ contract PythLazerTest is Test {
216218 assertEq (feed._fundingRate, 123456 );
217219 assertEq (feed._fundingTimestamp, 1234567890 );
218220 assertEq (feed._fundingRateInterval, 3600 );
221+ assertEq (feed._marketSession, 0 );
219222
220223 // Verify exists flags (all should be set)
221224 assertTrue (PythLazerLib.hasPrice (feed));
@@ -227,6 +230,7 @@ contract PythLazerTest is Test {
227230 assertTrue (PythLazerLib.hasFundingRate (feed));
228231 assertTrue (PythLazerLib.hasFundingTimestamp (feed));
229232 assertTrue (PythLazerLib.hasFundingRateInterval (feed));
233+ assertTrue (PythLazerLib.hasMarketSession (feed));
230234 }
231235
232236 /// @notice Test parsing single feed with minimal properties
@@ -270,6 +274,7 @@ contract PythLazerTest is Test {
270274 assertFalse (PythLazerLib.isFundingRateRequested (feed));
271275 assertFalse (PythLazerLib.isFundingTimestampRequested (feed));
272276 assertFalse (PythLazerLib.isFundingRateIntervalRequested (feed));
277+ assertFalse (PythLazerLib.isMarketSessionRequested (feed));
273278 }
274279
275280 /// @notice Test parsing multiple feeds
@@ -325,6 +330,7 @@ contract PythLazerTest is Test {
325330 assertFalse (
326331 PythLazerLib.isFundingRateIntervalRequested (update.feeds[0 ])
327332 );
333+ assertFalse (PythLazerLib.isMarketSessionRequested (update.feeds[0 ]));
328334
329335 // Verify Feed 2
330336 assertEq (update.feeds[1 ].feedId, 2 );
@@ -342,6 +348,7 @@ contract PythLazerTest is Test {
342348 assertFalse (
343349 PythLazerLib.isFundingRateIntervalRequested (update.feeds[1 ])
344350 );
351+ assertFalse (PythLazerLib.isMarketSessionRequested (update.feeds[1 ]));
345352
346353 // Verify Feed 3
347354 assertEq (update.feeds[2 ].feedId, 3 );
@@ -359,6 +366,80 @@ contract PythLazerTest is Test {
359366 assertFalse (
360367 PythLazerLib.isFundingRateIntervalRequested (update.feeds[2 ])
361368 );
369+ assertFalse (PythLazerLib.isMarketSessionRequested (update.feeds[2 ]));
370+ }
371+
372+ /// @notice Test parsing MarketSession property
373+ function test_parseUpdate_marketSession () public pure {
374+ bytes [] memory properties = new bytes [](3 );
375+ properties[0 ] = buildProperty (0 , encodeInt64 (100000000 )); // price
376+ properties[1 ] = buildProperty (4 , encodeInt16 (- 8 )); // exponent
377+ properties[2 ] = buildProperty (9 , encodeInt16 (1 )); // marketSession (1 = PRE_MARKET)
378+
379+ bytes [] memory feeds = new bytes [](1 );
380+ feeds[0 ] = buildFeedDataMulti (1 , properties);
381+
382+ bytes memory payload = buildPayload (
383+ 1700000000 ,
384+ PythLazerStructs.Channel.RealTime,
385+ feeds
386+ );
387+
388+ PythLazerStructs.Update memory update = PythLazerLib
389+ .parseUpdateFromPayload (payload);
390+
391+ PythLazerStructs.Feed memory feed = update.feeds[0 ];
392+
393+ assertEq (feed._marketSession, 1 );
394+ assertTrue (PythLazerLib.hasMarketSession (feed));
395+ assertTrue (PythLazerLib.isMarketSessionRequested (feed));
396+ assertEq (PythLazerLib.getMarketSession (feed), 1 );
397+
398+ // Test different market session values
399+ bytes [] memory properties2 = new bytes [](3 );
400+ properties2[0 ] = buildProperty (0 , encodeInt64 (200000000 ));
401+ properties2[1 ] = buildProperty (4 , encodeInt16 (- 8 ));
402+ properties2[2 ] = buildProperty (9 , encodeInt16 (2 )); // POST_MARKET
403+
404+ bytes [] memory feeds2 = new bytes [](1 );
405+ feeds2[0 ] = buildFeedDataMulti (2 , properties2);
406+
407+ bytes memory payload2 = buildPayload (
408+ 1700000001 ,
409+ PythLazerStructs.Channel.RealTime,
410+ feeds2
411+ );
412+
413+ PythLazerStructs.Update memory update2 = PythLazerLib
414+ .parseUpdateFromPayload (payload2);
415+
416+ PythLazerStructs.Feed memory feed2 = update2.feeds[0 ];
417+ assertEq (feed2._marketSession, 2 );
418+ assertEq (PythLazerLib.getMarketSession (feed2), 2 );
419+ }
420+
421+ /// @notice Test MarketSession getter when not requested
422+ function test_parseUpdate_marketSessionNotRequested () public pure {
423+ bytes [] memory properties = new bytes [](2 );
424+ properties[0 ] = buildProperty (0 , encodeInt64 (100000000 ));
425+ properties[1 ] = buildProperty (4 , encodeInt16 (- 8 ));
426+
427+ bytes [] memory feeds = new bytes [](1 );
428+ feeds[0 ] = buildFeedDataMulti (1 , properties);
429+
430+ bytes memory payload = buildPayload (
431+ 1700000000 ,
432+ PythLazerStructs.Channel.RealTime,
433+ feeds
434+ );
435+
436+ PythLazerStructs.Update memory update = PythLazerLib
437+ .parseUpdateFromPayload (payload);
438+
439+ PythLazerStructs.Feed memory feed = update.feeds[0 ];
440+
441+ assertFalse (PythLazerLib.isMarketSessionRequested (feed));
442+ assertFalse (PythLazerLib.hasMarketSession (feed));
362443 }
363444
364445 /// @notice Test when optional properties are zero
@@ -471,8 +552,8 @@ contract PythLazerTest is Test {
471552
472553 /// @notice Test unknown property ID
473554 function test_parseUpdate_unknownProperty () public {
474- // Build payload with invalid property ID (99 )
475- bytes memory invalidProperty = buildProperty (99 , encodeInt64 (100 ));
555+ // Build payload with invalid property ID (10, which is > 9 )
556+ bytes memory invalidProperty = buildProperty (10 , encodeInt64 (100 ));
476557
477558 bytes [] memory properties = new bytes [](1 );
478559 properties[0 ] = invalidProperty;
0 commit comments