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
to determine the storage slot. However, according to Solidity’s mapping storage layout rules, the storage slot for a mapping value is derived as:
Given that the intended key is the contract’s address (SCRVUSD
) and the mapping slot is 18
, the correct computation should be:
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:
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:
Demonstration via a Simple Script:
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.
- 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)
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.