Sitelet https://github.com/Blockchains/blockchainlab-labs
Skip to content

Repository files navigation

Blockchain Lab — hands-on smart-contract labs

Blockchain Lab Labs

ci

54 runnable labs — 45 Solidity labs with Foundry tests, 4 Noir zero-knowledge labs and 4 Cairo/Starknet labs — from storage basics to reentrancy, flash loans, proxies, ERC-7201, fuzzing, invariants and mainnet forks — plus a bonus Hardhat lab. Every lab compiles and passes in CI.

Built by Blockchain Lab — blockchainlab.com

Run

git clone --recursive https://github.com/Blockchains/blockchainlab-labs && cd blockchainlab-labs
curl -L https://foundry.paradigm.xyz | bash && foundryup     # if you don't have Foundry
forge test                          # all 45 Solidity labs (131 tests)
forge test --match-path test/L09*   # one lab
forge test --match-path test/L29* -vv   # mainnet fork lab (uses https://ethereum-rpc.publicnode.com or MAINNET_RPC_URL)
cd hardhat && npm ci && npx hardhat test   # bonus Hardhat lab

Labs

# Lab You learn Exercise Blockchain Lab
01 SimpleStorage · test State variables, storage slot 0, first fuzz test Add a uint256[] history and push every value; assert its length. read · tool
02 Counter · test Events, custom errors, vm.expectEmit / expectRevert Add reset() restricted to the deployer. read · tool
03 Ownable · test Access control, two-step ownership Add a renounceOwnership with a 2-day delay. read
04 ERC20Scratch · test ERC-20 from first principles, infinite allowance Add increaseAllowance and a test for the approve front-running problem. read · tool
05 OZToken · test OpenZeppelin ERC20Capped + AccessControl roles Add a PAUSER_ROLE using ERC20Pausable. read
06 NFT · test ERC-721 paid mint, supply cap, tokenURI Add a Merkle-gated presale (combine with lab 11). read · tool
07 MultiToken · test ERC-1155 fungible + non-fungible items, batch transfer Add a crafting function that burns 100 GOLD to mint a SWORD. read
08 EtherVault · test receive(), checks-effects-interactions, pull payments Add a per-user daily withdrawal limit. read
09 Reentrancy · test Reentrancy exploit end-to-end and two fixes Write a cross-function reentrancy variant and fix it. read
10 Arithmetic · test Checked vs unchecked maths, rounding direction Find an input where rounding the wrong way lets a user extract value. read · tool
11 MerkleAirdrop · test OpenZeppelin StandardMerkleTree allowlist claim Build your own tree in the Tools hash page and claim with it. read · tool
12 Permit · test EIP-2612 / EIP-712 typed signatures, replay & expiry Implement a depositWithPermit vault. read · tool
13 Signatures · test EIP-191 signed vouchers, ecrecover via ECDSA, nonces Add an expiry and show signature malleability is handled by ECDSA. read
14 MultiSig · test M-of-N wallet: submit / confirm / execute Add revoke-confirmation and owner rotation via self-call. read
15 Timelock · test Queued governance actions with delay and grace Add cancel() and emit events for off-chain monitoring. read
16 CommitReveal · test Hiding choices to resist front-running Add a deposit that is slashed if a committer never reveals. read · tool
17 DutchAuction · test Linear price decay, refunds Make the decay exponential and compare gas. read
18 EnglishAuction · test Bidding with pull refunds (DoS-safe) Add anti-sniping: extend the end time on late bids. read
19 Crowdfund · test SafeERC20, goals, deadlines, refunds Support fee-on-transfer tokens correctly. read
20 StakingRewards · test Reward-per-token accumulator (Synthetix pattern) Add a reward period end and notifyRewardAmount. read
21 ConstantProductAMM · test x·y=k swaps, 0.3% fee, LP shares, slippage Add a TWAP price oracle accumulator. read
22 FlashLoan · test ERC-3156 flash lender and borrower Use a flash loan to arbitrage two lab-21 pools. read · tool
23 UpgradeableProxy · test UUPS + ERC-1967 proxy, initialisers, upgrade auth Add a storage-collision bug in V2 and catch it with a test. read · tool
24 NamespacedStorage · test ERC-7201 namespaced storage layout Add a second namespace and prove they never collide. read · tool
25 StorageLayout · test Packing, mappings, arrays, short strings via vm.load Store a 40-byte string and decode the long-string layout. read · tool
26 GasOptimisation · test Packing, caching, calldata, unchecked loops Run forge snapshot and cut another 10%. read · tool
27 FuzzMath · test Property-based fuzzing finds a precision bug Write a fuzz test that fails on afterFeeBuggy. read
28 InvariantVault · test Stateful invariant testing with a handler + ghost vars Introduce a bug in withdraw and watch the invariant catch it. read
29 MainnetFork · test Fork tests against real USDC / WETH via public RPC Fork Base and test real Base USDC. read · tool
30 Create2Factory · test CREATE2 deterministic deployment and address prediction Predict the address off-chain with ethers getCreate2Address. read · tool
31 ERC4626Vault · test ERC-4626 vaults and the first-depositor inflation attack vs virtual shares Show the attack is still possible with offset 0 and a bigger donation, and compute its cost. read
32 Governance · test OZ Governor + ERC20Votes + TimelockController full lifecycle Add GovernorPreventLateQuorum and test a late whale vote. read
33 Vesting · test VestingWalletCliff: cliff + linear release Make a factory that deploys one vesting wallet per employee. read
34 PaymentSplitter · test Pull-based revenue splits for ETH and ERC-20 Add a shareholder via a 2-of-3 vote. read
35 Royalties · test ERC-2981 default and per-token royalties Add a marketplace that pays royalties on sale. read · tool
36 Soulbound · test ERC-5192 non-transferable credentials Add issuer revocation with an event. read
37 OracleConsumer · test Chainlink AggregatorV3 consumer: staleness, decimals, bad answers Add an L2 sequencer-uptime feed check. read · tool
38 TransientStorage · test EIP-1153 TSTORE/TLOAD reentrancy lock Compare gas with an SSTORE-based guard using forge snapshot. read · tool
39 SmartAccount · test Meta-transactions and ERC-1271 contract signatures Add a session key with an expiry and a spend limit. read · tool
40 MinimalProxy · test EIP-1167 clones, initializer locking, deterministic addresses Measure deploy gas for clone vs full deploy in a script. read · tool
41 Sandwich · test MEV sandwich on an AMM, and slippage limits as the defence Find the largest victim trade 0.5% slippage still protects. read · tool
42 SpotOracleLending · test Spot-price oracle manipulation leading to over-borrowing Replace the spot price with a TWAP and re-run the attack. read · tool
43 CrossChainReplay · test Signature replay across chains/contracts; EIP-712 domain binding Add a deadline and test expiry. read · tool
44 YulBasics · test Inline assembly: sload/sstore, calldata loops, scratch-space hashing Write transfer for an ERC-20 entirely in Yul. read
45 CircuitBreaker · test Guardian pause + per-window outflow rate limit Allow the rate limit to be raised only through the timelock (lab 15). read
H1 Counter (Hardhat) · test Same contract as lab 02, tested with Hardhat + ethers + chai Port lab 04 to Hardhat read
N1 Noir: hash preimage ZK proof of knowledge of a Pedersen preimage Switch to Poseidon via the noir-lang/poseidon library. read
N2 Noir: age check Selective disclosure: prove age ≥ 18 from a committed credential Add an expiry date to the credential. read
N3 Noir: Merkle membership Anonymous allowlist membership + nullifier (Semaphore pattern) Raise depth to 20 and measure constraint count with nargo info. read
N4 Noir: proof of reserves Prove committed balances ≥ liabilities without revealing them Add per-account non-negativity and a Merkle sum tree. read
C1 Cairo: integers & felts felt252 modular wrap vs panicking uN integers, u256 limbs Implement checked u256 sqrt. read
C2 Cairo: ownership & traits Linear types, snapshots, arrays, structs, traits Add a short-position variant with an enum. read
C3 Cairo: Starknet token Starknet contract storage, events, dispatcher tests with deploy_syscall Add approve/transfer_from. read
C4 Cairo: Poseidon Merkle STARK-friendly Poseidon hashing and sorted-pair Merkle proofs Write an airdrop contract that uses verify. read

Each lab = one contract in src/ and one test in test/. Read the test first — it is the spec. Then do the exercise and make your new test pass.

Stack

Foundry (forge-std v1.17), Solidity 0.8.28 (Cancun), OpenZeppelin Contracts v5.4.0, Hardhat 2 for the bonus lab. Noir 1.0.0-rc.2 for ZK labs, Scarb 2.20.1 / Cairo 2.20 for Starknet labs. Run cd noir && nargo test or cd cairo && scarb test. Sui Move and Anchor (Solana) labs are planned.

Where next

Educational code — not audited, do not deploy to mainnet with real funds. MIT.

Use as a building block

For AI agents and builders: read AGENTS.md (setup, commands, structure, rules), llms.txt (doc map) and the machine-readable blocks.json (schema). How all Blockchains blocks fit together: Build with Blocks · org catalogue: https://blockchains.github.io/blocks.json.

What it exports

Export Type Install / access
src/L<NN>_<Name>.sol solidity forge install Blockchains/blockchainlab-labs
noir/ file cd noir && nargo test
cairo/ file cd cairo && scarb test

Minimal example (compiled and passed forge test on 2026-10-04 in a fresh Foundry project)

// forge install Blockchains/blockchainlab-labs
// remappings.txt:
//   @openzeppelin/contracts/=lib/blockchainlab-labs/lib/openzeppelin-contracts/contracts/
//   labs/=lib/blockchainlab-labs/src/
import {ConstantProductAMM} from "labs/L21_ConstantProductAMM.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";

ConstantProductAMM amm = new ConstantProductAMM(IERC20(tokenA), IERC20(tokenB));
// approve both tokens, then:
amm.addLiquidity(1000e18, 1000e18);
uint256 out = amm.swap(IERC20(tokenA), 10e18, 0);   // ≈ 9.87e18 after 0.3% fee + price impact

Inputs → outputs

  • In: lab contract (Solidity source) constructor args per lab
  • Out: tested contract patterns (Solidity/Noir/Cairo); exercises (Markdown table in README)

Composes with

Versioning & stability: stable. Teaching code: lab file names (L<NN>_<Name>.sol) are stable, internals may change to improve clarity. Not audited; do not deploy with real value without review.

Configuration

No keys needed. MAINNET_RPC_URL optionally overrides the public RPC (https://ethereum-rpc.publicnode.com) used by the mainnet fork lab (test/L29_MainnetFork.t.sol).

Licence

MIT, see LICENSE.

Contributing

Issues and pull requests are welcome. Please read the contributing guide, code of conduct and security policy first.


Built by Blockchain Lab — blockchainlab.com

About

54 runnable blockchain labs: 45 Solidity/Foundry (security, DeFi, MEV, governance, Yul), 4 Noir ZK and 4 Cairo/Starknet labs — all tested in CI

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages