Generate secure ERC-20 token contracts with customizable features like minting, burning, and access control.
## ROLE
You are a Solidity developer specializing in token contracts who has deployed hundreds of production ERC-20 tokens.
## CONTEXT
I need to create an ERC-20 token contract.
## TOKEN SPECIFICATIONS
- Token name: ${{NAME}}
- Symbol: ${{SYMBOL}}
- Initial supply: ${{SUPPLY}}
- Decimals: ${{DECIMALS}}
- Features needed: ${{FEATURES}}
## TASK
Generate complete ERC-20 contract:
**1. FEATURE SELECTION**
| Feature | Include | Implementation |
|---------|---------|----------------|
| Mintable | | Owner can mint |
| Burnable | | Holders can burn |
| Pausable | | Emergency pause |
| Capped | | Max supply limit |
| Permit | | Gasless approvals |
| Votes | | Governance |
| Snapshots | | Balance history |
**2. BASE CONTRACT**
```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol";
import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Permit.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
contract ${{NAME}}Token is ERC20, ERC20Burnable, ERC20Permit, Ownable {
constructor(address initialOwner)
ERC20("${{NAME}}", "${{SYMBOL}}")
ERC20Permit("${{NAME}}")
Ownable(initialOwner)
{
_mint(msg.sender, ${{SUPPLY}} * 10 ** decimals());
}
function mint(address to, uint256 amount) public onlyOwner {
_mint(to, amount);
}
}
```
**3. ADDITIONAL FEATURES**
```solidity
// Pausable extension
// Capped extension
// Snapshot extension
// Custom features
```
**4. ACCESS CONTROL OPTIONS**
```solidity
// Option A: Ownable (single owner)
// Option B: AccessControl (role-based)
// Option C: AccessControlEnumerable (with enumeration)
```
**5. SECURITY CONSIDERATIONS**
- [ ] Overflow protection (built into 0.8+)
- [ ] Reentrancy (not typical for ERC20)
- [ ] Access control properly set
- [ ] Mint/burn permissions secured
**6. GAS OPTIMIZATIONS**
```solidity
// Optimization tips for your token
```
**7. DEPLOYMENT SCRIPT**
```javascript
// Hardhat deployment script
async function main() {
const Token = await ethers.getContractFactory("${{NAME}}Token");
const token = await Token.deploy(deployerAddress);
await token.waitForDeployment();
console.log("Token deployed to:", await token.getAddress());
}
```
**8. VERIFICATION COMMANDS**
```bash
npx hardhat verify --network mainnet CONTRACT_ADDRESS "CONSTRUCTOR_ARGS"
```
**9. TEST TEMPLATE**
```javascript
describe("Token", function() {
// Test cases
});
```
**10. POST-DEPLOYMENT CHECKLIST**
- [ ] Verify contract on explorer
- [ ] Test all functions
- [ ] Transfer ownership to multisig
- [ ] Add to token listsOr press ⌘C to copy
Replace these placeholders with your own content before using the prompt.
[{NAME][{SYMBOL][{SUPPLY][{DECIMALS][{FEATURES]{
constructor(address initialOwner)
ERC20("${{NAME}{
_mint(msg.sender, ${{SUPPLY}{
_mint(to, amount);
}{
const Token = await ethers.getContractFactory("${{NAME}{
// Test cases
}