|
| 1 | +# CLAUDE.md |
| 2 | + |
| 3 | +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. |
| 4 | + |
| 5 | +## Project Overview |
| 6 | + |
| 7 | +`uint-quantization-lib` is a pure-function Solidity library for shift-based `uint256` lossy compression. The core mechanism is floor quantization via right-shifting. A `Quant` value type packs `(discardedBitWidth, encodedBitWidth)` into a single `uint16`, making the compression scheme explicit and reusable. The recommended pattern is `immutable` + `create(discardedBitWidth, encodedBitWidth)`. |
| 8 | + |
| 9 | +## Commands |
| 10 | + |
| 11 | +```bash |
| 12 | +forge build # compile |
| 13 | +forge test # all tests (includes 65536 fuzz runs) |
| 14 | +forge test --match-path test/UintQuantizationLib.t.sol # library tests only |
| 15 | +forge test --match-test test_encodePrecise_notAligned_reverts # single test |
| 16 | +forge test --match-test testFuzz_ # fuzz tests only |
| 17 | +forge test --match-path test/showcase/ShowcaseGas.t.sol --gas-report -vv # gas benchmarks |
| 18 | +forge fmt # format Solidity files |
| 19 | +``` |
| 20 | + |
| 21 | +## Architecture |
| 22 | + |
| 23 | +### Core library: `src/UintQuantizationLib.sol` |
| 24 | + |
| 25 | +- UDT `Quant` wraps `uint16`: bits 0-7 = discardedBitWidth, bits 8-15 = encodedBitWidth. |
| 26 | +- All library functions are `internal pure`. |
| 27 | +- Errors (`BadConfig`, `Overflow`, `NotAligned`) are file-level, not inside the library block. |
| 28 | +- `using UintQuantizationLib for Quant global` at file bottom propagates method-call syntax to all importers automatically (no local `using` needed). |
| 29 | +- `VERSION` constant is bumped automatically by semantic-release; do not edit it manually. |
| 30 | + |
| 31 | +### Showcase: `src/showcase/ShowcaseSolidityFixtures.sol` |
| 32 | + |
| 33 | +Production-style contracts for gas benchmarks only. Raw vs quantized pairs: `RawETHStakingShowcase` / `QuantizedETHStakingShowcase` (real-life staking) and `RawExtremePackingShowcase` / `QuantizedExtremePackingShowcase` (12 slots into 1). |
| 34 | + |
| 35 | +### Tests: `test/` |
| 36 | + |
| 37 | +- `UintQuantizationLib.t.sol`: `QuantHarness` exposes library via method-call syntax for external calls. `UintQuantizationLibSmokeTest` has concrete regression tests and fuzz tests. Fuzz parameters use `uint8` for discardedBitWidth/encodedBitWidth; use `bound()` over `vm.assume` for value-in-range constraints. |
| 38 | +- `showcase/ShowcaseGas.t.sol`: Asserts quantized paths save >= 32% (real-life) and >= 80% (extreme) gas vs raw on zero-to-nonzero writes. |
| 39 | + |
| 40 | +### Configuration |
| 41 | + |
| 42 | +- `foundry.toml`: optimizer runs = 0x10000, fuzz runs = 0x10000, deps via Soldeer (`libs = ["dependencies"]`). |
| 43 | +- `remappings.txt`: maps `forge-std/` from `dependencies/`. |
| 44 | + |
| 45 | +## Conventions |
| 46 | + |
| 47 | +- Solidity `^0.8.25`, 4-space indentation, NatSpec on public-facing behavior. |
| 48 | +- Errors are file-level with bare names (not namespaced inside the library). |
| 49 | +- Create schemes with `UintQuantizationLib.create(...)`; never use `Quant.wrap(...)` directly. |
| 50 | +- Showcase pairs follow `Raw...` / `Quantized...` naming. |
| 51 | +- Test names: `test_` prefix for concrete, `testFuzz_` for fuzz. Descriptive: `test_encode_overflow_reverts`. |
| 52 | +- Fuzz tests: `uint8` params for scheme dimensions, `bound()` not `vm.assume` for bounding values. |
| 53 | +- Conventional Commits: `feat:`, `fix:`, `ci:`, `docs:`, `chore:`, `refactor:`, `perf:`. |
| 54 | +- If gas numbers change, include before/after output from the showcase gas report. |
| 55 | + |
| 56 | +## Release pipeline |
| 57 | + |
| 58 | +Fully automated on push to main (`.github/workflows/release.yml`): |
| 59 | +1. `scripts/analyze-bump.sh` checks if any `src/**/*.sol` files changed since the last Soldeer publish (`soldeer-published` tag). If no Solidity source changed, no release is created. |
| 60 | +2. If source changed, Claude (Opus, max effort) analyzes the diff and determines the semver bump (major/minor/patch). Falls back to "patch" if Claude is unavailable. |
| 61 | +3. `@semantic-release/exec` bumps the `VERSION` constant in `UintQuantizationLib.sol`. |
| 62 | +4. GitHub release created, CHANGELOG.md + source committed with `[skip ci]`. |
| 63 | +5. `forge soldeer push` publishes to the Soldeer registry, then tags `soldeer-published`. |
0 commit comments