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

Incorrect Loop Bound in Price Parameters Adjustment

scrvUSD Oracle

Issue Description

In the _obtain_price_params function, when the current timestamp (parameters_ts) is later than the last profit update plus the profit unlock period, the contract calculates number_of_periods as:

number_of_periods: uint256 = min(
(parameters_ts - params.last_profit_update) // period,
self.max_v2_duration,
)

However, the subsequent loop is defined as:

for _: uint256 in range(number_of_periods, bound=MAX_V2_DURATION):
new_balance_of_self: uint256 = (
params.balance_of_self
* (params.total_supply - params.balance_of_self) // params.total_supply
)
params.total_supply -= (
params.balance_of_self * params.balance_of_self // params.total_supply
)
params.balance_of_self = new_balance_of_self

In Vyper, range(start, bound=stop) iterates from start up to but not including stop. In this case, the loop runs for MAX_V2_DURATION - number_of_periods iterations, which is not necessarily equal to number_of_periods as likely intended.

Impact & Attack Path

  • Incorrect Parameter Adjustment:
    Over-iterating in this loop causes the price parameters (especially total_supply and balance_of_self) to be adjusted more than expected. The net effect is a further reduction (or distortion) of the effective supply or balance that feeds into the price calculation.

  • Potential Exploit:
    An attacker might force a scenario in which the update is delayed so that parameters_ts is significantly greater than params.last_profit_update. Then, because the loop runs too many iterations, the oracle could report an artificially manipulated (e.g., undervalued) price. This mispricing could be exploited in a stableswap pool to gain arbitrage profit.

Recommendation

  • Fix Loop Bounds:
    Modify the loop to iterate exactly number_of_periods times. For example, use:

    for _: uint256 in range(number_of_periods):
    ...

    This ensures that the adjustment is applied only the intended number of periods.

Updates

Lead Judging Commences

0xnevi Lead Judge 5 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement
Assigned finding tags:

[invalid] finding-incorrect-loop-bound

Invalid, `bound` here has a different meaning from Python's `range(a, b)`. It is a bound of maximum iterations, meaning the loop will only go to the bounded `MAX_V2_DURATION` when `number_of_periods >= MAX_V2_DURATION`

Support

FAQs

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