sherlock-audit / 2024-08-flayer-judging

2 stars 0 forks source link

Fit Cyan Kookaburra - Lack of validation checks will cause transaction reverts for users #808

Closed sherlock-admin4 closed 1 month ago

sherlock-admin4 commented 1 month ago

Fit Cyan Kookaburra

Low/Info

Lack of validation checks will cause transaction reverts for users

Summary

In multiple contracts (TaxCalculator.sol, LinearRangeCurve.sol, BaseImplementation.sol, CollectionShutdown.sol, Listings.sol), lack of checks before division operations will cause transaction reverts for users as division by zero errors occur when denominators are zero.

Root Cause

Divisions are performed without ensuring that denominators are non-zero:

Internal pre-conditions

  1. TaxCalculator.sol

    • Line 69:
      • UTILIZATION_KINK equals 1 ether, making 1 ether - UTILIZATION_KINK zero.
    • Line 117:
      • _initialCheckpoint.compoundedFactor is zero.
  2. LinearRangeCurve.sol

    • Line 60:
      • end equals start, so end - start is zero.
  3. BaseImplementation.sol

    • Line 199:
      • ONE_HUNDRED_PERCENT is zero.
  4. CollectionShutdown.sol

    • Lines 150, 245, 310, 343:
      • ONE_HUNDRED_PERCENT is zero.
      • Other variables in denominators are zero.
  5. Listings.sol

    • Line 933:
      • _listing.duration is zero.

External pre-conditions

N/A.

Attack Path

  1. Users or contracts invoke functions that perform divisions without checking denominators:

    • For example, a user calls a function that calculates interest or fees.
  2. A division by zero occurs due to zero denominators:

    • The calculation attempts to divide by zero, causing an exception.
  3. Transactions revert, leading to denial of service:

    • The function execution halts, and the user's transaction fails.

Impact

The affected parties cannot execute transactions involving these calculations, resulting in:

PoC

Example for LinearRangeCurve.sol Line 60:

// Scenario where end equals start
uint128 spotPrice = 1 ether;
uint128 delta = packDelta(1000, 1000); // start = end = 1000
uint256 numItems = 1;

// Unpack delta to get start and end
(uint32 start, uint32 end) = unpackDelta(delta);

// This will cause a division by zero
uint256 inputValue = numItems * (spotPrice * (end - block.timestamp) / (end - start));
// Since end == start, (end - start) == 0, causing division by zero

Similar PoCs for other instances:

Mitigation