Invariants before contracts
Writing down what must always be true, before writing the code that must never break it, is the cheapest smart-contract security you can buy.
Normal software has a forgiving relationship with bugs. You find one, you fix it, you deploy. A deployed contract holding other people's money has no such affordance: a bug is not a ticket, it is a loss, and it is public.
The practice that changes outcomes more than any other is writing the invariants first. Before the implementation exists, state the properties that must always hold. Total supply equals the sum of balances. The pool can never pay out more than it holds. No function lets a caller withdraw someone else's position.
Written this way, the properties become executable. Foundry runs them as invariant tests, throwing generated sequences of calls at the contract and trying to violate them. This finds a category of bug that example-based unit tests structurally cannot, because you did not think of the sequence.
The second-order effect is on design. Properties that are difficult to state usually indicate a contract doing too much. When you cannot express what must remain true, that is the signal to split the thing, not to write a longer sentence.
None of this replaces an external audit, and we say so to every client who hopes it might. What it does is make the audit cheaper and less alarming, because the findings that survive to the auditor are the subtle ones rather than the ones a property test would have caught in week one.