TextDAO Contracts Coding Standards
This document outlines the coding standards and best practices for developing smart contracts in the TextDAO project. Adhering to these standards ensures consistency, readability, and maintainability across the codebase.
General Guidelines
- Use Solidity version 0.8.24 or later.
- Follow the official Solidity Style Guide as a baseline.
- Use
pragma solidity ^0.8.24;at the beginning of each file.
Naming Conventions
Contracts and Libraries
- Use PascalCase
Example:
MyContract,TextDAOLibrary
Interfaces
- Prefix with
Iand use PascalCase Example:IMyInterface,ITextDAO
Functions
- Use camelCase
- Prefix internal functions in contracts with an underscore (_)
- Do not prefix internal functions in libraries with an underscore
Example:
myFunction,calculateTotal,_internalFunction(in contracts)
Variables
- Use camelCase for function parameters, return variables, and local variables
- Prefix storage variables with
s_ - Prefix immutable variables with
i_ - Prefix constant variables with
c_Example:uint256 totalAmount,address s_owner,uint256 i_maxSupply,uint256 public constant c_MAX_SUPPLY = 1000000
Events
- Use PascalCase
- Prefix warning events with
WARN_Example:TransferEvent,ProposalCreated,WARN_InsufficientFunds
Modifiers
- Use mixedCase
Example:
onlyOwner,nonReentrant
Enums
- Use PascalCase for enum name, and ALL_CAPS for values
Example:
enum Color { RED, GREEN, BLUE }
Struct
- Use PascalCase
Example:
struct UserInfo { ... }
Code Layout
- Use 4 spaces for indentation (not tabs).
- Maximum line length is 120 characters.
- Use single quotes for strings.
- Place the opening brace on the same line as the declaration.
- Place the closing brace on a new line.
Example:
contract MyContract {
uint256 private constant c_MAX_VALUE = 100;
function calculateSum(uint256 a, uint256 b) public pure returns (uint256) {
require(a < c_MAX_VALUE && b < c_MAX_VALUE, 'Values too large');
return a + b;
}
}
Documentation
- Use NatSpec comments for all public and external functions and state variables.
- Write clear and concise comments explaining complex logic.
- Keep comments up-to-date when changing code.
Example:
/// @notice Calculates the sum of two numbers
/// @param a The first number
/// @param b The second number
/// @return The sum of a and b
function calculateSum(uint256 a, uint256 b) public pure returns (uint256) {
// Ensure inputs are within acceptable range
require(a < c_MAX_VALUE && b < c_MAX_VALUE, 'Values too large');
return a + b;
}
Security Considerations
- Use the
checks-effects-interactionspattern to prevent reentrancy. - Be cautious with
delegatecalland understand its implications. - Use
transfer()orcall.value()()with checks for ETH transfers. - Avoid using
tx.originfor authentication. - Use SafeMath for versions < 0.8.0 (for 0.8.0 and later, built-in overflow checks are sufficient).
Gas Optimization
- Use
uint256instead ofuint8,uint16, etc., unless packing into structs. - Avoid loops with unbounded length.
- Use
memoryfor read-only arrays,storagefor modifiable state. - Use events to store data that doesn't need to be accessed by smart contracts.
Testing
- Write comprehensive unit tests for all functions.
- Use the MC DevKit for enhanced testing capabilities.
- Implement fuzzing tests for critical functions.
- Test for edge cases and boundary conditions.
Meta Contract (MC) Specific Guidelines
- Use the MC DevKit for state management and testing.
- Follow the UCS (Upgradeable Clone for Scalable Contracts) pattern for upgradeable contracts.
- Use proper storage management techniques to prevent storage conflicts.
Example of MC DevKit usage in tests:
import {MCTest} from "@mc-devkit/Flattened.sol";
contract MyContractTest is MCTest {
function setUp() public {
_use(MyContract.someFunction.selector, address(new MyContract()));
}
function test_someFunction_success() public {
// Test implementation
(bool success, ) = target.call(abi.encodeWithSelector(MyContract.someFunction.selector, arg1, arg2));
assertTrue(success);
}
}
Version Control
- Use descriptive commit messages that explain the purpose of the changes.
- Create feature branches for new developments and use pull requests for code reviews.
- Tag releases with semantic versioning (e.g., v1.0.0, v1.1.0).
Continuous Integration
- Integrate automated testing into the CI/CD pipeline.
- Ensure all tests pass before merging changes into the main branch.
- Use static analysis tools (e.g., Slither, Mythril) as part of the CI process.
Conclusion
By adhering to these coding standards, we ensure consistency, readability, and maintainability across the TextDAO smart contracts. These standards should be followed by all contributors to the project. Regular code reviews and automated linting tools should be used to enforce these standards.
Remember that while these guidelines are important, they should not impede productivity or innovation. Use your judgment and discuss with the team if you believe a deviation from these standards is warranted in a specific case.