Thank you for your interest in contributing to Mesh Contract! This document outlines the process for contributing to the smart contract layer of the ThinkMesh ecosystem.
- Code of Conduct
- Getting Started
- Development Workflow
- Smart Contract Standards
- Testing Requirements
- Pull Request Process
- Security
This project adheres to a code of conduct. By participating, you agree to uphold these values:
- Respectful collaboration — All contributors deserve respect
- Quality over quantity — We value well-tested, documented code
- Security first — Smart contracts handle real funds; safety is non-negotiable
- Node.js >= 18.0.0
- npm or yarn
- Git
# Fork and clone
git clone https://github.com/YOUR_USERNAME/mesh-contract.git
cd mesh-contract
# Install dependencies
npm install
# Set up environment
cp .env.example .env
# Fill in .env with your testnet private key and RPC URLs
# Compile to verify setup
npm run compile
# Run tests to confirm everything works
npm testfeat/description-of-feature
fix/description-of-fix
docs/what-you-are-documenting
test/what-you-are-testing
chore/maintenance-task
- Create a branch from
main - Write your code with NatSpec documentation
- Write tests (coverage must stay above 95%)
- Run the full test suite:
npm test - Run static analysis:
npm run slither(if available) - Open a Pull Request
All public and external functions must include NatSpec:
/// @title ThinkToken
/// @notice ERC-20 reward token for ThinkMesh contributors
/// @dev Mintable by authorized roles only; implements ERC-20 + ERC-20Permit
contract ThinkToken {
/// @notice Mint tokens to a contributor address
/// @dev Only callable by MINTER_ROLE
/// @param to The recipient address
/// @param amount The amount of tokens to mint (18 decimals)
function mint(address to, uint256 amount) external onlyRole(MINTER_ROLE) {
_mint(to, amount);
}
}- Use OpenZeppelin Contracts v5 where possible
- Follow Solidity Style Guide
- Use
^0.8.20pragma minimum - Prefer
custom errorsoverrequirestrings for gas efficiency - Use
SafeERC20for token transfers
- ✅ Use
ReentrancyGuardfor functions handling ETH/tokens - ✅ Use
AccessControlorOwnablefor privileged functions - ✅ Use
Pausablefor emergency stops - ✅ Use OpenZeppelin's
Address.sendValuenot raw.call - ❌ Never use
tx.originfor authentication - ❌ Never store sensitive data on-chain
Coverage must remain above 95%. Run:
npm run coverageEach contract should have a corresponding test file:
test/
├── ThinkToken.test.ts
├── ReputationRegistry.test.ts
├── ImpactNFT.test.ts
├── MeshDAO.test.ts
└── BountyEscrow.test.ts
For every function, cover:
- ✅ Happy path (success)
- ✅ Access control (unauthorized callers revert)
- ✅ Edge cases (zero amounts, max values)
- ✅ Events emitted
- ✅ State changes verified
- Fill out the PR template completely
- Link the relevant issue using
Closes #issue-number - Ensure CI passes — all checks must be green
- Request review from at least one core contributor
- Address all review comments before merge
- NatSpec documentation on all new public/external functions
- Tests written and passing (
npm test) - Coverage stays above 95% (
npm run coverage) - No compiler warnings
-
.env.exampleupdated if new env vars added -
CHANGELOG.mdupdated (for non-trivial changes)
Do NOT open public GitHub issues for security vulnerabilities.
Email: security@thinkmesh.io
Include:
- Description of the vulnerability
- Steps to reproduce
- Potential impact
- Suggested fix (optional)
We will respond within 48 hours and coordinate responsible disclosure.
A formal bug bounty program is coming. For now, critical vulnerabilities discovered before mainnet launch will be acknowledged with THINK token grants upon launch.
We use Mozilla Fluent for managing puzzle text, CLI prompts, hints, error messages, and TUI labels. Contributors can easily add support for new languages without modifying game logic.
-
Locate the locales directory: Navigate to
contracts/puzzle/locales/. -
Create a new
.ftlfile: Name your file using standard ISO 639-1 language codes (e.g.,de.ftlfor German,ja.ftlfor Japanese,pt.ftlfor Portuguese). -
Copy and translate keys: Copy string definitions from
contracts/puzzle/locales/en.ftland translate values into your target language. Preserve variable parameters like{$lang}or{$code}.Example (
de.ftl):welcome-title = Willkommen zur Mesh-Rätsel-Herausforderung! puzzle-prompt = Lösen Sie das Rätsel: Finden Sie den versteckten Hash-Schlüssel.
-
Register the locale in
contracts/puzzle/src/lib.rs: Add the locale code and resource file mapping to theLOCALESarray:const LOCALES: &[(&str, &str)] = &[ ("en", include_str!("../locales/en.ftl")), ("fr", include_str!("../locales/fr.ftl")), ("es", include_str!("../locales/es.ftl")), ("de", include_str!("../locales/de.ftl")), // <-- Add your new locale here ];
-
Test your new locale: Run the CLI with your locale code:
cargo run -p mesh-puzzle -- --lang de
If any keys are missing in your translation file, the i18n system automatically falls back to English (en).
If you find this project valuable, consider funding it through Drips. Wave 1 is active — your streaming contribution helps us ship audited contracts faster.
Thank you for helping build the on-chain backbone of collaborative problem solving! 🚀