Fast Khaki Raccoon
Medium
The bellow math performs one crucial mistake, it calculates the divergence, by using the higher value - highExchangeRate
as denominator.
// 1e5 * (highExchangeRate - lowExchangeRate) / highExchangeRate
uint256 _deviation = (
DEVIATION_PRECISION * (_exchangeRateInfo.highExchangeRate - _exchangeRateInfo.lowExchangeRate)
) / _exchangeRateInfo.highExchangeRate;
This will cause values that should be equal or bigger than maxOracleDeviation
to still be smaller than it, further allowing borrowing when the system should be stopped due to a faulty oracle.
if (_deviation <= _exchangeRateInfo.maxOracleDeviation) {
_isBorrowAllowed = true;
}
This bug is best shown with an example or two.
From this example we have secluded that the difference between 10 and 15 would cause a 33.3% divergence, not taking into account that 5 is 50% of 10.
prerequisite | values |
---|---|
lowExchangeRate | 100k |
highExchangeRate | 105.25k |
maxOracleDeviation | 5% |
Here even though the value difference between 100k and 105.25k is 5.25k we still pass the bellow 5% maxOracleDeviation
and thus operate as normal allowing borrowers to borrow.
Dividing by the highExchangeRate
rather than the low one.
No response
No response
There is no attack path per say, just a faulty environment where the bug would happen on occasion. Perhaps the attack would be a user to borrow at times when borrowing should be disabled, but isn't due to the faulty math.
Oracles will function normally even when the deviation exceeds _exchangeRateInfo.maxOracleDeviation
.
Invariant is broken.
The system allows users to borrow under a state where it's checks should stop borrowing:
if (_deviation <= _exchangeRateInfo.maxOracleDeviation) {
_isBorrowAllowed = true;
}
No response
Consider dividing by the low one to make the system more secure and avoid possible failures. Alternative would be to use the average between the two.