- Pin the compiler version with an exact pragma (`pragma solidity 0.8.24;`) rather than a range — ranges allow unintended compiler upgrades that change behavior.
- Use `PascalCase` for contract and event names, `camelCase` for functions and local variables, and `UPPER_CASE` for constants.
- Declare visibility (`public`, `external`, `internal`, `private`) explicitly on every function and state variable — never rely on defaults.
- Use `external` instead of `public` for functions only called from outside the contract — `external` reads calldata directly and costs less gas.
- Order contract members consistently: state variables, events, errors, modifiers, constructor, external functions, public functions, internal functions, private functions.
- Use `immutable` for values set once in the constructor and `constant` for compile-time literals — both avoid storage slot costs.
- Emit events for every significant state change to enable off-chain indexing — include both old and new values where relevant for better auditability.
- Use custom errors (`error InsufficientBalance(uint256 available, uint256 required);`) instead of `require` with string messages — they save gas and are more descriptive.