https://github.com/CodeHawks-Contests/2025-03-curve/blob/198820f0c30d5080f75073243677ff716429dbfd/contracts/scrvusd/oracles/ScrvusdOracleV2.vy#L98
https://github.com/CodeHawks-Contests/2025-03-curve/blob/198820f0c30d5080f75073243677ff716429dbfd/contracts/scrvusd/oracles/ScrvusdOracleV2.vy#L155-L160
The ScrvusdOracleV2
contract uses a max_price_increment
value that is supposed to be "linearly approximated to max 63% APY" according to the documentation. However, the actual implementation allows for a maximum price growth of approximately 6307% APY, which is 100 times higher than documented. This discrepancy could lead to unexpected price movements, potentially affecting StableSwap pools and other integrations relying on this oracle.
In the ScrvusdOracleV2.vy
contract, there's a max_price_increment
parameter set during initialization:
This parameter is used in the _smoothed_price
function to limit how quickly the price can change:
However, when calculating the maximum yearly growth, we find that the actual APY is much higher than documented:
Running this test yields:
This indicates that the contract's smoothing mechanism allows for price changes approximately 100 times higher than documented, which could lead to unexpected behaviors in integrating protocols.
The impact of this vulnerability is significant for protocols integrating with this oracle:
Unexpected Price Movements: Systems using this oracle would experience price changes that are 100x faster than documented, potentially breaking assumptions about maximum price growth rates.
Pool Vulnerability: As stated in the README, "If not precise enough, this can lead to MEV in the liquidity pool, at a loss for the liquidity providers." With a much higher growth ceiling, the risk of MEV (Miner Extractable Value) exploitation increases.
Arbitrage Opportunities: The excessive price movement allowance could create arbitrage opportunities that would not exist if the oracle behaved as documented, leading to potential value extraction from liquidity pools.
Protocol Integration Issues: The documentation states that "the oracle is controlled by a DAO and its parameters can be changed by a vote." Systems may be designed assuming a 63% APY limit, but the actual implementation allows for much faster price changes.
The README also mentions: "Taking the minimum pool fee as 1bps means that the oracle should not jump more than 1 bps per block." The current implementation could significantly exceed this guideline under certain conditions.
Manual code review
Custom test script
To align the code with the documented behavior, the max_price_increment
value should be reduced by a factor of 100:
This adjustment would ensure the maximum APY is approximately 63% as documented.
Additionally, it's recommended to add explicit tests to verify this behavior in the test suite to prevent similar issues in the future.
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.