Oracle price does not compound #22
Labels
3 (High Risk)
Assets can be stolen/lost/compromised directly
bug
Something isn't working
sponsor confirmed
Sponsor agrees this is a problem and intends to fix it (OK to use w/ "disagree with severity")
Lines of code
https://github.com/code-423n4/2022-03-volt/blob/f1210bf3151095e4d371c9e9d7682d9031860bbd/contracts/oracle/ScalingPriceOracle.sol#L136
https://github.com/code-423n4/2022-03-volt/blob/f1210bf3151095e4d371c9e9d7682d9031860bbd/contracts/oracle/ScalingPriceOracle.sol#L113
Vulnerability details
Impact
The oracle does not correctly compound the monthly APRs - it resets on
fulfill
.Note that the
oraclePrice
storage variable is only set in_updateCPIData
as part of the oraclefulfill
callback.It's set to the old price (price from 1 month ago) plus the interpolation from
startTime
to now.However,
startTime
is reset inrequestCPIData
due to theafterTimeInit
modifier, and therefore when Chainlink callsfulfill
in response to the CPI request, thetimeDelta = block.timestamp - startTime
is close to zero again andoraclePrice
is updated to itself again.This breaks the core functionality of the protocol as the oracle does not track the CPI, it always resets to
1.0
after everyfulfill
instead of compounding it.In addition, there should also be a way for an attacker to profit from the sudden drop of the oracle price to
1.0
again.POC
As an example, assume
oraclePrice = 1.0 (1e18)
,monthlyAPR = 10%
. The time elapsed is 14 days. CallinggetCurrentOraclePrice()
now would return1.0 + 14/28 * 10% = 1.05
.requestCPIData
. This resetsstartTime = now
.getCurrentOraclePrice()
now would return1.0
again astimeDelta
(andpriceDelta
) is zero:oraclePriceInt + priceDelta = oraclePriceInt = 1.0
.fulfill
is called it setsoraclePrice = getCurrentOraclePrice()
which will be close to1.0
as thetimeDelta
is tiny.Recommended Mitigation Steps
The
oraclePrice
should be updated inrequestCPIData()
not infulfill
.Cover this scenario of multi-month accumulation in tests.
The text was updated successfully, but these errors were encountered: