Details:
In the function _extractParametersFromProof
of the ScrvusdVerifierV1
contract, the code extracts multiple parameters from storage proofs. The implementation does not enforce the existence of each slot; if a slot does not exist, its value defaults to zero. Although the comment indicates that “slots might not exist,” this silent fallback may be problematic if the business logic (such as price updates via update_price
) requires valid non-zero data. An attacker or misconfiguration in the state proof could result in critical parameters being set to zero, which might then cause incorrect or manipulated behavior in subsequent oracle updates.
Root Cause:
Lack of validation on slot existence during the state proof extraction process. The contract assumes that a missing slot yielding a default value of zero is acceptable, without verifying whether a zero value is semantically valid for the intended operation.
Impact:
Incorrect Data Processing: Critical parameters may be incorrectly set to zero, potentially leading to wrong computations or price updates.
Exploitation Risk: An attacker might intentionally craft or manipulate proofs to omit certain slots, resulting in a controlled default to zero and thereby potentially manipulating the outcome of the oracle’s price calculations.
Operational Failure: Downstream contracts or functions that depend on non-zero values for correct operation might behave unexpectedly or fail entirely.
Recommendation:
Validation: Implement explicit checks to verify that each required slot exists and contains a non-zero (or otherwise acceptable) value.
Error Handling: Instead of silently accepting zero values, revert the transaction if any critical slot is missing or invalid, unless a default of zero is an intentional and safe fallback.
Documentation: Clearly document the expected behavior for missing slots to ensure that any defaulting to zero is by design and not a source of potential errors.
Proof of Concept:
Crafted Proof Input: An attacker or a misconfigured system provides a state proof where one or more expected storage slots are omitted.
Slot Extraction: The _extractParametersFromProof
function processes the input and, due to the missing slots, assigns zero to the corresponding parameters (i.e., params[i - 1] = slot.value;
becomes zero).
Oracle Update: These zero values are then passed to the update_price
function, which may compute an incorrect price update based on the invalid parameters.
Result: The system processes the transaction using these default values, potentially leading to unintended behavior or allowing for price manipulation.
- 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.