Details:
The extraction functions (_extractParametersFromProof and _extractPeriodFromProof) enforce a strict number of RLP items and assume a specific ordering. For example, the parameters extraction requires proofs.length == PROOF_CNT
and the period extraction demands exactly 2 proofs. The contract only validates the count and basic structure, without verifying the semantic binding between each proof item and its corresponding storage slot. An attacker who can supply proofs—even if they have the correct count—could potentially reorder or manipulate the items to mislead the contract during the state proof extraction.
Root Cause:
The core issue is the reliance on a fixed array order and a simple count check for the proof items without further validating that each item corresponds to the expected storage slot. This design assumes that the proofs are always generated correctly, which might not hold true if an adversary can influence the proof data.
Impact:
If an attacker manages to supply a reordered or manipulated proof that still satisfies the length requirement, the contract could misinterpret the extracted parameters. This misinterpretation could lead to incorrect state values being passed to the oracle update functions, potentially causing erroneous price updates or profit unlock times, which may have broader financial repercussions.
Recommendation:
Enhanced Validation: In addition to checking the number of proofs, validate that each proof item contains the expected storage key or identifier.
Mapping Proof Items: Consider using an explicit mapping between proof items and their corresponding storage slots rather than relying solely on fixed ordering.
Redundancy Checks: Incorporate additional checks to ensure that the extracted values match expected ranges or patterns, reducing the risk of misinterpretation.
Trusted Proof Source: If possible, restrict proof submission to trusted sources to mitigate the risk of attacker-supplied malformed proofs.
Proof of Concept:
An attacker crafts an RLP-encoded proof array with the required number of items but deliberately reorders the slot proofs such that the parameter intended for one slot is extracted into a different parameter index.
The manipulated proof passes the proofs.length
check and basic structure validations, leading the extraction functions to misinterpret the slot values.
The extracted, incorrect parameters are then used in the oracle update function, potentially causing a malicious price update or misconfigured profit unlock time.
- 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.