Pieces Protocol

First Flight #32
Beginner FriendlyFoundrySolidityNFT
100 EXP
View results
Submission Details
Severity: low
Valid

[M-5] Rounding Errors in Fee Calculations Can Lead to Loss of Precision and Financial Discrepancies

Summary

The buyOrder function calculates fees using integer division, which can lead to rounding errors and loss of precision. For example, if order.price is small, the calculated fees may be zero. This can result in the protocol not collecting the intended fees, leading to financial discrepancies

Vulnerability Details

The fee calculations in the buyOrder function use integer division, which truncates any fractional part of the result. This can lead to significant rounding errors, especially for small values of order.price. As a result, the calculated fees may be zero or significantly lower than intended, causing financial discrepancies in the protocol.

function buyOrder(uint256 orderIndex, address seller) external payable {
// ... (checks omitted for brevity)
uint256 fee = order.price / 100; // 1% fee
uint256 sellerFee = fee / 2; // 0.5% fee to seller
// Rest of the function...
}

Impact

Medium Impact: Small amounts of funds may be lost due to rounding errors, especially for small order.price values.

Financial Discrepancies: The protocol may not collect the intended fees, leading to financial losses or inconsistencies.

User Dissatisfaction: Users may perceive the protocol as unfair or unreliable if fees are not calculated accurately.

Tools Used

Slither, Foundry

Recommendations

Use fixed-point arithmetic or scaled values to avoid rounding errors and ensure precise fee calculations. For example:

uint256 constant FEE_SCALE = 1e18; // Scale for precision
uint256 constant FEE_PERCENT = 1e16; // 1% fee (1e18 * 0.01)
uint256 constant SELLER_FEE_RATIO = 2; // 50% of the fee goes to the seller
function buyOrder(uint256 orderIndex, address seller) external payable {
// Existing checks...
uint256 fee = (order.price * FEE_PERCENT) / FEE_SCALE; // 1% fee with precision
uint256 sellerFee = fee / SELLER_FEE_RATIO; // 0.5% fee to seller
// Rest of the function...
}

Additional Considerations:

Use libraries like OpenZeppelin's SafeMath or PRBMath for precise arithmetic operations.

Emit events to log fee calculations and ensure transparency for users and auditors.

Updates

Lead Judging Commences

fishy Lead Judge 5 months ago
Submission Judgement Published
Validated
Assigned finding tags:

Precision loss

Support

FAQs

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