Using a single block number state variable for updates of both price parameters and profit max unlock time creates synchronization issues where one verifier can unfortunately block the other, leading to stale data and incorrect pricing.
First, note the snippet below from ScrvusdOracleV2::update_price
And also from ScrvusdOracleV2::update_profit_max_unlock_time
As seen, both verifiers (ScrvusdVerifierV1 for price parameters and ScrvusdVerifierV2 for profit max unlock time) update the same last_block_number
state variable in the oracle. This shared state creates a critical synchronization issue, as any update from either verifier increases the minimum block number required for future updates from either verifier, this would then mean that if we attempt to update the oracle for valid data on the price it would fail on the oracle level as Outdated
, where as the price might have not been updated for a long time causing longer ingestion of stale data.
Textual POC:
Price is updated at block 1000
Profit max unlock time is updated at block 1150
30 minutes later.
Any valid proof of price update from block 1000
up to 1149
will be rejected by the oracle and claimed as Outdated
, where as in real sense this price update is fresher than the current one stored and should be accepted.
As hinted under Vulnerability Details, this shared state variable breaks the valid flow for price updates, as it creates a scenario where:
If the price parameter verifier (ScrvusdVerifierV1
) consistently runs with newer blocks than the profit max unlock time verifier (ScrvusdVerifierV2
), the latter will frequently encounter reverts with the "Outdated" error, having a state on the destination chain, where our profit evolution logic is wrong and stale, which affects pricing.
This blocking effect means one of the two crucial state variables (either price parameters or profit max unlock time) will become stale and outdated.
Since the profit max unlock time is essential for accurate price calculations, having stale unlock time data while price parameters are updated (or vice versa) leads to incorrect pricing.
As updates fail more frequently, the protocol becomes vulnerable to price manipulation and arbitrage opportunities across chains due to the divergence.
This effectively means provers even lose funds as any attempt at updating price requires tx fees.
Manual review
Separate the block number tracking for each type of update:
This separation allows each verifier to operate independently on its own update schedule, preventing one verifier from blocking the other and ensuring both price parameters and profit max unlock time can be kept up-to-date.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.