Skip to content

Latest commit

 

History

History
91 lines (57 loc) · 2.86 KB

039.md

File metadata and controls

91 lines (57 loc) · 2.86 KB

Glamorous Tweed Albatross

Medium

Division by Zero in getExchangeRate

Summary

The lack of validation for priceOut in the getExchangeRate function allows division by zero, which can revert critical operations and disrupt user order processing. This vulnerability occurs because priceOut relies on external oracles, which may return zero under certain conditions.

Root Cause

The _getExchangeRate function directly divides priceIn by priceOut without verifying that priceOut is greater than zero:

https://github.com/sherlock-audit/2024-11-oku/blob/main/oku-custom-order-types/contracts/automatedTrigger/AutomationMaster.sol#L86

Internal pre-conditions

1- The oracles[tokenOut].currentValue() method must return 0. 2- The _getExchangeRate function must be called as part of order execution or maintenance.

External pre-conditions

1- Oracle malfunction or misconfiguration causes priceOut to be zero. 2- Manipulated oracles provide a zero price for tokenOut.

Attack Path

1-Oracle Manipulation:

  • An attacker influences the external price oracle to return 0 for priceOut.
  • For example, they might exploit a flash loan to affect price feeds or tamper with low-liquidity markets.

2- Division by Zero:

  • When _getExchangeRate is called, the division by priceOut triggers a revert.

3- Impact on Operations:

  • All transactions relying on this function, such as order creation or upkeep, fail.
  • This leads to user disruption and possible denial-of-service conditions.

Impact

1- User Disruption:

  • Orders relying on the affected token pair will fail to execute.
  • Users may experience delays or inability to trade due to contract reverts.

2- Denial of Service:

  • Manipulating the oracle to zero can disrupt the entire system if many orders depend on the affected token.

3- Reputation Damage:

  • Persistent disruptions can erode user trust in the platform.

PoC

Setup: Deploy the contract with a mock oracle system. Configure tokenOut's oracle to return 0 for currentValue.

Trigger: Call a function dependent on _getExchangeRate, such as checkInRange or performUpkeep.

Expected Result: Observe that the contract reverts due to division by zero.

Mitigation

Proposed Fix

Add a validation step to ensure priceOut is greater than zero before performing the division: Corrected Code:

function _getExchangeRate(IERC20 tokenIn, IERC20 tokenOut) internal view returns (uint256 exchangeRate) {
    uint256 priceIn = oracles[tokenIn].currentValue();
    uint256 priceOut = oracles[tokenOut].currentValue();

    require(priceOut > 0, "Price out is zero");
    return (priceIn * 1e8) / priceOut;
}

Alternatively, validate oracle values earlier in the workflow:

uint256 priceOut = oracles[tokenOut].currentValue();
require(priceOut > 0, "Invalid price from oracleOut");
uint256 exchangeRate = (priceIn * 1e8) / priceOut;