Grading Scale
| Grade | Range |
|---|---|
| Distinction | 90-100% |
| Merit | 80-89% |
| Pass | 70-79% |
| Fail | Below 70% |
Week 1 Homework: Encrypted Calculator
Due: End of Week 1Covers: Modules 00-04
Estimated Time: 3-4 hours
Specification
Build anEncryptedCalculator.sol contract that:
- Stores two encrypted values (
euint32 aandeuint32 b) per user - Provides
setA(uint32)andsetB(uint32)functions to set values from plaintext - Implements these operations, each returning and storing the result:
add()→ a + bsubtract()→ a - bmultiply()→ a * bdivide()→ a / b (plaintext divisor)compare()→ returns ebool (a > b)minimum()→ min(a, b)bitwiseAnd()→ a AND b
- Each result is stored in a
euint32 lastResultwith proper ACL - Emits
OperationPerformed(address indexed user, string operation)event - Inherits
ZamaEthereumConfig
Required Tests (minimum 10)
- Test each of the 7 operations with known values
- Test ACL: verify sender has access to results
- Test divide by 1 (identity)
- Test compare with equal values
Grading Rubric
| Criteria | Weight | Description |
|---|---|---|
| Functionality | 40% | All 7 operations work correctly with encrypted values |
| Code Quality | 20% | Clean imports, proper naming, NatSpec comments |
| Testing | 25% | Minimum 10 tests, each operation tested, edge cases |
| ACL Management | 15% | Every new ciphertext has FHE.allowThis() + FHE.allow() |
Submission Checklist
Contract compiles with
npx hardhat compileAll tests pass with
npx hardhat testNo unused imports
Events emitted for each operation
ACL set on every result
Week 2 Homework: Encrypted Vault with Access Control
Due: End of Week 2Covers: Modules 05-09
Estimated Time: 4-5 hours
Specification
Build aSecureVault.sol contract that:
- Allows users to deposit encrypted amounts using
externalEuint64+inputProof - Allows users to withdraw encrypted amounts with no-revert pattern
- Owner can set an encrypted daily withdrawal limit per user
- Withdrawal checks BOTH: sufficient balance AND within limit
- Owner can grant read access to a third party for any user’s balance
- Includes a
generateLuckyNumber()function usingFHE.randEuint32() - Users can make their own balance publicly decryptable via
FHE.makePubliclyDecryptable() - Emits events:
Deposited,Withdrawn,LimitSet,AccessGranted
Required Tests (minimum 12)
- Deposit with encrypted input and verify balance
- Withdraw within balance (succeeds)
- Withdraw over balance (silently sends 0, no revert)
- Withdraw over limit (silently sends 0)
- Owner sets withdrawal limit
- Non-owner cannot set limit
- Grant access to third party
- Generate random number
- Make balance publicly decryptable
- Multi-user isolation
- Deposit + withdraw + verify remaining balance
- Double deposit accumulation
Grading Rubric
| Criteria | Weight | Description |
|---|---|---|
| Functionality | 35% | All features work: deposit, withdraw, limits, access grant, randomness |
| Security Patterns | 25% | No-revert pattern on withdraw. FHE.select used. Input validation |
| Testing | 25% | Minimum 12 tests. Silent failure cases verified |
| Code Quality | 15% | Clean code, proper event emission, NatSpec |
Submission Checklist
Contract compiles
All tests pass
No revert on insufficient balance/limit (FHE.select pattern)
FHE.fromExternal used for all external inputs
FHE.isInitialized check after fromExternal
Events emitted for all state changes
Week 3 Homework: Confidential Token + Voting System
Due: End of Week 3Covers: Modules 10-14
Estimated Time: 5-6 hours
Specification
Build TWO contracts that work together:Contract 1: ConfidentialToken.sol
A simplified confidential ERC-20 with:
- Encrypted balances (
mapping(address => euint64)) mint(address to, uint64 amount)— owner onlytransfer(externalEuint64 encAmount, bytes calldata inputProof, address to)— with no-revert patternbalanceOf(address)returnseuint64handle- No amount in
Transferevent (only from, to) - Total supply tracked as public
uint64
Contract 2: TokenVoting.sol
An encrypted voting system:
- References the ConfidentialToken contract
createProposal(string description, uint256 durationSeconds)— owner onlyvote(uint256 proposalId, externalEuint64 encVote, bytes calldata inputProof)— vote weight = 1- Encrypted
yesVotesandnoVotestallies per proposal finalizeProposal(proposalId)— after deadline, makes tallies publicly decryptable- Duplicate vote prevention per proposal per address
Required Tests (minimum 15)
- Token: mint, transfer success, transfer fail (silent), balance check
- Token: transfer to self, transfer zero
- Voting: create proposal, cast yes vote, cast no vote
- Voting: prevent double vote
- Voting: finalize after deadline
- Voting: reject finalize before deadline
- Voting: reject non-owner proposal creation
- Integration: mint tokens then vote
- Multi-user: 3 users vote, verify tally
- Edge case: vote on non-existent proposal
Grading Rubric
| Criteria | Weight | Description |
|---|---|---|
| Functionality | 35% | Both contracts work correctly |
| Architecture | 20% | Clean separation between token and voting |
| Testing | 25% | Minimum 15 tests. Integration tests included |
| Security | 20% | No-revert on transfer. Duplicate vote prevention. ACL on all handles |
Submission Checklist
Both contracts compile
All tests pass
No amounts in events
No revert on insufficient token balance
Duplicate vote prevention works
Tallies only decryptable after finalization
ACL correct on all handles
Week 4 Homework: Capstone — Confidential DAO
Due: End of Week 4Covers: Modules 15-19
Estimated Time: 8-10 hours
Specification
Build a complete Confidential DAO system:Contract 1: GovernanceToken.sol
- Encrypted ERC-20 governance token
- Minting, encrypted transfers with no-revert pattern
delegate(address)— delegate voting power- Gas-optimized: use plaintext operands where possible
Contract 2: DAO.sol
createProposal(string description, uint256 amount, address recipient, uint256 duration)castVote(uint256 proposalId, externalEuint64 encSupport, bytes calldata inputProof)— encrypted yes/no vote- Encrypted tallies (
euint64 yesVotes,euint64 noVotes) finalizeProposal(proposalId)— after deadline, make tallies publicly decryptableexecuteProposal(proposalId)— if yes > no, transfer ETH from treasuryreceive()— accept ETH donations to treasury- Duplicate vote prevention
- LastError pattern for vote feedback
Security Requirements (MANDATORY)
FHE.isInitialized() check on all external inputs
No branching on encrypted conditions (use FHE.select only)
ACL on every new ciphertext handle
No amounts in events
Input validation on all public functions
Required Tests (minimum 20)
- GovernanceToken: mint, transfer, delegate
- DAO: create proposal, cast yes, cast no
- DAO: prevent double vote
- DAO: finalize after deadline, reject before
- DAO: execute passing proposal (treasury transfer)
- DAO: reject execution of failing proposal
- DAO: accept treasury funding
- Security: non-owner cannot create proposals
- Security: non-owner cannot mint
- Integration: full lifecycle (mint -> fund treasury -> propose -> vote -> finalize -> execute)
- Multi-user: 3+ voters with different votes
- Edge cases: vote on non-existent proposal, execute before finalize, empty treasury
Grading Rubric
| Criteria | Weight | Description |
|---|---|---|
| Functionality | 30% | Complete DAO lifecycle works |
| Security | 25% | All security requirements met. No information leakage |
| Testing | 20% | Minimum 20 tests. Full lifecycle tested |
| Code Quality | 15% | Gas-optimized. Clean architecture. NatSpec |
| Documentation | 10% | README explaining architecture and security |
Submission Checklist
Both contracts compile
All 20+ tests pass
Full lifecycle works end-to-end
All security requirements met
Gas optimizations applied
Events emit no sensitive data
README with architecture explanation
Submission Guidelines
Format
Each homework should be submitted as:- Solidity contract(s) in
contracts/ - Test file(s) in
test/ - All tests passing with
npx hardhat test
Late Policy
- On time: full credit
- 1 day late: maximum 90%
- 2 days late: maximum 80%
- 3+ days late: maximum 70%
Academic Integrity
- You may reference the bootcamp’s example contracts and lesson materials
- You may use the Zama documentation
- All code must be your own work
- AI-assisted code is acceptable but must be reviewed and understood by the student