A critical security vulnerability has been identified in the ScrvusdVerifierV1
contract, specifically in the verifyScrvusdByBlockHash
function. The issue arises due to improper validation of block header data, which can be exploited to manipulate price updates.
The function verifyScrvusdByBlockHash
extracts a block header from the RLP-encoded input and attempts to verify its validity by checking its hash against the one stored in IBlockHashOracle
. However, if an attacker controls the _block_header_rlp
input, they could construct a valid-looking block header with an arbitrary state root. Since the function does not rigorously validate the authenticity of the state root within the provided block header, an attacker could inject falsified proof data and manipulate oracle updates.
The core issue lies in the following check:
This check ensures that the provided block header hash matches the oracle’s expected value but does not verify that the corresponding state root in the block header is also authentic. This allows an attacker to submit a modified block header with a malicious state root, bypassing proper validation.
an attacker can exploit it to inject arbitrary state proofs, potentially manipulating the oracle's reported prices. The impact includes:
False price updates, affecting financial stability.
Potentially triggering incorrect liquidations or arbitrage opportunities.
Severe disruption of protocol trust and stability.
Manual review of ScrvusdVerifierV1.sol
Hardhat/Foundry for local contract testing
RLP decoding libraries for analysis
Chain state proof verification tools
To mitigate this vulnerability, the following actions should be taken:
Implement strict validation of the state root to ensure that it is derived from an authentic and verified source.
Use Merkle proof verification to authenticate state root integrity.
Introduce additional cross-references with trusted sources to prevent spoofed data from influencing the contract.
Consider using chain-native verification methods instead of relying solely on external oracles.
- Anything related to the output by the `BLOCK_HASH_ORACLE` is OOS per \[docs here]\(<https://github.com/CodeHawks-Contests/2025-03-curve?tab=readme-ov-file#blockhash-oracle>). - The PoC utilizes a mock `BLOCK_HASH_ORACLE`which is not representative of the one used by the protocol - Even when block hash returned is incorrect, the assumption is already explicitly made known in the docs, and the contract allows a subsequent update within the same block to update and correct prices - All state roots and proofs must be verified by the OOS `StateProofVerifier` inherited as `Verifier`, so there is no proof that manipulating block timestamp/block number/inputs can affect a price update - There seems to be a lot of confusion on the block hash check. The block hash check is a unique identifier of a block and has nothing to do with the state root. All value verifications is performed by the OOS Verifier contract as mentioned above
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.