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

The ScrvusdVerifierV1 contract is unusable due to access control in update_price.

Summary

The ScrvusdVerifierV1 contract is unusable due to access control in update_price which is callable by PRICE_PARAMETERS_VERIFIER only.

Vulnerability Details

The function verifyScrvusdByBlockHash and the function verifyScrvusdByStateRoot in ScrvusdVerifierV1.sol use call to _updatePrice which in turns calls update_price. However, update_price is access controlled and is callable by only PRICE_PARAMETERS_VERIFIER. This interlock makes the ScrvusdVerifierV1 contract unusable.

https://github.com/CodeHawks-Contests/2025-03-curve/blob/198820f0c30d5080f75073243677ff716429dbfd/contracts/scrvusd/verifiers/ScrvusdVerifierV1.sol#L66

return _updatePrice(params, block_header.timestamp, block_header.number);

https://github.com/CodeHawks-Contests/2025-03-curve/blob/198820f0c30d5080f75073243677ff716429dbfd/contracts/scrvusd/verifiers/ScrvusdVerifierV1.sol#L79

return _updatePrice(params, params[5], _block_number);

https://github.com/CodeHawks-Contests/2025-03-curve/blob/198820f0c30d5080f75073243677ff716429dbfd/contracts/scrvusd/verifiers/ScrvusdVerifierV1.sol#L113-L121

/// @dev Calls the oracle to update the price parameters.
/// Both child contracts use the same oracle call, differing only in how they obtain the timestamp.
function _updatePrice(
uint256[PARAM_CNT] memory params,
uint256 ts,
uint256 number
) internal returns (uint256) {
return IScrvusdOracle(SCRVUSD_ORACLE).update_price(params, ts, number);
}

https://github.com/CodeHawks-Contests/2025-03-curve/blob/198820f0c30d5080f75073243677ff716429dbfd/contracts/scrvusd/oracles/ScrvusdOracleV2.vy#L295-L305

def update_price(
_parameters: uint256[ALL_PARAM_CNT], _ts: uint256, _block_number: uint256
) -> uint256:
"""
@notice Update price using `_parameters`
@param _parameters Parameters of Yearn Vault to calculate scrvUSD price
@param _ts Timestamp at which these parameters are true
@param _block_number Block number of parameters to linearize updates
@return Absolute relative price change of final price with 10^18 precision
"""
access_control._check_role(PRICE_PARAMETERS_VERIFIER, msg.sender) #@audit access control here.

Impact

Both the functions verifyScrvusdByBlockHash and verifyScrvusdByStateRoot in the ScrvusdVerifierV1.sol use update_price which is callable by PRICE_PARAMETERS_VERIFIER only, resulting in ScrvusdVerifierV1 unusable.

Tools Used

Manual review

Recommendations

Consider including appropriate access control in ScrvusdVerifierV1 contract and allowing calls from ScrvusdVerifierV1 contract to access update_price in addition to the present access by PRICE_PARAMETERS_VERIFIER.

Updates

Lead Judging Commences

0xnevi Lead Judge
6 months ago
0xnevi Lead Judge 5 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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