DeFiLayer 1Layer 2
14,723 OP
View results
Submission Details
Severity: low
Valid

Missing Initialization of `last_block_number` Leads to Allowing Stale Block Number Updates in `update_price`

Summary

The last_block_number state variable in the scrvUSD oracle contract is not initialized in the constructor (__init__). This omission results in its default value being 0. The update_price function compares the provided _block_number argument against last_block_number to prevent outdated price updates. However, since last_block_number starts at zero, the first call to update_price will accept any _block_number greater than or equal to zero. This creates an opportunity for stale or outdated _block_number values to be used during the first update, which may lead to inconsistent or inaccurate price data.

Vulnerability Details

The last_block_number variable is not explicitly initialized in the constructor (__init__). By default, it assumes a value of zero.
During the first call to update_price, last_block_number will always be 0. This assertion:

assert self.last_block_number <= _block_number, "Outdated"

will pass for any _block_number ≥ 0, including stale or outdated values. This violates the intended logic of strictly enforcing monotonically increasing _block_number values, potentially allowing an outdated _parameters set to be accepted on the first call.

Impact

The update_price function could accept outdated _block_number values on its first invocation, causing the contract to log or store stale or incorrect price data. If incorrect price_params are updated with an old block number, subsequent calculations relying on accurate and fresh parameters could lead to inaccurate oracle prices. This behavior undermines the oracle’s integrity and potentially exposes integrations (StableSwap pools and other systems depending on scrvUSD) to stale pricing, increasing the risk of manipulation or mispricing in dependent protocols.

Tools Used

Manual Review

Recommendation

Explicitly initialize last_block_number in the constructor (__init__) with the current block number at deployment to ensure that only updates with valid, fresh block numbers are allowed:

+ self.last_block_number = block.number
Updates

Lead Judging Commences

0xnevi Lead Judge 2 months ago
Submission Judgement Published
Validated
Assigned finding tags:

finding-block-number-not-initialized

I believe low to be appropriate, although could hear arguments for informational. The next `_block_number` for each price/max unlock time update will always be greater than the default zero, so the assertion of `assert self.last_block_number <= _block_number, "Outdated"` will pass without issue, but for consistency could be updated during deployment. Arguably at deployment, an update that has been verified via the verifier has not occur yet, so there would likely be no issues here given after the first correct update it will work as intended. The first update for price/profit max unlock time will also unlikely be outdated based on block number, which can be presumed to be true given this are extracted and verified within the OOS `StateProofVerifier`.

Support

FAQs

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