Precision Errors Remediation
How to fix precision loss and rounding errors in DeFi calculations.
Precision Errors Remediation
Overview
Related Detector: Precision Errors
Precision loss in financial calculations enables value extraction. The fix is to always multiply before dividing, use u128 intermediates for large calculations, and apply consistent rounding direction.
Recommended Fix
Before (Vulnerable)
// Division first truncates the intermediate result
let rate = price / decimals;
let output = amount * rate;
After (Fixed)
// Multiply first to preserve precision, use u128 to prevent overflow
let output = (amount as u128)
.checked_mul(price as u128)
.unwrap()
.checked_div(decimals as u128)
.unwrap() as u64;
Alternative Mitigations
Fixed-Point Libraries
Use a fixed-point arithmetic library for complex financial calculations:
use spl_math::precise_number::PreciseNumber;
let precise_amount = PreciseNumber::new(amount as u128)?;
let precise_price = PreciseNumber::new(price as u128)?;
let result = precise_amount.checked_mul(&precise_price)?
.checked_div(&PreciseNumber::new(decimals as u128)?)?;
Common Mistakes
Mistake: Rounding in Favor of the User
// WRONG: truncation favors withdrawer, protocol loses value over time
let user_share = total_balance * user_tokens / total_supply;
Round in favor of the protocol (round down on withdrawals, round up on deposits).
Mistake: Ignoring u64 Overflow
// WRONG: amount * price can overflow u64
let value = amount * price / PRECISION;
Use u128 intermediates or checked_mul.