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

Incorrect Double Hashing in` _extractParametersFromProof` in `ScrvusdVerifierV1.sol`

Summary

The _extractParametersFromProof function applies an unnecessary keccak256 hash to all PARAM_SLOTS[i] values when extracting storage slot data. This double hashing affects all parameters (params[0] to params[6]), including literal slots (e.g., 21 for total_debt) and the calculated slot for balanceOf(self). As a result, all extracted values are likely incorrect, disrupting the data passed to SCRVUSD_ORACLE for price updates.

Vulnerability Details

In the function _extractParametersFromProof:

Verifier.SlotValue memory slot = Verifier.extractSlotValueFromProof(
keccak256(abi.encode(PARAM_SLOTS[i])),
account.storageRoot,
proofs[i].toList()
);
  • The function hashes each PARAM_SLOTS[i] value with keccak256(abi.encode(...)) before passing it to extractSlotValueFromProof.

  • For literal slots (e.g., PARAM_SLOTS[1] = 21 for total_debt):

Expected: Slot 21 should be used directly to fetch total_debt.

Actual: keccak256(abi.encode(21)) is used, which points to an unrelated slot.

  • For the computed slot (PARAM_SLOTS[7] = keccak256(abi.encode(18, SCRVUSD))):

Expected: A precomputed slot like keccak256(abi.encode(SCRVUSD, 18)) should be used directly.

Actual: keccak256(abi.encode(keccak256(abi.encode(18, SCRVUSD)))) is used, further deviating from the correct slot.

This affects all extracted params values (total_debt, total_idle, totalSupply, etc ).

Impact

  1. Data Corruption: All params values (params[0] to params[6]) passed to SCRVUSD_ORACLE are incorrect, likely breaking the oracle’s ability to compute accurate prices or validate state.

  2. Financial Risk: If SCRVUSD is a token contract and the oracle relies on these parameters (e.g., totalSupply, total_debt) for pricing or liquidity, this could lead to significant financial miscalculations or exploitable errors.

Tools Used

  • Manual code review

Recommendations

Fix the logic: Remove the extra keccak256 hash to use PARAM_SLOTS[i] directly

function _extractParametersFromProof(
bytes32 stateRoot,
bytes memory proofRlp
) internal view returns (uint256[PARAM_CNT] memory) {
RLPReader.RLPItem[] memory proofs = proofRlp.toRlpItem().toList();
require(proofs.length == PROOF_CNT, "Invalid number of proofs");
Verifier.Account memory account = Verifier.extractAccountFromProof(
SCRVUSD_HASH,
stateRoot,
proofs[0].toList()
);
require(account.exists, "scrvUSD account does not exist");
uint256[PARAM_CNT] memory params;
for (uint256 i = 1; i < PROOF_CNT; i++) {
Verifier.SlotValue memory slot = Verifier.extractSlotValueFromProof(
(-) keccak256(abi.encode(PARAM_SLOTS[i])), //remove this line
(+) PARAM_SLOTS[i], //Add this line
account.storageRoot,
proofs[i].toList()
);
params[i - 1] = slot.value;
}
return params;
}
Updates

Lead Judging Commences

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

[invalid] finding-storage-key-compute-wrong

See primary comments in issue #23

Support

FAQs

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