code-423n4 / 2022-03-volt-findings

0 stars 0 forks source link

Possibility of stale and static value of VOLT for longer duration on change of ScalingPriceOracle #87

Closed code423n4 closed 2 years ago

code423n4 commented 2 years ago

Lines of code

https://github.com/code-423n4/2022-03-volt/blob/f1210bf3151095e4d371c9e9d7682d9031860bbd/contracts/oracle/ScalingPriceOracle.sol#L71-L95

Vulnerability details

If there will be a need for governance action to swap out the ScalingPriceOracle that the OraclePassThrough points to, then it will have to be performed only after 15th till 30/31st of any month. This is due to two constraints viz,

  (1) 28 days TIMEFRAME, and 
  (2) the requestCPIData() cannot be performed before the 15th of the month.

Due to this, if any change of ScalingPriceOracle is done during 3rd(4th in case of 31 days in that month) until 15th, there will be stale / static value for a longer period of time (more than 3 days as mentioned in the Notes on LERP in SYSTEMARCHITECTURE.md). For Example, if the new ScalingPriceOracle is deployed on 3rd April, the 28 days TIMEFRAME will expire on 1st May, but the requestCPIData() cannot be called until 15th of May,
So, the linear interpolation will stop, and there will be a constant price reported from 1st May until 15th May, which will not be truly reflecting the changes in the CPIData.

Impact

Because of stale and static price reported for longer period (ref. above), there may be undesired behavior like possibility for arbitrage opportunities, etc., and the protocol behaves like any other stable coin, and not inflation adjusted as its supposed to be.

Proof of Concept

Contract : ScalingPriceOracle.sol

Refer Notes On LERP from : https://github.com/code-423n4/2022-03-volt/blob/main/SYSTEMARCHITECTURE.md

The 28 day linear interpolation timeframe leaves the possibility for the price to not increase for 1-3 days after the change has finished interpolating. This could cause an increase in VOLT borrow demand during that period of time as the cost of inflation does not exist for borrowers during this window. Alternative solutions have been evaluated, however, it is not clear that these solutions are strictly better as there are likely tradeoffs such as increased gas costs for reading the VOLT price from the oracle. This issue of increased borrow demand for a short period of time is only exploitable by users with a large bankroll that are trying to get leverage for a very short period of time, and are not selling and buying back the VOLT as the trading fees would likely eat into any cost savings. This cost savings would be equivalent to 6 basis points, which is small enough to ignore.

Recommended Mitigation Steps

Change code such that we have ability to set the startTime in Timed.sol, during deployment of ScalingPriceOracle.sol contract.

In Timed.sol add below function,

    function _setStartTime(uint256 _startTime) internal {
        startTime = _startTime;
    }

And in the constructor of ScalingPriceOracle.sol add another parameter for startTimeValue with below changes

line#35 _initTimed(); replace this line with

    _setStartTime(startTimeValue) 

where the startTimeValue parameter = value of startTime in old ScalingPriceOracle.sol contract

ElliotFriedman commented 2 years ago

This was a previously acknowledged issue in the docs.