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

Incorrect Timestamp Validation in update_price Leading to Future Price Extrapolation

Summary

ScrvusdOracleV2::update_price function lacks validation to ensure the provided timestamp (_ts) is not in the future relative to block.timestamp. This allows extrapolation of prices based on unearned future rewards, compromising the oracle’s precision

Vulnerability Details

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

The update_price function accepts _ts (the timestamp at which parameters are true) without checking if _ts <= block.timestamp. This _ts is assigned to self.price_params_ts and used in _raw_price via _obtain_price_params, which extrapolates rewards based on the time difference (parameters_ts - params.last_profit_update). A future _ts can inflate the price by assuming additional reward periods have passed.

This will occur when a PRICE_PARAMETERS_VERIFIER submits _ts > block.timestamp, causing _obtain_price_params to apply unearned reward periods.

Impact

In _obtain_price_params, a future _ts increases number_of_periods, adding unearned gain to total_idle, inflating the price in _raw_price.

price_v1 and price_v2 use self.price_params_ts (set to_ts), potentially overvaluing scrvUSD relative to current time.

So

  • Stableswap-ng pools (e.g., USDC/scrvUSD) may overvalue scrvUSD, leading to arbitrage losses for LPs, though smoothing (max_price_increment) limits severity

Tools Used

Recommendations

  • Add timestamp validation in update_price to ensure that _ts reflects current or past state, preventing future extrapolation

@external
def update_price(
_parameters: uint256[ALL_PARAM_CNT], _ts: uint256, _block_number: uint256
) -> uint256:
access_control._check_role(PRICE_PARAMETERS_VERIFIER, msg.sender)
assert self.last_block_number <= _block_number, "Outdated"
+ assert _ts <= block.timestamp, "Future timestamp" # Added validation
self.last_block_number = _block_number
# ...
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.