The scrvUSD oracle contract implements an access control system using the access_control
module. However, there's a significant vulnerability in the way block number updates are handled, specifically in the update_price
function. This flaw could potentially allow unauthorized actors to manipulate the price oracle data.
The vulnerable code snippet is located in the update_price
function:
The problematic part is the comment "Allowing same block updates for fixing bad blockhash provided (if possible)". This approach introduces a significant security risk because:
It allows any actor to update the block number within the same block.
There's no additional verification beyond checking if the new block number is greater than or equal to the previous one.
This creates a window of opportunity for malicious actors to exploit the system.
This PoC demonstrates three scenarios:
An authorized user successfully updates the price.
An unauthorized user attempts to update the price and receives an expected error.
An authorized user updates the price with the same block number as the previous update.
The key point to note is that the third scenario shows that the contract allows updates with the same block number. This is exactly what we want to exploit in our main attack scenario.
In a real-world scenario, an attacker would:
Monitor the blockchain for upcoming transactions that might affect the price oracle.
Once they identify a transaction that will update the price oracle, they would quickly submit their own transaction with the same block number.
When the block is mined, their transaction would execute first, allowing them to manipulate the price oracle data before the intended update occurs.
This attack leverages the fact that the contract doesn't enforce a strict requirement for increasing block numbers, allowing an attacker to interfere with the normal functioning of the price oracle.
As discussed in the previous report, to mitigate this vulnerability, you should:
Only accept updates from future blocks.
Implement a time-lock mechanism for price updates.
Require multi-sig approval for critical updates.
The impact of this vulnerability could be severe:
1- Unauthorized Updates: Any actor who can call the update_price
function could potentially manipulate the price oracle data by submitting a higher block number.
2- Reentrancy Attacks: Since the block number check is performed early in the function, it doesn't prevent reentrant calls. An attacker could exploit this to repeatedly call the function, potentially causing unintended state changes.
3- Front-Running: Malicious actors could front-run legitimate updates, potentially manipulating the price oracle before authorized updates occur.
4- System Instability: Frequent or malicious updates could cause rapid price fluctuations, destabilizing the entire system relying on this oracle.
reviewed it manualy
1- Strict Block Number Checks: Instead of allowing same-block updates, only accept updates from future blocks:
2- Time-Lock Mechanism: Introduce a delay between the time a price update is proposed and when it takes effect. This gives time for other nodes to validate the update:
- See [here]([https://github.com/CodeHawks-Contests/2025-03-curve?tab=readme-ov-file#blockhash-oracle)](https://github.com/CodeHawks-Contests/2025-03-curve?tab=readme-ov-file#blockhash-oracle) on how it is used to verify storage variable - All state roots and proofs must be verified by the OOS `StateProofVerifier` inherited as `Verifier` (where the price values and params are extracted), so there is no proof that manipulating timestamp/inputs can affect a price update - It is assumed that the OOS prover will provide accurate data and the OOS verifier will verify the prices/max unlock time to be within an appropriate bound/values - There is a account existance check in L96 of `ScrvusdVerifierV1.sol`, in which the params for price updates are extracted from
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.