The ScrvusdOracleV2.vy
contract contains a potentially problematic loop in the _obtain_price_params
function. While the loop does include a bound parameter, it can still iterate up to MAX_V2_DURATION
times (defined as 4 * 12 * 4 = 192
), which could lead to excessive gas consumption or even transaction failures due to hitting block gas limits in certain scenarios.
Severity: Medium
Files Affected:
contracts/scrvusd/oracles/ScrvusdOracleV2.vy
Functions Affected:
_obtain_price_params()
The problematic loop is found in the _obtain_price_params
function:
Several concerning aspects of this code:
The loop iteration count is determined by number_of_periods
, which is bounded by self.max_v2_duration
. This value is configurable but has a default of 4 * 6 = 24
and can go up to MAX_V2_DURATION = 4 * 12 * 4 = 192
.
The constant MAX_V2_DURATION
(192) is used as the loop bound parameter, meaning the function is protected against infinite loops, but could still iterate many times.
Each iteration performs multiple divisions and multiplications, which are relatively gas-intensive operations.
This function is called by _raw_price()
, which is used in multiple public functions including price queries and price updates.
The unbounded loop vulnerability could lead to several issues:
Gas Limit Exceedance: If number_of_periods
is large, the loop could consume enough gas to exceed block gas limits, causing transactions to fail. This is particularly concerning for price updates which are critical for protocol operation.
Denial of Service: A prolonged period without updates could lead to a large number_of_periods
value, potentially making price updates impossible due to gas limitations, effectively creating a denial of service condition.
Inconsistent Query Results: View functions might execute locally without gas constraints, but transactions that need to use the same calculations on-chain might fail, leading to inconsistencies between what users see and what they can execute.
Gas Cost Unpredictability: The gas cost of interacting with the contract becomes highly variable and unpredictable, depending on how much time has passed since the last update.
Financial Impact: If price updates become impossible due to gas limitations, it could lead to stale prices being used for financial decisions, potentially causing losses for users.
While the risk is mitigated somewhat by the configurable max_v2_duration
parameter and the hard cap of MAX_V2_DURATION
, it remains a significant concern for the contract's gas efficiency and reliability.
Manual code review
Implement Batch Processing:
Modify the function to process a fixed number of periods at a time and track progress:
Optimize Loop Operations:
Simplify the calculations inside the loop to reduce gas consumption:
Implement a Maximum Time Gap Limit:
Add a check to prevent processing extremely large gaps:
Use Logarithmic Approximation for Large Gaps:
For very large time gaps, switch to a more efficient mathematical approximation:
Lower Default and Maximum Values:
Reduce the default and maximum values for max_v2_duration
to ensure the loop doesn't consume too much gas:
Add Gas Monitoring:
Add monitoring for high gas consumption scenarios to alert administrators:
By implementing these recommendations, particularly the batch processing approach or mathematical approximations for large time gaps, the contract would be more resilient against gas-related issues and provide more consistent behaviour regardless of the time between updates.
Invalid, In the verifier contracts, each price param count is restricted to 7 as per `PARAM_CNT`
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.