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

Incorrect Storage Slot Calculation for balanceOf

Details:
The vulnerability arises from how the storage slot for the balanceOf(self) parameter is computed in the ScrvusdVerifierV1 contract. The contract uses the expression

keccak256(abi.encode(18, SCRVUSD))

to determine the storage slot. However, according to Solidity’s mapping storage layout rules, the storage slot for a mapping value is derived as:

keccak256(abi.encode(key, slot))

Given that the intended key is the contract’s address (SCRVUSD) and the mapping slot is 18, the correct computation should be:

keccak256(abi.encode(SCRVUSD, 18))

This mistake causes the contract to reference an incorrect storage slot when extracting the balance, which leads to reading an unintended value.

Root Cause:
The root cause is the reversed order of arguments in the abi.encode call. The developer mistakenly encoded the slot number first and the contract address second, rather than the other way around, causing the computed hash to target the wrong slot in storage.

Impact:

  • Incorrect Parameter Extraction: The contract reads a balance value from an unintended storage slot, meaning the value passed to the oracle’s update_price function will be wrong.

  • Potential Mispricing: Since the oracle relies on this value, any miscalculation can lead to incorrect pricing, which might be exploited by attackers or result in significant financial discrepancies.

  • Broader System Effects: Inaccurate data can cascade through any financial logic that uses this balance, undermining system integrity and trust.

Recommendation:

  • Correct the Parameter Order: Update the computation to use the proper order:

    uint256(keccak256(abi.encode(SCRVUSD, 18)))
  • Review All Storage Slot Calculations: Perform a thorough audit of other similar storage slot computations to ensure that the correct ordering is consistently applied.

  • Test Against Known Values: Validate the corrected hash against manually computed values or test cases to ensure that the extracted balance corresponds to the expected storage slot.

Proof of Concept:

  1. Demonstration via a Simple Script:

    // Example snippet to compare computed storage slots:
    pragma solidity 0.8.18;
    contract SlotCalculation {
    address public constant SCRVUSD = 0x0655977FEb2f289A4aB78af67BAB0d17aAb84367;
    function wrongSlot() public pure returns (bytes32) {
    // Incorrect order: slot number first, then address.
    return keccak256(abi.encode(18, SCRVUSD));
    }
    function correctSlot() public pure returns (bytes32) {
    // Correct order: address first, then slot number.
    return keccak256(abi.encode(SCRVUSD, 18));
    }
    }
  2. Verification:
    Deploy the contract and call both functions. The output values will differ, confirming that the ordering affects the computed storage slot. The correct implementation should match the Solidity storage layout for mappings.

Updates

Lead Judging Commences

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

[invalid] finding-ScrvusdVerifierV1-incorrect-storage-slot-balanceOf-compute

- Per sponsor comments, verified slot is vyper, solidity contract only verifies it. - Vyper computes storage slots different from solidity as seen [here](https://ethereum.stackexchange.com/questions/149311/storage-collision-in-vyper-hashmap)

Support

FAQs

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