Severity: HIGH
Category: Oracle Security / Data Validation
Impact: Possible manipulation of scrvUSD price oracle
Likelihood: Medium
In ScrvusdVerifierV1.sol, the verifyScrvusdByStateRoot
function relies on the block number parameter to fetch the state root, but there's no verification that the provided _block_number
corresponds to the block where the proof data was actually generated. This could allow an attacker to mix state proofs from one block with a different block number.
Attacker monitors scrvUSD contract state changes on Ethereum
When favorable parameters exist in block N, attacker:
Captures the state proof from block N
Calls verifyScrvusdByStateRoot
with a different block number M
If the state root for block M happens to validate against the proof from block N
The oracle receives incorrect historical data
Price Manipulation: Could allow injection of incorrect historical prices
Stale Data: System could operate on outdated state information
Oracle Reliability: Compromises the trustworthiness of the cross-chain price feed
Add verification that the proof data matches the claimed block number:
Include block number in the proof data and validate it matches
Add a timestamp freshness check
Implement proof expiration mechanism
This is a HIGH severity issue because:
Impact: Could compromise the integrity of the oracle's price feed
Real-world Exploitability: Practical in production environments
Economic Risk: Could affect DeFi protocols relying on this oracle
Recovery Difficulty: Challenging to detect and correct historical data
- 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.