Omniscia Euler Finance Audit

ScaleUtils Manual Review Findings

ScaleUtils Manual Review Findings

SUS-01M: Potential Increase of Acceptable Values

Description:

The ScaleUtils::calcOutAmount function will perform a sequence of calculations which may result in interim overflow operations that could potentially be avoided by restructuring the arithmetic order of operations.

Specifically, the calculation inAmount * unitPrice may overflow when executing the code's else path, however, the inAmount * priceScale calculation may succeed and the result of the result * unitPrice / feedScale with arbitrary precision may be calculate-able with an end-result that fits within a 256 bit number.

Similarly, the if branch of the code executes a priceScale * unitPrice calculation that may underflow when the divisions can be performed in sequence.

Impact:

The current approach is sound, and in most circumstances the overflow would occur in an upstream call that would utilize the result of the function.

In any case, as the ScaleUtils::calcOutAmount function is meant to be a library we consider an increase of its operational range to be potentially desirable.

Example:

src/lib/ScaleUtils.sol
64/// @notice Convert the price by applying scale factors.
65/// @param inAmount The amount of `base` to convert.
66/// @param unitPrice The unit price reported by the feed.
67/// @param scale The scale factors returned by `calcScale`.
68/// @param inverse Whether to price base/quote or quote/base.
69/// @return The resulting outAmount.
70function calcOutAmount(uint256 inAmount, uint256 unitPrice, Scale scale, bool inverse)
71 internal
72 pure
73 returns (uint256)
74{
75 uint256 priceScale = (Scale.unwrap(scale) << 128) >> 128;
76 uint256 feedScale = Scale.unwrap(scale) >> 128;
77 if (inverse) {
78 // (inAmount * feedScale) / (priceScale * unitPrice)
79 return FixedPointMathLib.fullMulDiv(inAmount, feedScale, priceScale * unitPrice);
80 } else {
81 // (inAmount * unitPrice * priceScale) / feedScale
82 return FixedPointMathLib.fullMulDiv(inAmount * unitPrice, priceScale, feedScale);
83 }
84}

Recommendation:

We advise the code to potentially accommodate for these cases, re-ordering the arithmetic sequences if any of the interim calculations overflow and thus increasing the total range of values that the ScaleUtils::calcOutAmount function will produce a result for.

Alleviation:

The Euler Finance team evaluated this exhibit and specified that the current safe operational range of the function is adequate for their intents and purposes.

SUS-02M: Potential Negation Overflow

Description:

The referenced statement will perform a negation without validating that the diff value will properly fit in the int8 data type if negated.

Impact:

As evidenced in exhibits within the PythOracle, this particular code segment will not be executed. Additionally, the negation would overflow and thus the code would simply revert as negations are performed using checked arithmetic.

As such, this exhibit cannot constitute a vulnerability that is higher than informational.

Example:

src/lib/ScaleUtils.sol
53/// @notice Calculate the scale factors for converting a unit price.
54/// @param baseDecimals The decimals of the base asset.
55/// @param quoteDecimals The decimals of the quote asset.
56/// @param priceDecimals The decimals of the feed price, not incorporated into the price.
57/// @return The scale factors used for price conversions.
58function calcScale(uint8 baseDecimals, uint8 quoteDecimals, int8 priceDecimals) internal pure returns (Scale) {
59 int8 diff = int8(baseDecimals) - priceDecimals;
60 if (diff > 0) return from(quoteDecimals, uint8(diff));
61 else return from(quoteDecimals + uint8(-diff), 0);
62}

Recommendation:

We advise the code to ensure the diff value is different than the minimum possible (type(int8).min), yielding a descriptive error message in such a case as the negation would overflow.

Alleviation:

The relevant function of this exhibit was removed as part of remediative efforts for POE-02C, rendering this exhibit inapplicable.