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

Same-block resubmission vulnerability

Summary

The ScrvusdOracleV2 contract allows the same block number to be used in multiple calls to update_profit_max_unlock_time and update_price. This creates a replay attack vector, where an attacker can repeatedly submit old proofs to manipulate the oracle's state, even if newer, more accurate data is available.

Vulnerability Details

In the ScrvusdOracleV2 contract, the update_profit_max_unlock_time and update_price functions include the following check:

# Allowing same block updates for fixing bad blockhash provided (if possible)
assert self.last_block_number <= _block_number, "Outdated"

This check is intended to allow for corrections in case of bad blockhash data. However, it also allows an attacker to repeatedly submit the same block number.

The access_control._check_role mitigates the risk of unauthorized actors, but it does not prevent a malicious or compromised UNLOCK_TIME_VERIFIER from exploiting this behavior.

A malicious or compromised verifier could:

  • Find a block with a favorable profit_max_unlock_time value (e.g., unusually low value that increases price)

  • Then if the value changes to something less favorable, submit multiple updates with the same block number to manipulate the value

  • Manipulate price calculations and exploit price discrepancies in pools

In summary, an attacker can repeatedly call update_profit_max_unlock_time with the same block_number to manipulate the profit_max_unlock_time value.

Impact

This vulnerability allows an attacker to:

  • Manipulate price calculations: By controlling the profit_max_unlock_time, the attacker can influence the oracle's price calculations, potentially creating arbitrage opportunities or causing losses for liquidity providers.

  • Regulatory capture: An attacker could effectively "lock" the oracle to favorable historical values, preventing legitimate updates and profiting from the artificial price.

  • Cause financial harm: Exploiting price discrepancies in pools that rely on this oracle for pricing data can lead to significant financial losses.

Tools Used

Manual inspection, copilot, uv and moccasin.

Recommended Mitigation

Require strictly increasing block numbers. However, since the system has legitimate uses for same-block updates (fixing bad blockhash issues) consider fixes that balance security with functionality, such as an override flag with more security control which for example can allow same-block update if required and be cleared until it is explicitly reset again.

Updates

Lead Judging Commences

0xnevi Lead Judge
6 months ago
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.