In ScrvusdVerifierV1.sol
, the _extractParametersFromProof
function only checks that the proofs array has the correct overall length but fails to validate the individual proof elements. This is in contrast to ScrvusdVerifierV2.sol
, which performs more comprehensive validation of its proofs. This inconsistency could lead to the extraction of incorrect parameters, potentially affecting the accuracy of price calculations in the scrvUSD oracle system.
Severity: Medium
Files Affected:
contracts/scrvusd/verifiers/ScrvusdVerifierV1.sol
Functions Affected:
_extractParametersFromProof()
In ScrvusdVerifierV1.sol
, the proof validation is limited to checking the array length:
The function then proceeds to extract slot values without additional validation:
In contrast, ScrvusdVerifierV2.sol
includes more comprehensive validation:
This inconsistency in validation could allow malformed or incomplete proofs to be processed by ScrvusdVerifierV1.sol
, potentially leading to incorrect parameter extraction.
The implications become more severe when examining how these parameters are used in the oracle (ScrvusdOracleV2.vy
):
These parameters are then used in critical price calculations:
If any of these parameters are incorrect due to improper proof validation, it could directly affect price calculations and potentially lead to division by zero errors or incorrect prices.
The inadequate proof validation in ScrvusdVerifierV1.sol
could have several implications:
Silent Use of Default Values: If a storage slot doesn't exist in the scrvUSD contract, the function would still use the default value (0) for the parameter, which could lead to incorrect price updates.
Incorrect Parameter Extraction: Malformed proofs might lead to extracting incorrect data or misinterpreting the proof structure, causing price calculations based on invalid inputs.
Potential Oracle Manipulation: An attacker might craft special proof inputs that exploit the lack of validation to manipulate the extracted parameters, potentially affecting price calculations in the oracle.
Financial Impact: Given that these parameters are used in price calculations that may affect trading decisions, incorrect values could lead to financial losses for users of the protocol.
Division by Zero Risk: If the total_supply parameter (params[2]) is incorrectly extracted as 0, it could cause division by zero errors in the oracle's price calculations.
Inconsistent Behavior Between Contracts: The different validation approaches between V1 and V2 create inconsistent security profiles, where V2 is more robust against certain types of invalid inputs.
Manual code review
Add Comprehensive Proof Validation:
Enhance the proof validation in ScrvusdVerifierV1.sol
to match or exceed the rigor of ScrvusdVerifierV2.sol
:
Add Proof Element Validation:
Add validation for each individual proof element to ensure they are properly formatted:
Standardize Validation Across Contracts:
Implement a shared validation function that both contracts can use to ensure consistent validation:
Add Parameter Reasonableness Checks:
Beyond validating the proof structure, add checks to ensure extracted parameters are within reasonable bounds, especially considering their role in the oracle's price calculations:
Consider Parameter-Specific Validation:
Add validation specific to each parameter type based on their usage in the oracle:
By implementing these recommendations, particularly the comprehensive proof validation and slot existence checks, the contract would be more robust against invalid or malicious inputs, reducing the risk of incorrect parameter extraction and improving overall security of the price oracle system.
- Looking at the OOS `StateProofVerifier` and `MerklePatriciaProofVerifier` contract that extracts the slot, the `exists` flag will be flagged as true as long as a non-zero length value is returned as seen [here](https://github.com/curvefi/curve-xdao/blob/3ff77bd2ccc9c88d50ee42d2a746fc7648c7ff2c/contracts/libs/StateProofVerifier.sol#L133C13-L136). From the `MerklePatriciaProofVerifier.extractProofValue`, the minimum length returned will be 1 as represenetd by `bytes(0)`. So this seems to be purely a sanity check that might not even be required. - A slot with zero values is only allowed when the proof provided by the prover correctly proofs that such values are included within the Merkle-Patricia-Tree. The values fetched from mainnet from the V3Vault stored in the merkle trie is likely checked before hand and aggregated into the MerkleTree.
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.