🎱Wrong Assumption of 18 decimals

Wrong price scale for GasOracle

Vulnerability Details

The GasOracle contract currently utilizes two Chainlink oracles to derive the gas price in USD: one oracle provides the gas price in ETH (with variable decimals), and the other offers the USD value per ETH (also with variable decimals). The contract multiplies the raw values returned from these oracles without adequately accounting for the decimals involved, assuming a fixed decimal scale of 18 for the result.

This assumption is articulated in the code comment:

plaintextCopy code"Returned value is USD/Gas * 10^18 for compatibility with rest of calculations"

However, this approach introduces risks as the true decimal scale of the oracles may differ from the assumed 18 decimals. There is a toWad function present in the codebase, designed for scaling conversions, but it remains unused, failing to address the scaling issue.

Impact

Incorrect decimal scaling leads to significant discrepancies in the reported gas price in USD. Depending on the actual decimals provided by the oracles, the gas price may be substantially inflated or underreported, leading to inaccurate cost estimations and potential financial losses for users engaging with the contract.

To rectify this vulnerability, the contract should dynamically adjust its decimal scaling based on the actual decimals provided by each oracle. Implement the following steps to mitigate the risk:

  1. Query the decimals() function from the Chainlink oracles to ascertain the decimal count of each oracle’s responses.

  2. Scale the raw oracle responses to a consistent 18 decimals.

  3. Ensure that the latestAnswer function consistently returns values scaled to 18 decimals, irrespective of the decimals provided by the underlying oracles.

By implementing dynamic decimal scaling, the contract will provide accurate gas price estimations in USD, preventing the risks associated with fixed decimal assumptions and enhancing the reliability and accuracy of the contract's operations.

makerPrice assumes oracle price is always in 18 decimals

Vulnerability Details

The EIP1271Wallet._validateOrder function within the system calculates a makerPrice, which inherently uses 18 decimals since takerToken is invariably set to WETH. This decimal count must align with that of the priceFloor returned by the Chainlink oracle to ensure accurate and reliable comparisons between the two values. The present deprecated Chainlink API appears to operate with the assumption of 18 decimals, yet this might not be the case should an upgrade to a newer API version occur.

In the scenario of an API upgrade, the decimal count for Chainlink’s returned values might differ, potentially leading to inconsistencies and inaccuracies in the price comparison process within _validateOrder function. Hence, relying on the current setup without addressing the decimal alignment issue poses risks of malfunction.

To preemptively address and rectify potential decimal misalignments between makerPrice and priceFloor:

  1. Upgrade the Chainlink API: Move away from the deprecated API to the newer version, ensuring access to the latest features and improved reliability.

  2. Dynamic Decimal Adjustment: Implement a mechanism that dynamically adjusts the decimals of makerPrice to align with those of priceFloor. This adjustment should consider the actual decimal count provided by the upgraded Chainlink API.

    For instance, retrieve and use the decimals() function from the Chainlink oracle to ascertain the decimal count of the priceFloor. Then, scale the makerPrice accordingly to ensure that both values are compared at the same decimal level, preventing any inaccuracies or issues arising from decimal misalignment.

By proactively upgrading and implementing dynamic decimal adjustment, you ensure that the system remains resilient and accurate in its price comparisons, irrespective of the API version or decimal count variations introduced by Chainlink in the future.

Impact

The identified vulnerability pertains to a critical miscalculation in the TwapOracle.sol file, which can lead to significant inaccuracies in the computed result value due to incorrect handling of the token's decimals. Since this result value plays a crucial role in the minting mechanism, any error in its computation can lead to severe implications for the platform's functionality and security. Ensuring the oracle's accuracy is crucial, as inaccuracies can lead to imprecise valuations and unintended consequences in transactions, significantly jeopardizing the system’s integrity and users' assets.

Proof of Concept

In TwapOracle.sol, at line 156, the code calculates result using the following formula:

javascriptCopy coderesult = ((sumUSD * IERC20Metadata(token).decimals()) / sumNative);

For a token with 18 decimals, this translates into:

javascriptCopy coderesult = ((sumUSD * 18) / sumNative);

This calculation is problematic and logically incorrect. It appears that the intent was to scale sumUSD by the token's number of decimals, but the implemented logic does not achieve this due to the multiplication by the number of decimals rather than by a scaling factor derived from the number of decimals. The issue results in a significant miscalculation of result, with potential severe implications given its role in the minting mechanism.

The calculation should be corrected to scale sumUSD appropriately based on the token’s decimals. Replace the erroneous line of code with the following corrected version:

javascriptCopy codeuint256 scalingFactor = 10 ** IERC20Metadata(token).decimals();
result = (sumUSD * scalingFactor) / sumNative;

This corrected calculation uses a scalingFactor derived from the token's number of decimals, ensuring accurate scaling and, consequently, a precise computation of result. It is crucial to promptly address and rectify this vulnerability to preserve the platform's functionality and protect against potential exploits leveraging this calculation error. Since the oracle's accuracy is a key audit focus, this high-severity issue demands immediate attention and resolution.

Last updated