code-423n4 / 2022-08-olympus-findings

5 stars 4 forks source link

Operator.sol bond markets will stop functioning if price becomes greater than 10 ** (decimals * 2) #469

Closed code423n4 closed 1 year ago

code423n4 commented 2 years ago

Lines of code

https://github.com/code-423n4/2022-08-olympus/blob/b5e139d732eb4c07102f149fb9426d356af617aa/src/policies/Operator.sol#L363-L469

Vulnerability details

Impact

Bond markets cease to work

Proof of Concept

https://github.com/code-423n4/2022-08-olympus/blob/b5e139d732eb4c07102f149fb9426d356af617aa/src/policies/Operator.sol#L375

uint256 oracleScale = 10**uint8(int8(PRICE.decimals()) - priceDecimals);

L375 will underflow and revert when PRICE.decimals()) < priceDecimals.

int8 priceDecimals = _getPriceDecimals(range.cushion.high.price);

function _getPriceDecimals(uint256 price_) internal view returns (int8) {
    int8 decimals;
    while (price_ >= 10) {
        price_ = price_ / 10;
        decimals++;
    }
    return decimals - int8(PRICE.decimals());
}

The price here is already reduced by PRICE.decimals. This means that L375 will underflow when:

range.cushion.high.price > 10 ** (decimals * 2)

Tools Used

Recommended Mitigation Steps

Use an int instead of a uint for oracle scale

Oighty commented 2 years ago

The price feeds we're using have 18 decimals. For this to underflow, the price would need to be greater than 1e36, which implies 1e36 reserve tokens per OHM. There are no potential reserve assets that we're using with a price that low or with that many token decimals.

0xean commented 1 year ago

downgrading to QA