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

No checks on slot.value validity

Summary

The ScrvusdVerifierV1 contract fails to validate the logical consistency of parameters extracted from storage proofs,

Vulnerability Details

Affected Code

1. Parameter Extraction Without Validation:

// In ScrvusdVerifierV1.sol
function _extractParametersFromProof(...) internal view returns (uint256[PARAM_CNT] memory) {
// Extracts parameters without validation
for (uint256 i = 1; i < PROOF_CNT; i++) {
Verifier.SlotValue memory slot = Verifier.extractSlotValueFromProof(...);
params[i - 1] = slot.value; // No checks on slot.value validity
}
}

2. Oracle Price Calculation Vulnerability:
In ScrvusdOracleV2.vy, price is computed as:

python

def _raw_price(ts: uint256, parameters_ts: uint256) -> uint256:
return self._total_assets(parameters) * 10**18 // self._total_supply(parameters, ts)

In Case:

  • total_debt = 0

  • total_idle = 0

  • total_supply = 1 (to avoid division by zero)

Result:

_total_assets = 0 + 0 = 0

price = 0 * 1e18 / 1 = 0

Impact

return price = 0, breaking integrations.

Tools Used

  1. Manual Code Review

    • Identified lack of parameter validation in the verifier.

  2. Static Analysis

    • Confirmed division risks in _raw_price.

Recommendations

1. Add Parameter Sanity Checks in Verifier

solidity

// In ScrvusdVerifierV1.sol
require(params.total_debt + params.total_idle > 0, "Invalid total_assets");
require(params.total_supply > 0, "Invalid total_supply");
Updates

Lead Judging Commences

0xnevi Lead Judge 3 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement
Assigned finding tags:

[invalid] finding-slot-not-check-verifierv1-v2

- 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.

Support

FAQs

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