One rule
Assume every public or external function will be called by a stranger, a bot, or another contract. Write the function so it is still safe.
A safer contract checks first, updates its own state second, and talks to other contracts last. This is Checks-Effects-Interactions.
Public means public
Do not store secrets in a contract. Private variables are not secret. Local variables are not secret either. Anyone can inspect contract data on-chain.
Use Solidity 0.8.x arithmetic checks. Do not add unchecked blocks unless you can explain why wrapping is safe.