Tadle

Tadle
DeFiFoundry
27,750 USDC
View results
Submission Details
Severity: low
Valid

Precision Errors in Token Calculations

Vulnerability Details:

The contract employs floor rounding in several division operations, leading to potential precision loss over time. This issue is particularly noticeable in functions like closeBidTaker, where token amounts are calculated.

Impact:

Repeated transactions that consistently round down can cause a cumulative loss of value, affecting the precision of token distributions. This discrepancy between expected and actual balances could become significant over multiple transactions.

Proof Of Concept:

Link to code\

In the closeBidTaker function, consider the following scenario:

uint256 collateralFee = 1000000; // 1 million tokens
uint256 userRemainingPoints = 999;
uint256 offerInfo.usedPoints = 1000;
uint256 userCollateralFee = collateralFee.mulDiv(
userRemainingPoints,
offerInfo.usedPoints,
Math.Rounding.Floor
);
// userCollateralFee = 1000000 * 999 / 1000 = 999000

Here, the user receives 999,000 tokens. However, if similar calculations are repeated 1000 times, the cumulative loss would amount to:

1000 * (1000000 - 999000) = 1,000,000 tokens

This illustrates how small rounding errors can add up to significant losses after numerous transactions.

Additionally, when userRemainingPoints is much smaller than offerInfo.usedPoints, the floor rounding could reduce the fee to zero, even when a non-zero fee should be charged. For instance:

If collateralFee is 100, userRemainingPoints is 1, and offerInfo.usedPoints is 1000, the calculation results in:
100 * 1 / 1000 = 0 (rounded down)

But the actual fee should be 0.1, which would round to 1 in integer arithmetic.

Tools Used:

Manual Review

Recommendations:

*To mitigate this issue, consider using higher precision during calculations. Multiply by a large constant before performing division, and then scale back down:

uint256 PRECISION = 1e18;
uint256 userCollateralFee = collateralFee.mulDiv(
userRemainingPoints * PRECISION,
offerInfo.usedPoints,
Math.Rounding.Floor
) / PRECISION;

*Implement a minimum fee threshold to prevent very small fees from being rounded down to zero:

uint256 userCollateralFee = collateralFee.mulDiv(
userRemainingPoints,
offerInfo.usedPoints,
Math.Rounding.Floor
);
uint256 MIN_FEE = 1; // Set an appropriate minimum value
if (userCollateralFee == 0 && collateralFee > 0) {
userCollateralFee = MIN_FEE;
}
Updates

Lead Judging Commences

0xnevi Lead Judge about 1 year ago
Submission Judgement Published
Validated
Assigned finding tags:

finding-PreMarkets-Rounding-Direction

Duplicate of #456, however, for issues noting rounding directions, will be low severity given the impact is not proven sufficiently with a PoC/numerical example and most rounding will not result in significant losses e.g. most examples only proved at most a 1 wei difference when computing `depositAmount/platFormFees` and involves lower amount offers

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.