## Contract Development Framework
### Secure Contract Template
```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
import "@openzeppelin/contracts/security/Pausable.sol";
import "@openzeppelin/contracts/access/AccessControl.sol";
contract SecureContract is ReentrancyGuard, Pausable, AccessControl {
// Roles
bytes32 public constant ADMIN_ROLE = keccak256("ADMIN_ROLE");
bytes32 public constant OPERATOR_ROLE = keccak256("OPERATOR_ROLE");
// State variables
mapping(address => uint256) public balances;
uint256 public totalSupply;
// Events
event Deposit(address indexed user, uint256 amount);
event Withdrawal(address indexed user, uint256 amount);
// Modifiers
modifier validAddress(address _addr) {
require(_addr != address(0), "Invalid address");
require(_addr != address(this), "Cannot be contract");
_;
}
constructor() {
_grantRole(DEFAULT_ADMIN_ROLE, msg.sender);
_grantRole(ADMIN_ROLE, msg.sender);
}
// External functions
function deposit() external payable nonReentrant whenNotPaused {
require(msg.value > 0, "Must send ETH");
balances[msg.sender] += msg.value;
totalSupply += msg.value;
emit Deposit(msg.sender, msg.value);
}
function withdraw(uint256 amount) external nonReentrant {
require(balances[msg.sender] >= amount, "Insufficient balance");
// Checks-Effects-Interactions pattern
balances[msg.sender] -= amount;
totalSupply -= amount;
(bool success, ) = msg.sender.call{value: amount}("");
require(success, "Transfer failed");
emit Withdrawal(msg.sender, amount);
}
// Admin functions
function pause() external onlyRole(ADMIN_ROLE) {
_pause();
}
function unpause() external onlyRole(ADMIN_ROLE) {
_unpause();
}
// Emergency withdrawal
function emergencyWithdraw() external onlyRole(ADMIN_ROLE) {
uint256 balance = address(this).balance;
(bool success, ) = msg.sender.call{value: balance}("");
require(success, "Transfer failed");
}
}
```
### Security Patterns
```solidity
// Reentrancy Protection
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
// Access Control
import "@openzeppelin/contracts/access/AccessControl.sol";
// SafeMath (not needed in 0.8+)
// Use checked arithmetic by default
// Pull over Push for payments
mapping(address => uint256) public pendingWithdrawals;
function withdraw() external {
uint256 amount = pendingWithdrawals[msg.sender];
require(amount > 0, "No funds");
pendingWithdrawals[msg.sender] = 0;
(bool success, ) = msg.sender.call{value: amount}("");
require(success, "Transfer failed");
}
```
## DeFi Contract Patterns
### ERC-20 Token
```solidity
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol";
import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Pausable.sol";
contract MyToken is ERC20, ERC20Burnable, ERC20Pausable, AccessControl {
bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");
constructor(string memory name, string memory symbol)
ERC20(name, symbol)
{
_grantRole(DEFAULT_ADMIN_ROLE, msg.sender);
_grantRole(MINTER_ROLE, msg.sender);
_mint(msg.sender, 1000000 * 10 ** decimals());
}
function mint(address to, uint256 amount) public onlyRole(MINTER_ROLE) {
_mint(to, amount);
}
function _beforeTokenTransfer(address from, address to, uint256 amount)
internal
override(ERC20, ERC20Pausable)
{
super._beforeTokenTransfer(from, to, amount);
}
}
```
### NFT Contract
```solidity
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol";
contract MyNFT is ERC721, ERC721URIStorage, ERC721Enumerable {
uint256 public mintPrice = 0.05 ether;
uint256 public maxSupply = 10000;
uint256 public maxPerWallet = 5;
mapping(address => uint256) public walletMints;
function mint(string memory uri) external payable {
require(msg.value >= mintPrice, "Insufficient payment");
require(totalSupply() < maxSupply, "Max supply reached");
require(walletMints[msg.sender] < maxPerWallet, "Wallet limit");
uint256 tokenId = totalSupply() + 1;
walletMints[msg.sender]++;
_safeMint(msg.sender, tokenId);
_setTokenURI(tokenId, uri);
}
}
```
## Testing with Foundry
```solidity
// Test contract
import "forge-std/Test.sol";
import "../src/Contract.sol";
contract ContractTest is Test {
Contract public c;
address public owner;
address public user;
function setUp() public {
owner = address(this);
user = address(0x1);
c = new Contract();
// Fund test user
vm.deal(user, 10 ether);
}
function testDeposit() public {
vm.prank(user);
c.deposit{value: 1 ether}();
assertEq(c.balances(user), 1 ether);
}
function test_RevertWithdrawInsufficient() public {
vm.prank(user);
vm.expectRevert("Insufficient balance");
c.withdraw(1 ether);
}
function testFuzzDeposit(uint96 amount) public {
vm.assume(amount > 0);
vm.prank(user);
c.deposit{value: amount}();
assertEq(c.balances(user), amount);
}
}
```
## Deployment Script
```solidity
// script/Deploy.s.sol
import "forge-std/Script.sol";
import "../src/Contract.sol";
contract DeployScript is Script {
function run() external {
uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY");
vm.startBroadcast(deployerPrivateKey);
Contract c = new Contract();
vm.stopBroadcast();
}
}
```
## Gas Optimization
```solidity
// Use calldata for read-only external functions
function getData(uint256[] calldata ids) external view returns (uint256[] memory) {
// ...
}
// Pack struct variables
struct Packed {
uint128 amount; // 16 bytes
uint128 timestamp; // 16 bytes = 1 slot
}
// Use immutable for constructor-set values
address public immutable token;
// Use constant for literals
uint256 public constant MAX_SUPPLY = 10000;
// Short circuit evaluation
if (condition1 && condition2) { // condition2 only checked if condition1 is true
// ...
}
```
## Security Checklist
```
PRE-DEPLOYMENT:
□ Run Slither static analysis
□ Run Mythril symbolic execution
□ Complete test coverage (>90%)
□ Fuzz testing with Echidna
□ Formal verification (Certora)
□ External audit
□ Bug bounty program
COMMON VULNERABILITIES:
□ Reentrancy (Use ReentrancyGuard)
□ Integer overflow (Solidity 0.8+)
□ Access control (Use Ownable/AccessControl)
□ Unchecked external calls
□ Front-running (Commit-reveal)
□ Timestamp manipulation
□ Block gas limit (DoS)
```