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

Incorrect Price Smoothing in ScrvusdOracleV2.vy::_smoothed_price

Summary

https://github.com/CodeHawks-Contests/2025-03-curve/blob/198820f0c30d5080f75073243677ff716429dbfd/contracts/scrvusd/oracles/ScrvusdOracleV2.vy#L155C1-L164C21

The _smoothed_price function in the contract is designed to linearly approximate price changes to avoid sharp fluctuations. However, it does not properly handle edge cases where the actual price change exceeds the max_price_increment threshold. Specifically, the function uses a linear approximation to limit the price change, but if the actual price change is larger than the allowed max_price_increment, the smoothed price will be incorrect. This can lead to discrepancies between the actual price and the smoothed price, especially during periods of high volatility.

Vulnerability Details

Example Scenario: Bob and Alice

Initial Setup:

  • The max_price_increment is set to 2 * 10**12 (0.02 bps per second).

  • The current smoothed price of scrvUSD is 1.0 (normalized to 10**18).

  • Due to a sudden market event, the actual price of scrvUSD spikes to 1.5 (a 50% increase).

Price Update:

  • The _smoothed_price function is called to update the price.

  • The function calculates the maximum allowed price change as:

max_change = (max_price_increment * (block.timestamp - last_update) * last_price) // 10**18

If the time elapsed since the last update is 10 seconds, the max_change would be:

max_change = (2 * 10**12 * 10 * 10**18) // 10**18 = 2 * 10**13
  • This means the price can only increase by 0.02 * 10 = 0.2 bps (or 0.002 in normalized terms).

Incorrect Smoothing:

  • The actual price change is 0.5 (from 1.0 to 1.5), which far exceeds the max_change of 0.002.

  • The _smoothed_price function clamps the price change to max_change, so the new smoothed price becomes:

last_price + max_change = 1.0 + 0.002 = 1.002
  • This is significantly lower than the actual price of 1.5.

Exploitation by Bob:

  • Bob notices the discrepancy between the actual price (1.5) and the smoothed price (1.002).

  • He uses the smoothed price to buy scrvUSD at the artificially low price of 1.002.

  • He then sells the scrvUSD on an external market at the actual price of 1.5, making a profit of (1.5 - 1.002) * amount

  • This arbitrage opportunity allows Bob to extract value from the system at the expense of liquidity providers like Alice.

Losses for Alice:

  • Alice is a liquidity provider who relies on the smoothed price to determine the value of her holdings.

  • Because the smoothed price is incorrect, Alice's holdings are undervalued, and she suffers losses when Bob exploits the discrepancy.

Impact

If the actual price change exceeds the max_price_increment, the smoothed price will be incorrect, leading to potential arbitrage opportunities or losses for liquidity providers.

Tools Used

Manual Review

Recommendations

Add a check to ensure the max_price_increment is sufficient for the actual price change. Consider using exponential smoothing or a more robust mechanism to handle large price changes.

Updates

Lead Judging Commences

0xnevi Lead Judge
2 months ago
0xnevi Lead Judge 2 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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