Boost _ Folks Finance 33443 - [Smart Contract - Low] StalenessCircuitBreakerNode checks if the last update time of the parent node is less than the threshold but the publicTime could be greater than current blocktimestamp
Submitted on Sat Jul 20 2024 14:42:29 GMT-0400 (Atlantic Standard Time) by @Tripathi for Boost | Folks Finance
Report ID: #33443
Report type: Smart Contract
Report severity: Low
Target: https://testnet.snowtrace.io/address/0xA758c321DF6Cd949A8E074B22362a4366DB1b725
Impacts:
Contract fails to deliver promised returns, but doesn't lose value
Description
Brief/Intro
StalenessCircuitBreakerNode checks if the last update time of the parent node is less than the threshold but the publicTime
could be greater than current block.timestamp
.
PythNode::Process()
calls pyth.getEmaPriceUnsafe()
and pyth.getPriceUnsafe()
for fetching price.
Issue is In StalenessCircuitBreakerNode
stalenessTolerance
is conceived as the maximum number of seconds that the price can be in the past(compared to block.timestamp) but in reality the price could also be in future
Vulnerability Details
This fact is corroborated by the logic inside Pyth SDK that performs an abs delta between the price.publishTime
in [getPriceNoOlderThan](https://github.com/pyth-network/pyth-crosschain/blob/main/target_chains/ethereum/sdk/solidity/AbstractPyth.sol#L48-L58)
. In the near SDK the check is even more explicit
Let's analyse getPriceUnsafe()
https://github.com/pyth-network/pyth-crosschain/blob/main/target_chains/near/receiver/src/lib.rs#L491
we can see that absolute difference is taken betweenprice.publishtime
and age which shows that price.publishtime
could be greater than block.timestamp
but during staleness check stalenessTolerance
is used for only previous prices
Impact Details
price.publishtime
could be greater than block.timestamp. In such case fetching price will revert due to underflow since block.timestamp < price.publishtime
References
https://github.com/pyth-network/pyth-crosschain/blob/main/target_chains/near/receiver/src/lib.rs#L509
Proof of concept
Proof of Concept
call getPriceNoOlderThan()
on any Pyth
priceFeed and check price.publishtime
For more clarifications
Check 5.4.13 of https://github.com/euler-xyz/euler-price-oracle/blob/master/audits/Euler_Price_Oracle_Spearbit_Report_DRAFT.pdf
Last updated