Both the ScrvusdVerifierV1.sol
and ScrvusdVerifierV2.sol
contracts make external calls to oracle contracts but fail to validate the return values from these calls, potentially masking oracle failures and leading to inconsistent protocol states. This is particularly concerning when examining the oracle contract (ScrvusdOracleV2.vy
), which returns meaningful values like price changes and update success indicators.
Severity: Medium
Files Affected:
contracts/scrvusd/verifiers/ScrvusdVerifierV1.sol
contracts/scrvusd/verifiers/ScrvusdVerifierV2.sol
Functions Affected:
_updatePrice()
in ScrvusdVerifierV1
verifyPeriodByBlockHash()
in ScrvusdVerifierV2
verifyPeriodByStateRoot()
in ScrvusdVerifierV2
In ScrvusdVerifierV1.sol
, the _updatePrice
function returns the result from the oracle call without any validation:
Looking at the oracle contract, we can see that this return value is significant - it represents the relative price change:
Similarly, in ScrvusdVerifierV2.sol
, both verification functions return the boolean result from the oracle calls without validation:
The oracle's corresponding function returns a boolean indicating whether the update was successful:
If these oracle calls fail silently (return 0 or false without reverting), the verifier contracts will propagate these failures without any indication of the issue. This creates a potential for silent failures where price or period updates appear to succeed but actually fail.
The lack of return value validation could lead to several issues:
Silent Failures: If the oracle operations fail but return a value rather than reverting, callers of these functions might assume the operations succeeded when they actually failed.
Inconsistent State: Silent failures could lead to inconsistent states between the verifier contracts and the oracles they interact with, potentially causing incorrect financial calculations.
Price Change Monitoring Issues: The update_price
function returns the relative price change, which could be important for monitoring and alerting systems. Without validation, significant price changes might not trigger appropriate alerts.
Missed Period Updates: If update_profit_max_unlock_time
returns false (indicating no change), this could be a meaningful business logic signal that's being ignored.
Protocol Instability: Over time, repeated silent failures could lead to significant divergence between expected and actual protocol states, potentially affecting protocol stability and the accuracy of price data.
Manual code review
Validate Oracle Return Values:
For ScrvusdVerifierV1
, check the returned price change and potentially log or act on significant changes:
For ScrvusdVerifierV2
, explicitly check the boolean return value:
Consider Reverting on Failed Updates:
For critical updates, consider reverting the transaction if the update doesn't produce the expected result:
Add Comprehensive Event Emission for Oracle Interactions:
Emit detailed events for all oracle interactions to facilitate monitoring and debugging:
Implement Oracle Interaction Circuit Breakers:
Add circuit breaker logic to prevent continued updates if the oracle is consistently returning unexpected values:
By implementing these recommendations, particularly the explicit validation and logging of oracle return values, the contracts would be more robust against silent failures and provide better visibility into oracle interaction issues.
- 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.