A hands-on Solidity training ground based on solidity-by-example.org.
This repository contains a comprehensive collection of Solidity smart contracts organized by topic, with full test coverage including unit tests, fuzz tests, and invariant tests where applicable.
solidity-dojo/
├── src/
│ ├── basic/ # Basic Solidity concepts
│ ├── applications/ # Practical applications
│ ├── hacks/ # Common vulnerabilities and solutions
│ ├── evm/ # EVM assembly and low-level operations
│ └── defi/ # DeFi protocol examples
├── test/ # Mirror structure of src/
├── foundry.toml # Foundry configuration
├── Dockerfile # Docker environment setup
└── docker-compose.yml # Docker compose configuration
Prerequisites: Docker Desktop installed and running
# Step 1: Build and start the container (first time only)
docker compose up -d
# Step 2: Run tests directly (no need to enter container)
docker compose exec dojo forge test
# Or enter container shell for interactive use:
docker compose exec dojo bash
# Then inside container:
forge test# Install dependencies
forge install
# Run all tests
forge test# Run all tests
forge test
# Run with verbose output (shows console logs)
forge test -v
# Run specific test file
forge test --match-path test/basic/Counter.t.sol
# Run specific test function
forge test --match-test test_inc_incrementsByOne
# Run tests with gas report
forge test --gas-report
# Run only failed tests from previous run
forge test --rerun
# Increase fuzz runs (default is 256)
forge test --fuzz-runs 1000# Install Foundry
curl -L https://foundry.paradigm.xyz | bash
foundryup
# Install dependencies
forge install
# Run tests
forge test# Run all tests
forge test
# Run tests with verbose output
forge test -v
# Run specific test file
forge test --match-path test/basic/Counter.t.sol
# Run specific test function
forge test --match-test test_inc_incrementsByOne
# Run fuzz tests only (increased runs)
forge test --fuzz-runs 1000See CONCEPTS.md for a Solidity by Example-style reference covering all 109 topics in this dojo. Each entry explains the concept, shows a code snippet, and links directly to the contract and its tests.
| Section | Count | Examples |
|---|---|---|
| Basic | 45 | HelloWorld, Counter, Primitives, Variables, Mapping, Inheritance, Delegatecall, VerifySignature, GasGolf |
| Applications | 18 | ERC20Token, ERC721Token, ERC1155Token, ERC20Permit, MultiSigWallet, TimeLock, UpgradeableProxy, PaymentChannel, MerkleAirdrop |
| DeFi | 16 | ConstantProductAMM, ConstantSumAMM, StableSwapAMM, Vault, StakingRewards, DiscreteStakingRewards, TokenLocker, DutchAuction, CrowdFund |
| Hacks | 20 | Reentrancy, FrontRunning, Honeypot, ArithmeticOverflow, BypassContractSize, WETHPermitAttack, SixtyThreeOver64Rule, OracleManipulation |
| EVM | 10 | AssemblyVariable, AssemblyMath, BitwiseOperators, StorageLayout, MemoryLayout |
Total: 109 contracts with 922 tests
| Check | Scope | Blocks PRs? |
|---|---|---|
| Forge Tests | All contracts | ✅ Yes |
| Slither (clean) | basic/ applications/ defi/ evm/ |
✅ Yes — fails on high severity |
| Slither (hacks) | hacks/ only |
❌ No — vulnerabilities are intentional |
| Codecov | All contracts | ❌ No — informational |
Static analysis results are visible in GitHub Security → Code Scanning. Coverage report on Codecov.
Note on
hacks/: Contracts insrc/hacks/are intentionally vulnerable — they exist to demonstrate attack vectors and exploitation techniques. Slither findings on this folder are expected and do not affect the quality gate.
Each contract includes:
- Unit Tests - Specific scenarios with deterministic inputs
- Fuzz Tests - Random inputs to test across value ranges (where applicable)
- Invariant Tests - Properties that must always hold (for stateful contracts)
All contracts follow NatSpec conventions:
/// @title ContractName
/// @notice Plain English description
/// @dev Technical implementation details
/// @param name Parameter description
/// @return Description of return valueKey gas-saving patterns demonstrated across the repo:
constantandimmutablefor compile-time values (~3 gas vs ~2100 for storage)calldatainstead ofmemoryfor external function parameters- Short-circuiting in boolean expressions
- Assembly for performance-critical operations (see
src/evm/*) - Storage caching, custom errors, and unchecked loop increments in many contracts
Dedicated gas optimization topics:
src/basic/Gas.sol— measuresgasleft()for storage writes, reads, and pure computation; introduces EIP‑1559 concepts.src/basic/UncheckedMath.sol— shows how 0.8+ overflow checks work and whenuncheckedis safe and cheaper, with tests comparing checked vs unchecked loops.src/basic/GasGolf.sol— side‑by‑side unoptimized vs optimized implementation of the same function (memory vs calldata, cached.length, custom errors, unchecked increments) with tests asserting the optimized version uses less gas.src/applications/MultiCall.sol— demonstrates batching multiple calls in one transaction to amortize the 21,000 gas base cost.
Recommended external references for gas optimization:
- Solidity docs — optimizer & storage layout
- EVM opcodes and gas costs
- RareSkills — 80+ gas optimization tips
- Cyfrin — Solidity gas efficiency on L2s
The internal Cursor skill at .cursor/skills/gas-optimization/SKILL.md is used to keep examples in this repo aligned with up‑to‑date best practices (storage caching, transient storage, via-ir, batch patterns, etc.).
Security best practices implemented:
- Checks-Effects-Interactions (CEI) pattern
- Reentrancy guards
- Proper error handling with custom errors
- Access control modifiers
- Input validation
This is a training repository. To add new contracts:
- Create the contract in
src/<section>/ContractName.sol - Create tests in
test/<section>/ContractName.t.sol - Follow the NatSpec documentation standard
- Include unit tests for all functions
- Add fuzz tests where applicable
- Add invariant tests for stateful contracts
- Solidity by Example
- Foundry Documentation
- Solidity Documentation
- CI.md — full documentation of the quality gate setup (Slither, Codecov, Forge)
MIT
