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

Lack of Front-Running Protection in update_price()

Summary

Front-running is an attack where a malicious user observes a pending transaction in the mempool and submits their own transaction with a higher gas fee to execute before the original transaction.

How update_price() Is Vulnerable

In contract, the function update_price() updates the price based on _parameters, but there is no mechanism to prevent manipulation before a critical transaction occurs.

def update_price(_parameters: PriceParameters):

assert access_control.has_role(PRICE_PARAMETERS_VERIFIER, msg.sender)

self.current_price_parameters = _parameters

Attack Scenario
  1. A user submits a transaction that relies on a stable price (e.g., staking, lending, or swapping).

  2. An attacker sees the transaction in the mempool and front-runs it by calling update_price() with manipulated parameters before the original transaction is executed.

  3. The user's transaction now executes with incorrect price data, leading to unfair asset swaps, incorrect rewards distribution, or losses.

Example of a Front-Running Attack

  • Suppose the real price of an asset is 100 tokens.

  • A user submits a transaction to swap 10 tokens based on the expected price of 100.

  • An attacker front-runs the transaction by updating the price to 80 before the swap occurs.

  • The user’s swap now happens at a lower price, causing them to receive fewer tokens than expected.

  • The attacker back-runs another transaction to restore the price to 100 and profits from the manipulated trade.

Vulnerability Details

https://github.com/CodeHawks-Contests/2025-03-curve/blob/main/contracts/scrvusd/oracles/ScrvusdOracleV2.vy#L295

Impact

Tools Used

Recommendations

1. Use a Commit-Reveal Scheme

Instead of allowing immediate updates, implement a two-step commit-reveal process:

  1. Commit Phase: The verifier submits a hashed price (keccak256(new_price, secret_salt)).

  2. Reveal Phase: After a delay, they reveal the actual price and the contract verifies it.

This prevents attackers from knowing the exact price change before it's revealed.

2. Use a Timelock Mechanism

Introduce a short delay (e.g., 1 block or 10 seconds) before the price update takes effect. This gives users time to react and adjust their transactions.

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.