Checking...
GEMINI AI
Available
Back to Home

Security Best Practices

Essential security guidelines for developing secure smart contracts

Why Security Matters

Smart contracts handle valuable assets and execute critical business logic. A single vulnerability can lead to catastrophic losses. Following security best practices is not optional—it's essential for protecting users and maintaining trust in your protocol.

These guidelines are based on common vulnerabilities found in production contracts and recommendations from security experts. Always audit your contracts before deployment, especially for production use.

Access Control

Use Access Control Modifiers

critical

Always use OpenZeppelin's Ownable or AccessControl for managing permissions. Never hardcode addresses.

Example:

Use `onlyOwner` modifier or role-based access control instead of direct address checks.

Implement Multi-Signature Wallets

high

For critical operations, require multiple signatures before execution.

Example:

Use Gnosis Safe or implement custom multi-sig for admin functions.

Avoid tx.origin

critical

Never use `tx.origin` for authorization. Always use `msg.sender` instead.

Example:

`require(msg.sender == owner)` instead of `require(tx.origin == owner)`.

Reentrancy Protection

Use Checks-Effects-Interactions Pattern

critical

Always follow the CEI pattern: check conditions, update state, then interact with external contracts.

Example:

Update balances before calling external contracts to prevent reentrancy attacks.

Implement ReentrancyGuard

critical

Use OpenZeppelin's ReentrancyGuard modifier for functions that call external contracts.

Example:

Add `nonReentrant` modifier to functions that perform external calls.

Avoid External Calls in Loops

high

External calls in loops can lead to gas issues and reentrancy vulnerabilities.

Example:

Batch external calls or use pull payment patterns instead.

Integer Overflow/Underflow

Use SafeMath or Solidity 0.8+

critical

Always use SafeMath library or Solidity 0.8+ which has built-in overflow protection.

Example:

Use `SafeMath.add()` or rely on Solidity 0.8+ automatic checks.

Validate Input Ranges

high

Always validate that inputs are within expected ranges before performing arithmetic.

Example:

Check that amounts are greater than 0 and less than maximum before calculations.

Gas Optimization

Use Packed Storage

medium

Pack multiple small variables into single storage slots to save gas.

Example:

Use `uint128` instead of `uint256` when values are small enough.

Cache Storage Variables

medium

Cache frequently accessed storage variables in memory to reduce gas costs.

Example:

Store `balances[user]` in a local variable if accessed multiple times.

Use Events Instead of Storage

low

For data that doesn't need to be read on-chain, use events instead of storage.

Example:

Emit events for historical data that can be indexed off-chain.

Input Validation

Validate All External Inputs

critical

Always validate inputs from users, external contracts, and oracles.

Example:

Check that addresses are not zero, amounts are positive, and arrays are not empty.

Use Require Statements with Clear Messages

medium

Provide clear error messages in require statements for better debugging.

Example:

`require(amount > 0, 'Amount must be greater than zero')`.

Sanitize String Inputs

high

Validate and sanitize string inputs to prevent injection attacks.

Example:

Check string length and validate format before processing.

Additional Security Resources

Security Tools

  • • Slither - Static analysis tool
  • • Mythril - Security analysis framework
  • • Echidna - Property-based fuzzer
  • • Manticore - Symbolic execution tool

Security Standards

  • • OpenZeppelin Contracts - Secure library
  • • Consensys Best Practices
  • • SWC Registry - Vulnerability database
  • • DeFi Security Standards
Live
0 Audits
0 NFTs