@@ -712,6 +712,39 @@ impl ProtocolSim for UniswapV4State {
712712 }
713713 }
714714
715+ // Update block information if provided in the delta attributes
716+ let block_number_bytes = delta
717+ .updated_attributes
718+ .get("block_number")
719+ .ok_or_else(|| {
720+ SimulationError::FatalError("block_number not found in updated attributes".into())
721+ })?;
722+
723+ self.block.number = u64::from_be_bytes(
724+ block_number_bytes[block_number_bytes.len() - 8..]
725+ .try_into()
726+ .map_err(|_| {
727+ TransitionError::DecodeError("Invalid block_number bytes".to_string())
728+ })?,
729+ );
730+
731+ let block_timestamp_bytes = delta
732+ .updated_attributes
733+ .get("block_timestamp")
734+ .ok_or_else(|| {
735+ SimulationError::FatalError(
736+ "block_timestamp not found in updated attributes".into(),
737+ )
738+ })?;
739+
740+ self.block.timestamp = u64::from_be_bytes(
741+ block_timestamp_bytes[block_timestamp_bytes.len() - 8..]
742+ .try_into()
743+ .map_err(|_| {
744+ TransitionError::DecodeError("Invalid block_timestamp bytes".to_string())
745+ })?,
746+ );
747+
715748 // Apply attribute changes
716749 if let Some(liquidity) = delta
717750 .updated_attributes
@@ -862,6 +895,46 @@ mod tests {
862895 )
863896 }
864897
898+ #[test]
899+ fn test_delta_transition_missing_block_update() {
900+ let block = BlockHeader {
901+ number: 1000,
902+ hash: Bytes::from_str(
903+ "0x28d41d40f2ac275a4f5f621a636b9016b527d11d37d610a45ac3a821346ebf8c",
904+ )
905+ .expect("Invalid block hash"),
906+ parent_hash: Bytes::from(vec![0; 32]),
907+ revert: false,
908+ timestamp: 1758201863,
909+ };
910+ let mut pool = UniswapV4State::new(
911+ 1000,
912+ U256::from_str("1000").unwrap(),
913+ UniswapV4Fees { zero_for_one: 100, one_for_zero: 90, lp_fee: 700 },
914+ 100,
915+ 60,
916+ vec![TickInfo::new(120, 10000), TickInfo::new(180, -10000)],
917+ block,
918+ );
919+
920+ assert_eq!(pool.block.number, 1000);
921+ assert_eq!(pool.block.timestamp, 1758201863);
922+
923+ let attributes: HashMap<String, Bytes> =
924+ [("block_number".to_string(), Bytes::from(2000_u64.to_be_bytes().to_vec()))]
925+ .into_iter()
926+ .collect();
927+
928+ let delta = ProtocolStateDelta {
929+ component_id: "State1".to_owned(),
930+ updated_attributes: attributes,
931+ deleted_attributes: HashSet::new(),
932+ };
933+
934+ let result = pool.delta_transition(delta, &HashMap::new(), &Balances::default());
935+ assert!(result.is_err())
936+ }
937+
865938 #[test]
866939 fn test_delta_transition() {
867940 let block = BlockHeader {
@@ -893,6 +966,8 @@ mod tests {
893966 ("fee".to_string(), Bytes::from(100_u32.to_be_bytes().to_vec())),
894967 ("ticks/-120/net_liquidity".to_string(), Bytes::from(10200_u64.to_be_bytes().to_vec())),
895968 ("ticks/120/net_liquidity".to_string(), Bytes::from(9800_u64.to_be_bytes().to_vec())),
969+ ("block_number".to_string(), Bytes::from(2000_u64.to_be_bytes().to_vec())),
970+ ("block_timestamp".to_string(), Bytes::from(1758201935_u64.to_be_bytes().to_vec())),
896971 ]
897972 .into_iter()
898973 .collect();
@@ -926,6 +1001,9 @@ mod tests {
9261001 .net_liquidity,
9271002 9800
9281003 );
1004+ // Verify block was updated
1005+ assert_eq!(pool.block.number, 2000);
1006+ assert_eq!(pool.block.timestamp, 1758201935);
9291007 }
9301008
9311009 #[tokio::test]
0 commit comments