The ScrvusdVerifierV1
and ScrvusdVerifierV2
contracts are designed to verify and update the scrvUSD
price and profit_max_unlock_time
parameters using state proofs. However, a vulnerability exists due to the lack of strict validation on the block_number
parameter in the update_price
and update_profit_max_unlock_time
functions. This allows an attacker to front-run legitimate calls by submitting a newer block_number
through ScrvusdVerifierV2
, causing subsequent legitimate calls to fail. This issue can disrupt the normal operation of the system and potentially be exploited for malicious purposes.
In ScrvusdVerifierV1
, anyone can call verifyScrvusdByBlockHash
and verifyScrvusdByStateRoot
:
These two functions will call update_price
:
In ScrvusdOracle
, the update_price
function will check the last_block_number
:
In ScrvusdVerifierV2
, anyone can call verifyPeriodByBlockHash
and verifyPeriodByStateRoot
:
which will call update_profit_max_unlock_time
:
In ScrvusdOracle
, the update_profit_max_unlock_time
function will check the same last_block_number
:
The vulnerability arises because both update_price
and update_profit_max_unlock_time
functions validate the block_number
against the same last_block_number
. If a user submits a transaction with an older block_number
, an attacker can monitor the transaction and front-run it by submitting a newer block_number
through ScrvusdVerifierV2
. This causes the legitimate transaction to fail due to the block_number
being outdated.
Attack Scenario
A user calls ScrvusdVerifierV1
's verifyScrvusdByBlockHash
or verifyScrvusdByStateRoot
function, submitting an older block_number
.
An attacker observes the transaction and quickly calls ScrvusdVerifierV2
's verifyPeriodByBlockHash
or verifyPeriodByStateRoot
function, submitting a newer block_number
.
The attacker's transaction is executed first, updating the last_block_number
to the newer value.
The user's transaction is executed afterward but fails because the submitted block_number
is now considered outdated.
Legitimate transactions may fail, preventing the timely update of scrvUSD
prices or profit_max_unlock_time
.
Attackers can exploit this vulnerability to disrupt the system's normal operation or manipulate parameters for their benefit.
The system's reliability and trustworthiness may be compromised.
The impact is Medium, the likelihood is Medium, so the severity is Medium.
Manual Review
Do not use the same last_block_number
for different function.
- See [here]([https://github.com/CodeHawks-Contests/2025-03-curve?tab=readme-ov-file#blockhash-oracle)](https://github.com/CodeHawks-Contests/2025-03-curve?tab=readme-ov-file#blockhash-oracle) on how it is used to verify storage variable - All state roots and proofs must be verified by the OOS `StateProofVerifier` inherited as `Verifier` (where the price values and params are extracted), so there is no proof that manipulating timestamp/inputs can affect a price update - It is assumed that the OOS prover will provide accurate data and the OOS verifier will verify the prices/max unlock time to be within an appropriate bound/values - There is a account existance check in L96 of `ScrvusdVerifierV1.sol`, in which the params for price updates are extracted from
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.