# CLAUDE.md: Smart contract work (Solidity)

## Hard rules
- Never deploy, broadcast transactions, sign messages, or read private keys/mnemonics. No `forge script --broadcast`, no `cast send`. Local `anvil` only.
- Don't add new dependencies without naming their audit status. Prefer OpenZeppelin Contracts at a pinned version.

## Commands
`forge build` · `forge test -vvv` · `forge test --match-test testFuzz` · `forge coverage` · `forge snapshot` (gas) · `slither .` · `forge fmt`

## Checklist for every change
- **Access control:** who can call each external/public function? Admin functions use roles or `Ownable2Step`; initializers can only run once.
- **Reentrancy:** state updated before external calls; `nonReentrant` on functions that move value; consider read-only reentrancy for view functions used by others.
- **Math and units:** decimals handled explicitly; rounding direction favors the protocol; no precision loss from dividing before multiplying.
- **External calls and tokens:** `SafeERC20`, handle fee-on-transfer/rebasing tokens or document they're unsupported; check return values.
- **Oracles:** no spot prices from AMMs for valuation; check staleness and decimals of price feeds.
- **DoS:** no unbounded loops over user-controlled arrays; pull over push payments.
- **Upgrades:** storage layout preserved (`forge inspect <C> storageLayout`), `_disableInitializers()` in implementation constructors.
- **Events** for all state changes; custom errors for reverts.

## Tests
Unit + fuzz + invariant tests (`invariant_totalSupplyMatchesBalances`). Every bug fix starts with a failing test reproducing the exploit.

## Report
List findings by severity (critical/high/medium/low/info) with the affected function and a suggested fix.
