Muscular Ceramic Dragonfly
Medium
The lack of proper handling for rounding errors in the checkMinOrderSize function will cause financial risks for the platform and users as an attacker will exploit rounding discrepancies to process orders below the minimum size requirement.
In checkMinOrderSize(IERC20 tokenIn, uint256 amountIn) there is insufficient rounding control when calculating the USD equivalent of an order.
No response
No response
A user attempts to place an order for 10 TokenA. In the checkMinOrderSize function, the following calculations are performed:
-
amountIn = 10 (number of tokens)
-
tokenPriceUSD = 0.001 (current price of the token in USD)
-
orderValueUSD = (10 * 0.001 * 10^18) / (10^18), resulting in orderValueUSD = 10 USD (initial value)
-
However, due to potential rounding errors, if tokenPriceUSD is rounded down to a smaller value (for example, $0.000999999999999999), the calculated orderValueUSD could be: orderValueUSD = (10 * 0.000999999999999999 * 10^18) / (10^18), resulting in orderValueUSD = 9.999999999999999 USD.
As a result, the checkMinOrderSize function incorrectly determines that the order for 10 TokenA meets the minimum size requirement since 9.999999999999999 < 10, and the order will be processed when it should have been rejected.
The platform suffers an approximate loss of funds due to the acceptance of invalid orders. The attacker gains the ability to exploit the rounding error for profit, while users face unexpected financial losses from processed trades.
No response
function checkMinOrderSize(IERC20 tokenIn, uint256 amountIn) external view returns (bool) {
uint256 tokenPriceUSD = getTokenPriceInUSD(tokenIn); // Assume this function gets the current price
uint256 orderValueUSD = (amountIn * tokenPriceUSD + (1 ether - 1)) / (10 ** tokenIn.decimals()); // Adjusted rounding
// Check if the order value meets the minimum size
return orderValueUSD >= minOrderSizeUSD;
}