Comprehensive security guidelines for blockchain applications. Protect your smart contracts, user data, and digital assets with enterprise-grade security practices.
Essential security practices organized by domain to ensure comprehensive protection
Best practices for secure smart contract development and deployment
Secure key generation, storage, and management practices
Authentication, authorization, and identity management
Secure communication and network infrastructure
Protecting sensitive data at rest and in transit
Security monitoring, logging, and incident response
Comprehensive security tasks organized by implementation phase
Understanding and preventing the most common smart contract vulnerabilities
Malicious contract repeatedly calls back into the target contract
Use ReentrancyGuard, follow Checks-Effects-Interactions pattern
function withdraw() external nonReentrant { ... }Arithmetic operations exceed variable limits
Use SafeMath library or Solidity 0.8+ built-in checks
using SafeMath for uint256;Unauthorized access to restricted functions
Implement proper access modifiers and role checks
modifier onlyOwner() { require(msg.sender == owner); _; }Manipulation of price oracles using flash loans
Use time-weighted average prices, multiple oracle sources
Use Chainlink or Band Protocol oraclesMEV bots exploit transaction ordering
Use commit-reveal schemes, private mempools
Implement time delays for sensitive operationsContract becomes unusable due to gas limit issues
Implement gas-efficient patterns, avoid unbounded loops
Use pagination for large data setsEssential tools for security analysis and vulnerability detection
Solidity static analysis framework
Security analysis tool for Ethereum
Symbolic execution tool
Security scanner for Ethereum
Property-based fuzzing framework
Industrial-scale fuzzing
Fast testing framework
Development environment
Formal verification platform
K framework for EVM
Verification-aware language
Interactive theorem prover
Production-ready code examples demonstrating security best practices
Example of a security-hardened ERC-20 token with protection mechanisms
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
import "@openzeppelin/contracts/security/Pausable.sol";
import "@openzeppelin/contracts/access/AccessControl.sol";
contract SecureToken is ERC20, ReentrancyGuard, Pausable, AccessControl {
bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");
bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE");
uint256 private constant MAX_SUPPLY = 1000000000 * 10**18; // 1B tokens
// Events for security monitoring
event SecurityEvent(string eventType, address indexed user, uint256 amount);
modifier validAddress(address addr) {
require(addr != address(0), "Invalid address");
require(addr != address(this), "Cannot be contract address");
_;
}
constructor() ERC20("SecureToken", "SECURE") {
_grantRole(DEFAULT_ADMIN_ROLE, msg.sender);
_grantRole(MINTER_ROLE, msg.sender);
_grantRole(PAUSER_ROLE, msg.sender);
}
function mint(address to, uint256 amount)
external
onlyRole(MINTER_ROLE)
validAddress(to)
whenNotPaused
{
require(totalSupply() + amount <= MAX_SUPPLY, "Exceeds max supply");
_mint(to, amount);
emit SecurityEvent("MINT", to, amount);
}
function transfer(address to, uint256 amount)
public
override
nonReentrant
validAddress(to)
whenNotPaused
returns (bool)
{
emit SecurityEvent("TRANSFER", msg.sender, amount);
return super.transfer(to, amount);
}
function transferFrom(address from, address to, uint256 amount)
public
override
nonReentrant
validAddress(to)
whenNotPaused
returns (bool)
{
emit SecurityEvent("TRANSFER_FROM", from, amount);
return super.transferFrom(from, to, amount);
}
function pause() external onlyRole(PAUSER_ROLE) {
_pause();
emit SecurityEvent("PAUSE", msg.sender, 0);
}
function unpause() external onlyRole(PAUSER_ROLE) {
_unpause();
emit SecurityEvent("UNPAUSE", msg.sender, 0);
}
// Emergency function to recover accidentally sent tokens
function emergencyRecover(address token, uint256 amount)
external
onlyRole(DEFAULT_ADMIN_ROLE)
{
require(token != address(this), "Cannot recover own tokens");
IERC20(token).transfer(msg.sender, amount);
emit SecurityEvent("EMERGENCY_RECOVER", msg.sender, amount);
}
}Multi-level access control with time-locks and emergency procedures
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;
import "@openzeppelin/contracts/access/AccessControl.sol";
import "@openzeppelin/contracts/security/Pausable.sol";
contract SecureAccessControl is AccessControl, Pausable {
bytes32 public constant ADMIN_ROLE = keccak256("ADMIN_ROLE");
bytes32 public constant OPERATOR_ROLE = keccak256("OPERATOR_ROLE");
bytes32 public constant EMERGENCY_ROLE = keccak256("EMERGENCY_ROLE");
struct TimeLock {
uint256 unlockTime;
bytes32 role;
address account;
bool executed;
}
mapping(bytes32 => TimeLock) public timeLocks;
uint256 public constant TIME_LOCK_DELAY = 2 days;
event RoleGrantRequested(bytes32 indexed role, address indexed account, bytes32 lockId);
event RoleGrantExecuted(bytes32 indexed role, address indexed account);
event EmergencyAction(address indexed actor, string action);
modifier onlyEmergency() {
require(hasRole(EMERGENCY_ROLE, msg.sender), "Emergency role required");
_;
}
constructor() {
_grantRole(DEFAULT_ADMIN_ROLE, msg.sender);
_grantRole(ADMIN_ROLE, msg.sender);
_grantRole(EMERGENCY_ROLE, msg.sender);
}
function requestRoleGrant(bytes32 role, address account)
external
onlyRole(ADMIN_ROLE)
{
bytes32 lockId = keccak256(abi.encodePacked(role, account, block.timestamp));
timeLocks[lockId] = TimeLock({
unlockTime: block.timestamp + TIME_LOCK_DELAY,
role: role,
account: account,
executed: false
});
emit RoleGrantRequested(role, account, lockId);
}
function executeRoleGrant(bytes32 lockId) external onlyRole(ADMIN_ROLE) {
TimeLock storage lock = timeLocks[lockId];
require(!lock.executed, "Already executed");
require(block.timestamp >= lock.unlockTime, "Time lock not expired");
_grantRole(lock.role, lock.account);
lock.executed = true;
emit RoleGrantExecuted(lock.role, lock.account);
}
function emergencyPause() external onlyEmergency {
_pause();
emit EmergencyAction(msg.sender, "PAUSE");
}
function emergencyUnpause() external onlyEmergency {
_unpause();
emit EmergencyAction(msg.sender, "UNPAUSE");
}
function emergencyRevokeRole(bytes32 role, address account)
external
onlyEmergency
{
_revokeRole(role, account);
emit EmergencyAction(msg.sender, "ROLE_REVOKE");
}
function supportsInterface(bytes4 interfaceId)
public
view
override(AccessControl)
returns (bool)
{
return super.supportsInterface(interfaceId);
}
}