Skip to content

Latest commit

 

History

History
57 lines (33 loc) · 2.68 KB

050.md

File metadata and controls

57 lines (33 loc) · 2.68 KB

Elegant Arctic Stork

Medium

Precision Loss in Fee Calculation During Dutch Auction Finalization

Summary

The fee calculation approach in buyNFT will cause precision loss for the auction owner and fee recipient, as currentPrice is divided by (10 ** differenceDecimals) too early in the process, leading to inaccurate fee and transfer amounts.

Root Cause

In Auction.sol:124 the fee calculation divides currentPrice by (10 ** differenceDecimals) before multiplying by the fee percentage, resulting in rounding errors when currentPrice has significant decimal values. https://github.com/sherlock-audit/2024-11-debita-finance-v3/blob/main/Debita-V3-Contracts/contracts/auctions/Auction.sol#L124

Internal pre-conditions

  1. The auction needs to be active (isActive set to true).
  2. The difference in decimals (differenceDecimals) must be greater than zero (i.e., the selling token has fewer than 18 decimals).

External pre-conditions

  1. The selling token's decimal precision must differ from 18, leading to adjustments in currentPrice.

Attack Path

  1. A user triggers the buyNFT function to buy the NFT.
  2. The contract calculates currentPrice in the native token decimal form, then divides by (10 ** differenceDecimals), causing a rounding error.
  3. This miscalculation results in a slight discrepancy in feeAmount and the amount transferred to the auction owner and the fee address, impacting the precision of the auction proceeds.

Impact

The auction owner and fee recipient may experience a slight precision loss, typically in the range of fractions of tokens per transaction. Over multiple transactions, this can result in accumulating discrepancies, particularly if the contract is frequently used.

PoC

For example, if currentPrice is 100.5 tokens with a differenceDecimals of 2, dividing by 100 before calculating the fee introduces a rounding error that causes the fee and transfer amounts to be off by 0.5 tokens.

Mitigation

// Adjust currentPrice to base 18 decimals for accurate fee calculation

uint adjustedCurrentPrice = currentPrice * (10 ** s_CurrentAuction.differenceDecimals);
uint feeAmount = (adjustedCurrentPrice * fee) / 10000;
uint transferAmount = adjustedCurrentPrice - feeAmount;

// Normalize amounts for transfer back to token decimals
uint normalizedTransferAmount = transferAmount / (10 ** s_CurrentAuction.differenceDecimals);
uint normalizedFeeAmount = feeAmount / (10 ** s_CurrentAuction.differenceDecimals);

// Then use normalizedTransferAmount and normalizedFeeAmount for actual transfers

This approach ensures currentPrice is adjusted accurately before division, minimizing precision loss and improving the reliability of the auction process.