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

Underflow Risk in `_unlocked_shares` Calculation

Description

The _unlocked_shares function calculates unlocked_shares as profit_unlocking_rate * (ts - last_profit_update) // MAX_BPS_EXTENDED. If ts < last_profit_update, this calculation will result in an arithmetic underflow, which can lead to critical miscalculations in the protocol.

Affected Code

https://github.com/CodeHawks-Contests/2025-03-curve/blob/198820f0c30d5080f75073243677ff716429dbfd/contracts/scrvusd/oracles/ScrvusdOracleV2.vy#L193-L219

@view
def _unlocked_shares(
full_profit_unlock_date: uint256,
profit_unlocking_rate: uint256,
last_profit_update: uint256,
balance_of_self: uint256,
ts: uint256,
) -> uint256:
unlocked_shares: uint256 = 0
if full_profit_unlock_date > ts:
unlocked_shares = profit_unlocking_rate * (ts - last_profit_update) // MAX_BPS_EXTENDED

Vulnerability Details

The calculation of unlocked_shares assumes that ts (the current timestamp) is always greater than or equal to last_profit_update. However, if ts < last_profit_update, the subtraction (ts - last_profit_update) will underflow, resulting in an incorrect and extremely large value for unlocked_shares. This could lead to incorrect price calculations in the oracle, as the unlocked shares are used to determine the total supply of assets. An attacker could exploit this by manipulating the last_profit_update timestamp, causing the oracle to return invalid price data. This would allow the attacker to manipulate the oracle's price calculations, potentially leading to financial losses for users relying on the oracle's data.

Tools Used

Manual Review

Recommended Mitigation Steps

Add a check to ensure ts >= last_profit_update before performing the calculation:

assert ts >= last_profit_update, "Invalid timestamp"
Updates

Lead Judging Commences

0xnevi Lead Judge 3 months ago
Submission Judgement Published
Invalidated
Reason: Out of scope
Assigned finding tags:

[invalid] finding-timestamp-underflow

This issues and duplicates are very similar to reasonings highlighted in issue #11. The timestamp variables are extracted and verified via the OOS `StateProofVerifier` contract inherited as `Verifier`. There is simply no concrete proof that the verifier allowed such an underflow to occur, representing stale price value updates.

Support

FAQs

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