Blockchain 10 min read

Solidity Best Practices for Secure Smart Contracts

By Born Digital Studio Team Malta

Solidity is the dominant language for Ethereum and EVM-compatible smart contracts, but its apparent simplicity masks serious pitfalls. A small oversight can lead to exploits worth millions. Writing secure Solidity requires understanding the EVM execution model, common vulnerability patterns, and defensive coding practices. Here are the practices we follow at Born Digital when building smart contracts for clients in the blockchain space.

Reentrancy and the Checks-Effects-Interactions Pattern

Reentrancy remains one of the most dangerous vulnerabilities in Solidity. It occurs when a contract makes an external call before updating its own state, allowing the called contract to re-enter the function and exploit the stale state. The classic defence is the checks-effects-interactions pattern: first validate all conditions (checks), then update contract state (effects), and only then make external calls (interactions). For additional protection, use OpenZeppelin's ReentrancyGuard modifier, which prevents nested calls to functions marked as nonReentrant. Every function that transfers ETH or tokens or makes external calls should be reviewed for reentrancy risk.

Access Control and Permissions

Proper access control is critical for contract security. Avoid relying solely on tx.origin for authentication, as this is vulnerable to phishing attacks. Use msg.sender instead. For role-based access control:

  • OpenZeppelin AccessControl: Provides granular role-based permissions with admin hierarchy. Define roles like MINTER_ROLE, PAUSER_ROLE, and ADMIN_ROLE to separate responsibilities across different addresses.
  • Ownable pattern: Suitable for simpler contracts where a single owner is sufficient. Always implement a two-step ownership transfer to prevent accidental loss of control.
  • Timelocks: For high-stakes operations like upgrading contracts or changing critical parameters, implement timelocks that give users time to react before changes take effect.

Gas Optimisation Techniques

Gas efficiency directly impacts user costs and contract usability. Pack storage variables to minimise slot usage — the EVM uses 32-byte storage slots, so group smaller types together. Use uint256 as the default integer type since the EVM operates on 256-bit words natively. Prefer mappings over arrays for lookups, use calldata instead of memory for read-only function parameters, and cache storage reads in local variables when a value is accessed multiple times within a function. Mark functions as external instead of public when they are only called from outside the contract. Use events for data that does not need to be read on-chain — event logs are significantly cheaper than storage writes.

Error Handling and Validation

Use custom errors introduced in Solidity 0.8.4 instead of revert strings — they are more gas-efficient and provide better developer experience. Validate all inputs at the start of functions using require statements or custom errors. Be explicit about integer overflow protection: Solidity 0.8.x includes built-in overflow checks, but if you use unchecked blocks for gas optimisation, ensure the arithmetic is provably safe. Never assume external contract calls will succeed — handle failures gracefully using try-catch for known interfaces and check return values for low-level calls.

Testing and Deployment

Comprehensive testing is not optional for smart contracts — once deployed, bugs cannot be patched without complex upgrade mechanisms. Write unit tests for every function, integration tests for contract interactions, and fuzz tests to discover edge cases. Use Foundry or Hardhat with coverage tools to ensure all code paths are tested. Before mainnet deployment, deploy to testnets, run formal verification where feasible, and engage at least one independent security audit. At Born Digital, we follow these practices rigorously when developing smart contracts, because in blockchain, there are no second chances with deployed code.

Need help with blockchain?

Born Digital offers expert blockchain services from Malta.

Share this article

Help others discover this insight

Born Digital Studio Team

Born Digital Studio is a Malta-based digital engineering studio specialising in eCommerce, blockchain, and digital product development. We build high-performance platforms for businesses across Europe.

Have a project in mind?

If this topic resonates with your business challenges, let's talk about how we can help.