๐งฎ Solana Fixed-Point Math Library
A high-performance, fixed-point arithmetic library optimized for Solana smart contracts. Provides safe, deterministic mathematical operations with 18 decimal places of precision, designed to minimize compute units while maximizing accuracy.
โจ Features
- ๐ฏ High Precision: 18 decimal places (1e18 scale factor) for accurate financial calculations
- โก Optimized for Solana: Minimal compute units, no dynamic loops, small stack footprint
- ๐ก๏ธ Safe by Design: Comprehensive overflow/underflow protection with Anchor error handling
- ๐ข Large Number Support: U256 backing for handling massive values safely
- ๐ Advanced Math: Power functions (including fractional exponents), logarithms, square roots, and exponentials
- ๐ฏ Well-Tested: 60+ comprehensive unit tests with 100% code coverage
- ๐ Fully Documented: Complete API documentation with examples
๐ฆ Installation
Add to your Cargo.toml:
[]
= "0.1.0"
= "0.29"
Or using cargo:
๐ Quick Start
use FixedPoint;
// Create fixed-point numbers
let price = from_int; // 100
let fee = from_percent?; // 5% = 0.05
let multiplier = from_ratio?; // 3/2 = 1.5
// Perform calculations
let fee_amount = price.mul?; // 100 * 0.05 = 5.0
let adjusted = price.mul?; // 100 * 1.5 = 150.0
// Advanced operations
let sqrt_price = price.sqrt?; // โ100 = 10.0
let compound = price.pow?; // 100^1.5 โ 1000.0
let log_price = price.ln?; // ln(100) โ 4.605
๐ Usage Examples
Basic Arithmetic
use FixedPoint;
let a = from_int;
let b = from_int;
// Addition and subtraction
let sum = a.add?; // 13.0
let diff = a.sub?; // 7.0
// Multiplication and division
let product = a.mul?; // 30.0
let quotient = a.div?; // 3.333...
// Convert back to integers
assert_eq!;
Financial Calculations
// Calculate compound interest: A = P(1 + r)^n
let principal = from_int; // $1000
let rate = from_percent?; // 5% annual
let years = from_int; // 10 years
let one = from_int;
let growth_factor = one.add?.pow?; // (1.05)^10
let final_amount = principal.mul?; // โ $1628.89
println!;
DeFi Price Calculations
// Constant product AMM (x * y = k)
let reserve_x = from_int; // 1M tokens
let reserve_y = from_int; // 500K tokens
let k = reserve_x.mul?; // Constant product
// Calculate price impact for a swap
let amount_in = from_int; // 10K tokens in
let new_x = reserve_x.add?;
let new_y = k.div?;
let amount_out = reserve_y.sub?;
println!;
Percentage and Basis Points
// Working with percentages
let total = from_int;
let fee_rate = from_bps?; // 250 bps = 2.5%
let fee = total.mul?; // $250
// Discounts
let discount = from_percent?; // 15% off
let discount_amount = total.mul?; // $1,500
let final_price = total.sub?; // $8,500
Advanced Math Operations
// Power functions
let base = from_int;
let exp = from_int;
let result = base.pow?; // 2^10 = 1024
// Fractional exponents (roots)
let number = from_int;
let cube_root_exp = from_ratio?;
let cube_root = number.pow?; // 27^(1/3) โ 3
// Logarithms
let value = from_int;
let ln_value = value.ln?; // ln(100) โ 4.605
let log10_value = value.log10?; // logโโ(100) = 2
let log2_value = value.log2?; // logโ(100) โ 6.644
// Square root
let number = from_int;
let sqrt = number.sqrt?; // โ144 = 12
Utility Functions
let value = from_fraction?; // 5.7
// Floor and ceiling
let floor = value.floor; // 5.0
let ceil = value.ceil?; // 6.0
// Get fractional part
let frac = value.frac?; // 0.7
// Min and max
let a = from_int;
let b = from_int;
let min = a.min; // 3.0
let max = a.max; // 5.0
๐๏ธ Solana Program Integration
In Your Anchor Program
use *;
use FixedPoint;
Precision
- Scale Factor: 10^18 (18 decimal places)
- Basic Operations: Exact (no rounding errors)
- Square Root: โ 0.01% error (Newton's method, 4 iterations)
- Logarithms: โ 0.1% error (Taylor series, 5 terms)
- Exponentials: โ 1% error (range reduction + Taylor series)
- Powers: โ 1-5% error (depends on base and exponent)
๐งช Testing
Run the comprehensive test suite:
# Run all tests
# Run tests with output
# Run specific test
# Run with coverage
The library includes 60+ tests covering:
- โ All constructor and conversion methods
- โ Arithmetic operations and identities
- โ Advanced mathematical functions
- โ Edge cases and error handling
- โ Complex real-world scenarios
- โ Mathematical properties (commutativity, associativity, etc.)
๐ API Reference
Constructors
| Method | Description | Example |
|---|---|---|
from_int(n) |
Create from integer | FixedPoint::from_int(100) |
from_u128(n) |
Create from u128 | FixedPoint::from_u128(1_000_000) |
from_f64(n) |
Create from float (testing) | FixedPoint::from_f64(3.14)? |
from_fraction(w, n, d) |
w + n/d | FixedPoint::from_fraction(5, 1, 2)? โ 5.5 |
from_ratio(n, d) |
n/d | FixedPoint::from_ratio(3, 4)? โ 0.75 |
from_percent(p) |
Percentage | FixedPoint::from_percent(25)? โ 0.25 |
from_bps(b) |
Basis points | FixedPoint::from_bps(250)? โ 0.025 |
from_scaled(u256) |
From raw scaled value | FixedPoint::from_scaled(value) |
Conversions
| Method | Description |
|---|---|
to_u64() |
Convert to u64 (truncates decimals) |
to_u128() |
Convert to u128 (truncates decimals) |
to_f64() |
Convert to f64 (for testing/display) |
Arithmetic Operations
| Method | Description | Errors |
|---|---|---|
add(&self, other) |
Addition | Overflow |
sub(&self, other) |
Subtraction | Underflow |
mul(&self, other) |
Multiplication | Overflow |
div(&self, other) |
Division | DivisionByZero, Overflow |
Advanced Math
| Method | Description | Precision |
|---|---|---|
pow(&self, exp) |
Power (x^y) | ~1-5% |
sqrt(&self) |
Square root | ~0.01% |
ln(&self) |
Natural logarithm | ~0.1% |
log10(&self) |
Base-10 logarithm | ~0.1% |
log2(&self) |
Base-2 logarithm | ~0.1% |
log(&self, base) |
Custom base logarithm | ~0.1% |
exp(&self) |
Exponential (e^x) | ~1% |
Utility Functions
| Method | Description |
|---|---|
floor() |
Round down to integer |
ceil() |
Round up to integer |
frac() |
Get fractional part |
abs() |
Absolute value |
min(&self, other) |
Minimum of two values |
max(&self, other) |
Maximum of two values |
is_zero() |
Check if zero |
โ ๏ธ Important Notes
Error Handling
All fallible operations return Result<FixedPoint, MathError>:
Always handle errors in your Solana programs:
let result = a.div.map_err?;
Precision Considerations
- Basic operations (add, sub, mul, div) are exact
- Square root uses Newton's method (4 iterations)
- Logarithms and exponentials use Taylor series approximations
- Powers use logarithm-based computation for fractional exponents
For critical financial calculations, test edge cases thoroughly.
Compute Unit Optimization
To minimize CU usage:
- Use integer operations when possible (
from_int,to_u64) - Prefer
sqrt()overpow(x, 0.5)for square roots - Cache repeated calculations
- Use
pow2_fast()for powers of 2
๐ค Contributing
Contributions are welcome! Please follow these guidelines:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Write tests for new functionality
- Ensure all tests pass (
cargo test) - Format code (
cargo fmt) - Lint code (
cargo clippy) - Commit changes (
git commit -m 'Add amazing feature') - Push to branch (
git push origin feature/amazing-feature) - Open a Pull Request
Development Setup
# Clone the repository
# Install dependencies
# Run tests
# Run clippy
# Format code
๐ Known Limitations
- Unsigned Only: Only handles non-negative numbers (use separate sign tracking if needed)
- Approximation Errors: Complex operations (ln, exp, pow) have ~0.1-5% error
- Range Limits: Maximum value is U256::MAX / 1018 โ 1.15 ร 1059
- Compute Units: Advanced operations consume more CU than basic arithmetic
๐ License
This project is licensed under either of:
- MIT License (LICENSE-MIT or http://opensource.org/licenses/MIT)
at your option.
๐ Acknowledgments
๐ Support
- Documentation: docs.rs/ra-solana-math
- Issues: GitHub Issues
Made with โค๏ธ for the Solana ecosystem
If this library helps your project, consider giving it a โญ on GitHub!