The Solidity verifier for scrvUSD assumes hardcoded storage slot positions for the Vyper oracle’s PriceParams
struct that do not necessarily match Vyper’s actual sequential storage layout. This misalignment can lead to the extraction of incorrect parameters, which in turn may cause the oracle to compute an inaccurate price, enabling attackers to manipulate the price feed and potentially drain stableswap pools.
The verifier’s PARAM_SLOTS
array hardcodes specific slots for struct members. For example, it assumes:
total_debt
is stored at slot 21
total_idle
is stored at slot 22
total_supply
is stored at slot 20
Other fields such as full_profit_unlock_date
, profit_unlocking_rate
, and last_profit_update
are similarly mapped, and balance_of_self
is derived via keccak256(abi.encode(18, SCRVUSD))
.
In Vyper, a struct’s members are allocated sequentially in storage. If the PriceParams
struct starts at slot n
, its members will be in slots n
(total_debt), n+1
(total_idle), n+2
(total_supply), and so on. The hardcoded values in the verifier may therefore not reflect the actual slot offsets in the deployed Vyper contract, especially when considering inherited variables or the ordering of state variables.
Reference: https://jtriley.substack.com/p/the-vyper-compiler?open=false#§storage-layout
If the verifier reads from incorrect storage slots, it will extract invalid parameter values. For instance, if the actual total_supply
is located at slot n+2
but the verifier reads slot 20, the resulting value will be erroneous. Such inaccuracies directly affect the oracle’s raw_price
computation.
The vulnerability directly undermines the integrity of the oracle’s price feed. Even if trusted roles are assumed, a wrong storage slot mapping leads to inaccurate price calculations and significant financial risk for dependent protocols.
Manual Review
Use Vyper’s storage inspection tools or compile the contract with detailed metadata to precisely determine the starting slot and sequential offsets for the PriceParams
struct.
Modify the PARAM_SLOTS
array in the verifier to reflect the actual storage layout. For example, if price_params
starts at slot n
, the mapping should be updated to:
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.