OrderBook

First Flight #43
Beginner FriendlySolidity
100 EXP
View results
Submission Details
Severity: low
Valid

Incorrect Fee Calculation Precision Using Low-Denomination Constants

# Incorrect Fee Calculation Precision Using Low-Denomination Constants
## Description
The contract charges a protocol fee using a low-precision calculation:
```solidity
// @> fee logic based on small integers
uint256 protocolFee = (order.priceInUSDC * FEE) / PRECISION;
```
Where:
```solidity
uint256 public constant FEE = 3; // 3%
uint256 public constant PRECISION = 100;
```
## Risk
**Likelihood**:
* Happens on all small-value orders.
* Occurs when fees are fractional and round to zero.
**Impact**:
* Protocol earns no fees on low-value orders.
* Poor precision can cause rounding errors too.
## Proof of Concept
Create a sell order with a very small `priceInUSDC`, such as **1 USDC** (which is `1e6` in USDC's 6 decimal format). The current fee calculation uses:
```solidity
uint256 protocolFee = (order.priceInUSDC * FEE) / PRECISION;
```
Where:
```solidity
FEE = 3;
PRECISION = 100;
```
This leads to:
```solidity
protocolFee = (1e6 * 3) / 100 = 30000 (0.03 USDC) //0.03 = 0 in solidity as it doesnot support float
```
**Protocol earns 0 fee**, even though the user is using the system.
This issue is caused by Solidity’s integer division — **fractions are truncated**.
**Another Issue could be rounding errors**
Even when the fee isn't completely zero, **rounding errors** can occur due to Solidity's **integer division**, which truncates toward zero.
Solidity doesn't handle floating-point math. So when you calculate fees like this:
```solidity
uint256 protocolFee = (order.priceInUSDC * FEE) / PRECISION;
```
Any **fractional result is truncated**. For example:
```solidity
(order.priceInUSDC = 101)
(FEE = 3)
(PRECISION = 100)
protocolFee = (101 * 3) / 100 = 3.03 → truncated to 3
```
So the protocol **loses 0.03 USDC** on this order. It’s small, but over millions of orders it accumulates.
## Recommended Mitigation
Switch to 6-decimal fee precision to match USDC, e.g., 3% = `3e4`, precision = `1e6`.
```diff
- uint256 public constant FEE = 3;
- uint256 public constant PRECISION = 100;
+ uint256 public constant FEE = 30000; // 3% fee
+ uint256 public constant PRECISION = 1e6;
```
Updates

Lead Judging Commences

yeahchibyke Lead Judge 11 days ago
Submission Judgement Published
Validated
Assigned finding tags:

Fee can be bypassed

Protocol Suffers Potential Revenue Leakage due to Precision Loss in Fee Calculation

Support

FAQs

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