DeFiLayer 1Layer 2
14,723 OP
View results
Submission Details
Severity: high
Invalid

Malicious State Proof Injection due to lack of validation of the state proof’s authenticity and integrity.

Summary

The ScrvusdVerifierV1 contract relies on state proofs to verify and update the price of scrvUSD. If the state proof verification process is not robust, an attacker could submit a malicious state proof to manipulate the scrvUSD price or the profit_max_unlock_time. Specifically:

  • Malicious State Proof: An attacker could craft a fake state proof that contains incorrect data (e.g., inflated or deflated prices, incorrect profit_max_unlock_time).

  • Lack of Robust Verification: If the contract does not thoroughly validate the state proof, the malicious data could be accepted, leading to incorrect updates.

Vulnerability Details

The root cause of the bug lies in the lack of validation of the state proof’s authenticity and integrity. Specifically:

  1. No Verification of Proof Source:

    • The contract does not verify whether the state proof (proofRlp) comes from a trusted or valid source.

    • An attacker could craft a malicious state proof that contains fake data (e.g., manipulated total_debt, total_idle, or profit_max_unlock_time).

  2. No Validation of Extracted Data:

    • The contract extracts slot values from the state proof but does not perform sanity checks on the extracted data.

    • For example, it does not ensure that the extracted values (e.g., total_debt, total_idle) fall within reasonable ranges or are consistent with historical data.

  3. Reliance on Untrusted Input:

    • The proofRlp parameter is provided by the caller, and the contract blindly trusts it without verifying its authenticity.

    • This makes the contract vulnerable to malicious inputs.

Proof of Concept

Detailed Case Example: Bob and Alice

Scenario Setup

  • Bob is a malicious actor who wants to manipulate the scrvUSD price for personal gain.

  • Alice is a liquidity provider who relies on the oracle for accurate price data.

  • The ScrvusdVerifierV1 contract is used to verify and update the scrvUSD price based on state proofs.

Bob Crafts a Malicious State Proof

  • Bob creates a fake state proof that contains manipulated data:

    • He sets total_debt to an artificially high value (e.g., 1e30).

    • He sets total_idle to an artificially low value (e.g., 0).

    • He sets profit_max_unlock_time to an incorrect value (e.g., 0 to disable profit unlocking).

  • Bob encodes this malicious data into an RLP-encoded state proof (proofRlp).

Step 2: Bob Submits the Malicious State Proof

  • Bob calls the verifyScrvusdByBlockHash or verifyScrvusdByStateRoot function, passing the malicious state proof as an argument.

  • The contract does not verify the authenticity or integrity of the state proof, so it accepts the malicious data.

Step 3: Extraction of Malicious Data

  • The _extractParametersFromProof function extracts the manipulated parameters from the malicious state proof:

    • total_debt is set to 1e30.

    • total_idle is set to 0.

    • profit_max_unlock_time is set to 0.

  • The function does not perform any sanity checks on the extracted data, so the malicious values are accepted.

Step 4: Price Update with Malicious Data

  • The _updatePrice function updates the scrvUSD price using the manipulated data:

    • The scrvUSD price is artificially inflated due to the manipulated total_debt and total_idle values.

    • The profit_max_unlock_time is set to 0, disrupting the profit unlocking mechanism.

Step 5: Exploitation by Bob

  • Bob uses the manipulated price to his advantage:

    • He sells his scrvUSD holdings at the inflated price, making a profit.

    • He exploits the disrupted profit unlocking mechanism to withdraw funds prematurely or delay profit distribution.

  • Bob’s actions are at the expense of other users, including Alice.

Step 6: Losses for Alice

  • Alice, as a liquidity provider, relies on the oracle for accurate price data.

  • Due to the manipulated price, Alice’s holdings are incorrectly valued:

    • If the price is inflated, Alice may overvalue her holdings and make poor financial decisions.

    • If the price is deflated, Alice may undervalue her holdings and suffer losses when trading or withdrawing funds.

  • The disrupted profit unlocking mechanism further exacerbates Alice’s losses, as she may not receive her expected profits on time.

Impact

  • Manipulate the price of scrvUSD to drain funds from the protocol.

  • Set an incorrect profit_max_unlock_time, disrupting the profit unlocking mechanism.

Tools Used

Manual Review of the code

Recommendations

  • Ensure that the state proof comes from a trusted source (e.g., a trusted oracle or consensus mechanism).

  • Cross-reference the state proof with multiple block headers or state roots to verify its authenticity

  • Implement sanity checks on the extracted parameters to ensure they fall within reasonable ranges. For example, check that total_debt and total_idle are not excessively high or low.

Updates

Lead Judging Commences

0xnevi Lead Judge 5 months ago
Submission Judgement Published
Invalidated
Reason: Out of scope
Assigned finding tags:

[invalid] finding-missing-proof-content-validation

- 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

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.