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

Replay/Outdated Proofs Vulnerability in Scrvusd Verifier Contracts

Details:
The verifier functions in both ScrvusdVerifierV1 and ScrvusdVerifierV2 do not include any mechanism to ensure that the provided state proofs are fresh or unique. They solely rely on external block hash and state root oracles to validate the proof data without checking if the proof corresponds to an update more recent than the last processed state. As a result, an attacker could replay an old but valid proof, causing the oracle to update with stale data.

Root Cause:
The root cause is the absence of replay protection. The contracts do not store any state (such as the last processed block number or timestamp) to verify that incoming proofs are newer than the current state, nor do they employ nonces or unique identifiers to invalidate reused proofs.

Impact:
If an attacker replays an outdated proof, the oracle may be updated with stale parameters. This could lead to mispricing or incorrect debt and profit values if the system depends on monotonic data updates. In turn, this might enable arbitrage opportunities or disrupt the proper operation of dependent systems, potentially causing financial losses or instability in the ecosystem.

Recommendation:

  • Implement Freshness Checks: Introduce state variables to track the most recent block number or timestamp for which the proof has been processed. Reject any proof whose corresponding block or timestamp is not strictly greater than the last recorded value.

  • Use Nonces or Unique Identifiers: Incorporate unique identifiers or nonces within the proofs to ensure that each proof can only be used once.

  • Oracle-Level Validation: Consider adding additional validation within the oracle contracts themselves to prevent updates with stale data, further mitigating replay risks.

Proof of Concept:

  1. Setup: An attacker obtains a valid state proof and corresponding block header for a specific block (e.g., block N) during a legitimate update.

  2. Replay: After the system has processed a newer update (block N+X), the attacker replays the previously captured state proof associated with block N by submitting it to the verifier function.

  3. Outcome: Since the verifier does not check whether the block number or timestamp is outdated, it accepts the replayed proof and calls the update function with stale data, potentially overwriting current parameters in the oracle with old values.

Updates

Lead Judging Commences

0xnevi Lead Judge 5 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement
Assigned finding tags:

[invalid] finding-replay-proof-lack-nonce

- All proof generated within `_proof_rlp` is generated via the off-chain prover, so there is no concrete proof that this proofs are non-unique. - All state roots and proofs must be verified by the OOS `StateProofVerifier` inherited as `Verifier`, so there is no proof that manipulating proofs can successfully pass a price update

Support

FAQs

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