ScrvusdOracle.vy creates a constant MAX_V2_DURATION and a variable max_v2_duration that are set to the wrong values. While the set_max_v2_duration() function can change the value of max_v2_duration, it cannot set it to within 16 units of the intended MAX_V2_DURATION. This error happens in the following lines of code:
4 years is 52 * 4 weeks, and the assumption that every month has 4 weeks causes MAX_V2_DURATION to be 16 weeks short of the intended value. Likewise, the default value of max_v2_duration is 2 weeks short of half a year. max_v2_duration is used to cap gains in total_idle funds in _obtain_price_params(). It is also used to cap the number of iterations of the following loop in _obtain_price_params(), interfering with balance_of_self calculations:
_obtain_price_params() therefore returns incorrect values whenever the number_of_periods calculated by it is within the error range of max_v2_duration. This function is called by _raw_price and is therefore called every time any price needs to be calculated. Functions relying on values modified incorrectly by _obtain_price_params() will also return the wrong values. For example, _total_assets() relies on total_idle funds which is modified by _obtain_price_params() depending on min(weeks_since_last_update, max_v2_duration).
Incorrectly set max_v2_duration returns incorrect prices and parameters when price update is happening within the error range of max_v2_duration. The impact is a failure of the protocol, but the likelihood is low. I am therefore submitting this as a medium vulnerability.
Add the following test to tests/scrvusd/oracle/unitary/test_v2.py and run with pytest -k test_max_v2_duration.
pytest v8.3.4, manual code review
Fix the values of MAX_V2_DURATION and max_v2_duration to reflect the intended maximum timespans.
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.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.