Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
583 changes: 335 additions & 248 deletions .gas-snapshot

Large diffs are not rendered by default.

9 changes: 0 additions & 9 deletions .github/workflows/copy-artifacts.yaml

This file was deleted.

17 changes: 0 additions & 17 deletions .github/workflows/manual-sol-artifacts.yaml

This file was deleted.

2 changes: 0 additions & 2 deletions .github/workflows/package-release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,5 @@ jobs:
release:
uses: rainlanguage/rainix/.github/workflows/rainix-autopublish.yaml@main
with:
crate: rain-math-float
npm-package: "@rainlanguage/float"
soldeer-package: rain-math-float
secrets: inherit
5 changes: 0 additions & 5 deletions .github/workflows/rainix-rs-static.yaml

This file was deleted.

5 changes: 0 additions & 5 deletions .github/workflows/rainix-rs-test.yaml

This file was deleted.

5 changes: 0 additions & 5 deletions .github/workflows/rainix-rs-wasm.yaml

This file was deleted.

3 changes: 0 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,7 @@ out
cache
dependencies
.direnv
target
temp
dist
node_modules
.env
.fixes
.pre-commit-config.yaml
Expand Down
1 change: 0 additions & 1 deletion .prettierignore

This file was deleted.

10 changes: 0 additions & 10 deletions .soldeerignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,31 +7,21 @@
.gitignore
.gitmodules
.pre-commit-config.yaml
.prettierignore
.soldeerignore
.vscode
CLAUDE.md
/audit
/cache
/crates
/dependencies
/dist
/docs
/flake.lock
/flake.nix
/foundry.lock
/foundry.toml
/lib
/node_modules
/out
/package.json
/package-lock.json
/remappings.txt
/scripts
/slither.config.json
/soldeer.lock
/target
/test
/test_js
/tsconfig.json
/REUSE.toml
123 changes: 23 additions & 100 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,133 +5,57 @@ code in this repository.

## Project Overview

Decimal floating-point math library for Rainlang/DeFi. The `Float` type packs a
224-bit signed coefficient and 32-bit signed exponent into a single `bytes32`.
Decimal (not binary) representation ensures exact decimal values (e.g., `0.1`).
No NaN, Infinity, or negative zero — operations error on nonsense rather than
producing special values.
Pure Solidity decimal floating-point math library for Rainlang/DeFi. The `Float`
type packs a 224-bit signed coefficient and 32-bit signed exponent into a single
`bytes32`. Decimal (not binary) representation ensures exact decimal values
(e.g., `0.1`). No NaN, Infinity, or negative zero — operations error on nonsense
rather than producing special values.

Dual implementation: Solidity for on-chain, Rust/WASM for off-chain JS/TS
consumption. The Rust crate uses revm to execute Solidity via an in-memory EVM,
ensuring identical behavior.
This repository is the library half of the rain.math.float split. It publishes
only the `rain-math-float` Soldeer package. The deployed concrete contract, the
on-chain deploy pins/snapshot, the deploy scripts/tests, and the Rust/WASM/npm
bindings live in `rain.math.float.deploy` and publish from there.

## Build Commands

### Solidity (Foundry)

```bash
forge build # Compile contracts
forge test # Run all Solidity tests (5096 fuzz runs)
forge test --mt testFunctionName # Run specific test by name
forge test -vvvv # Verbose trace output for debugging
nix develop # Enter dev shell with all tooling
```

### Rust

```bash
cargo build # Build native
cargo build --target wasm32-unknown-unknown --lib -r # Build WASM
cargo test # Run Rust tests
cargo test test_name # Run specific test
```

Rust tests depend on Foundry build artifacts (`out/`). Run `forge build` before
`cargo test` if artifacts are missing.

### JavaScript/WASM

```bash
npm install
npm run build # Full pipeline: Rust WASM → wasm-bindgen → base64 embed → CJS/ESM dist
npm test # TypeScript type check + vitest (tests in test_js/)
```

### Nix

```bash
nix develop # Enter dev shell with all tooling
```

### Deployment

Contracts are deployed deterministically via the Zoltu proxy to the same address
on all supported networks (Arbitrum, Base, Base Sepolia, Flare, Polygon). The
deterministic address is a function of bytecode + salt only — not the branch or
deployer — so a successful deploy from any branch lands at the same address a
main-branch deploy would.

**Typical flow for a source-changing PR**: trigger the `Manual sol artifacts`
GitHub workflow on the PR's branch before merge.
`gh workflow run manual-sol-artifacts.yaml --ref <branch> -f suite=decimal-float`
(use `log-tables` only when table bytecode changes, which is rare). The workflow
runs `script/Deploy.sol` with `--broadcast --verify` across all networks, using
`PRIVATE_KEY` regardless of ref. Do NOT wait for merge before deploying — there
is nothing to gain from waiting, and the CI deploy-constant tests need updating
anyway based on the deployed address.

**Two deployment suites** (log-tables must be deployed first if redeploying
tables):

```bash
DEPLOYMENT_KEY=<key> DEPLOYMENT_SUITE=log-tables forge script script/Deploy.sol:Deploy --broadcast --verify
DEPLOYMENT_KEY=<key> DEPLOYMENT_SUITE=decimal-float forge script script/Deploy.sol:Deploy --broadcast --verify
```

Expected addresses and code hashes are in
`src/lib/deploy/LibDecimalFloatDeploy.sol`. Any source change to
`LibDecimalFloat` or `LibFormatDecimalFloat` invalidates these constants; CI's
`testDeployAddress` and `testExpectedCodeHashDecimalFloat` will fail until
they're regenerated and committed. Network RPC URLs are configured in
`foundry.toml` via `CI_DEPLOY_*_RPC_URL` env vars.

## Architecture

### Solidity Layer (`src/`)
### Source (`src/`)

- **`lib/LibDecimalFloat.sol`** — Public API: arithmetic, comparison,
conversion, formatting, parsing. User-defined type `Float` wrapping `bytes32`.
- **`lib/implementation/`** — Internal arithmetic (512-bit intermediates for
mul/div), normalization, packing.
- **`lib/parse/`** — String-to-Float parsing.
- **`lib/format/`** — Float-to-string formatting.
- **`lib/table/`** — Log lookup tables (deployed as a data contract at a
deterministic address).
- **`concrete/DecimalFloat.sol`** — Exposes library functions as contract
methods (required for Rust/revm interop via ABI).
- **`lib/table/`** — Log lookup table source (`LibLogTable`); the transcendental
functions take the deployed tables-contract address as a parameter.
- **`error/`** — Custom error definitions (CoefficientOverflow,
ExponentOverflow, DivisionByZero, etc.).

### Scripts (`script/`)

- **`Deploy.sol`** — Production deployment script using Zoltu deterministic
proxy. Deploys log tables and DecimalFloat contract to all supported networks.
- **`BuildPointers.sol`** — Generates `src/generated/LogTables.pointers.sol`
(committed to repo; must be regenerated if log table data changes).

### Rust Layer (`crates/float/`)

- **`lib.rs`** — `Float` struct wrapping `B256`, implements
`Add`/`Sub`/`Mul`/`Div`/`Neg`. Uses `alloy::sol!` macro to generate bindings
from Foundry JSON artifacts in `out/`.
- **`js_api.rs`** — `#[wasm_bindgen]` exports for JS consumption (parse, format,
arithmetic, conversions).
- **`evm.rs`** — In-memory EVM setup via revm. All Rust float operations
delegate to Solidity through this.
- **`error.rs`** — Maps Solidity error selectors to Rust error types.

### JavaScript Layer
### Tests (`test/`)

- **`scripts/build.js`** — Build pipeline: compiles WASM, runs wasm-bindgen,
base64-encodes WASM into JS modules for both CJS and ESM.
- **`test_js/`** — Vitest tests for the WASM bindings.
- **`dist/`** — Generated output (CJS + ESM with embedded WASM).
- **`src/lib/`** — The pure-math suite mirroring `src/lib/`.
- **`abstract/LogTest.sol`** — Test helper that rebuilds the combined log tables
from `LibLogTable` source and deploys them as a data contract at a `create`
address, so the transcendental tests (`log10`/`pow`/`pow10`/`sqrt`) run
without any on-chain deploy pin.
- **`lib/`** — Reference (slow) implementations used to cross-check the library.

### Dependencies (`dependencies/`)

Managed by [Soldeer](https://soldeer.xyz) (`[dependencies]` in `foundry.toml`,
`libs = ['dependencies']`), not git submodules: forge-std,
`@openzeppelin-contracts`, rain-solmem, rain-string, rain-datacontract,
rain-deploy, rain-sol-codegen. Run `forge soldeer install` to fetch them.
`@openzeppelin-contracts`, rain-solmem, rain-string, rain-datacontract. Run
`forge soldeer install` to fetch them.

## Key Design Details

Expand All @@ -140,8 +64,7 @@ rain-deploy, rain-sol-codegen. Run `forge soldeer install` to fetch them.
(`ExponentOverflow` / `ExponentUnderflow`). Coefficient truncation on values
too large for int224 is silently tolerated because it preserves the order of
magnitude.
- Log/power use lookup table approximations with linear interpolation (table
deployed as a data contract).
- Log/power use lookup table approximations with linear interpolation.
- Three packing modes:
- `packLossless`: reverts on any precision loss.
- `packLossy`: surfaces the `lossless` flag, returns `FLOAT_ZERO` on exponent
Expand Down
Loading
Loading