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 5 months 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.

Give us feedback!