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

Incorrect `MAX_V2_DURATION` and `max_v2_duration` Calculation Leads to Price Calculation Errors

Title

Incorrect MAX_V2_DURATION and max_v2_duration Calculation Leads to Price Calculation Errors

Summary

The constants MAX_V2_DURATION and max_v2_duration in the ScrvusdOracle contract are incorrectly calculated, resulting in deviations from the intended durations. This miscalculation causes incorrect price and parameter updates when the price update occurs within the error range of max_v2_duration.

Vulnerability Details

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

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

Below are the respective definitions of MAX_V2_DURATION constant and max_v2_duration variable:

>> MAX_V2_DURATION: constant(uint256) = 4 * 12 * 4 # 4 years
def __init__(_initial_price: uint256):
...
# 2 * 10 ** 12 is equivalent to
# 1) 0.02 bps per second or 0.24 bps per block on Ethereum
# 2) linearly approximated to max 63% APY
self.max_price_increment = 2 * 10**12
>> self.max_v2_duration = 4 * 6 # half a year
access_control.__init__()
access_control._set_role_admin(PRICE_PARAMETERS_VERIFIER, access_control.DEFAULT_ADMIN_ROLE)
access_control._set_role_admin(UNLOCK_TIME_VERIFIER, access_control.DEFAULT_ADMIN_ROLE)

They are intended to represent specific durations in weeks (4 years and half a year, respectively). However, the calculations incorrectly assume that every month consists of exactly 4 weeks, resulting in the following errors:

  • MAX_V2_DURATION is 16 weeks short of the intended 4-year duration.

  • The default value of max_v2_duration is 2 weeks short of half a year.

Further explaination:

  • Incorrect MAX_V2_DURATION: A year has 52 weeks, so 4 years should be 52 * 4 = 208 weeks. However, the calculation 4 * 12 * 4 incorrectly assumes 48 weeks instead of 52, leading to a 16-week shortfall.

  • Incorrect max_v2_duration: Half a year should be 26 weeks, but the current calculation results in 24 weeks, causing a 2-week discrepancy.

Impact

This occurs discrepencies in several cases including:

  • Incorrect price calculations when price updates occur within the error range of max_v2_duration

  • Inaccurate parameter values, which propagate to functions relying on _obtain_price_params function

Recommendations

Make the following updates to let them represent correct durations:

For MAX_V2_DURATION:

-- MAX_V2_DURATION: constant(uint256) = 4 * 12 * 4 # 4 years
++ MAX_V2_DURATION: constant(uint256) = 52 * 4 # 4 years

For max_v2_duration:

-- self.max_v2_duration = 4 * 6 # half a year
++ self.max_v2_duration = 26 # half a year
Updates

Lead Judging Commences

0xnevi Lead Judge 2 months ago
Submission Judgement Published
Invalidated
Reason: Design choice
Assigned finding tags:

[invalid] finding-MAX_V2_DURATION

This is simply an approximation. I don't believe there is any incorrect logic here, given as long as this duration of growth is consistently applied, there will arguably be no incorrect oracle prices here. Additionally, I highly doubt there will be a instance where 48 weeks has passed since the last update.

Support

FAQs

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