Direct theft of any user funds, whether at-rest or in-motion, other than unclaimed yield
Description
Brief/Intro
In current implementation for oracle-contract.get_price, while function is_pyth_price_stale_or_outside_confidence return true in main.sw#L88, Redstone price feed will be used.
However there is a flaw when using Redstone price feed that might lead stale price being used.
Vulnerability Details
According to oracle-contract.get_price, when redstone is used, redstone.read_timestamp will be used as the price 's publish timestamp.
And redstone.read_timestamp will be checked against with current_time in main.sw#L107
The issue is that redstone.read_timestamp uses Unix timestamp, but Fule's timestamp function returns TAI64 format timestamp
63 /// Get the TAI64 timestamp of a block at a given `block_height`.
64 ///
65 /// # Additional Information
66 ///
67 /// The TAI64 timestamp begins at 2^62 seconds before 1970, and ends at 2^62 seconds after 1970,
68 /// with a TAI second defined as the duration of 9192631770 periods of the radiation corresponding
69 /// to the transition between the two hyperfine levels of the ground state of the cesium atom.
70 ///
71 /// # Arguments
72 ///
73 /// * `block_height`: [u32] - The height of the block to get the timestamp of.
74 ///
75 /// # Returns
76 ///
77 /// * [u64] - The TAI64 timestamp of the block at `block_height`.
78 ///
79 /// # Examples
80 ///
81 /// ```sway
82 /// use std::block::timestamp_of_block;
83 ///
84 /// fn foo() {
85 /// let timestamp_of_block_100 = timestamp_of_block(100u32);
86 /// log(timestamp_of_block_100);
87 /// }
88 /// ```
89 pub fn timestamp_of_block(block_height: u32) -> u64 {
90 asm(timestamp, height: block_height) {
91 time timestamp height;
92 timestamp: u64
93 }
94 }
From above code, we can see that timestamp() returns [The TAI64 timestamp of the current block.] (https://github.com/FuelLabs/sway/blob/6d9065b8d762a39eb475562426a2d4ed17d92d00/sway-lib-std/src/block.sw#L47)