Programmable Society Protocol is an EIP-5192 compliant Soulbound Token (SBT) system designed for decentralized education. It manages the entire lifecycle of a student's on-chain identity, from enrollment (Gray Badge) to graduation (Gold Badge), featuring Role-Based Access Control (RBAC), storage-optimized architecture, and property-based security testing.
- Soulbound Identity (EIP-5192): Tokens are non-transferable, ensuring the integrity of credentials.
- Smart Storage Architecture:
- Union Field Layout: Optimizes gas by sharing storage slots between Faculty (IPFS Hash) and Students (Grades).
- Dual Counter System: Separates global Token IDs from student file mappings. Ensures valid "Gold Badge" metadata (e.g.,
1.json) is only assigned upon certification, preventing metadata gaps.
- Dynamic Metadata:
- Enrolled: Students start with a global "Gray Badge" (Gas Optimized).
- Certified: Upon completion, the badge URI dynamically switches to a folder-based mapping (e.g.,
.../1.json) without minting a new token.
- Role-Based Access Control (RBAC):
- Owner: Manages Faculty (Teachers/TAs).
- Faculty: Manages Student enrollment and certification.
- Student: Passive receiver with "Right to be Forgotten" (Self-burn).
- Security First: Verified with both Unit Tests (Hardhat) and Fuzzing/Invariant Tests (Foundry).
- Language: Solidity v0.8.20
- Framework: Hardhat (Deployment) & Foundry (Fuzzing)
- Testing:
- Chai & Ethers.js (100% Statement Coverage)
- Forge (Property-based Fuzzing)
- Network: Polygon Amoy (Testnet) & Polygon Mainnet
- Storage: IPFS (via Pinata)
- Node.js (v16+)
- Foundry (for Fuzz testing)
- MetaMask Wallet (with POL/MATIC)
- Etherscan API Key (V2)
git clone https://github.com/bmhtsx/programmable-society-protocol.git
cd programmable-society-protocol
# Install Node dependencies
npm install
# Install Foundry dependencies
forge installCreate a .env file in the root directory:
# Your Wallet Private Key (No 0x prefix)
PRIVATE_KEY=your_private_key_here
# Etherscan V2 API Key (For verification on Polygon)
ETHERSCAN_API_KEY=your_etherscan_api_key
# (Optional) Contract Address - Filled after deployment
CONTRACT_ADDRESS=This project employs a hybrid testing strategy to ensure both logic correctness and security robustness.
Covers standard logic flows, RBAC, and storage layout.
npx hardhat test
# Check coverage
npx hardhat coverageStatus: 100% Statement Coverage.
Uses property-based testing to verify security invariants under thousands of random inputs.
Key Invariants Tested:
- Abuse of Power: Non-faculty addresses can never certify students.
- Lifecycle Integrity: Internal IDs (Gold Badge mapping) are only assigned after certification.
- Privilege Degradation: Revoked Faculty members immediately lose all permissions.
Run Fuzz tests:
forge testUpload your metadata to IPFS (e.g., Pinata):
- Default Gray Badge: A single image CID.
- Gold Badge Folder: A folder containing sequential JSONs (
1.json,2.json...).
Deploy to Polygon Amoy Testnet.
- Open
scripts/deploy.jsand updateDEFAULT_STUDENT_HASHandSTUDENT_GOLD_FOLDER_HASH(Raw CIDs). - Run:
npx hardhat run scripts/deploy.js --network amoy
- Update
.env: Copy the deployed address toCONTRACT_ADDRESSin your.envfile.
Add Teachers and TAs to the system.
- Open
scripts/1_setup_faculty.jsto configure addresses. - Run:
npx hardhat run scripts/1_setup_faculty.js --network amoy
Batch enroll students. They receive the default Gray Badge.
- Open
scripts/2_enroll_students.jsto configure student list. - Run:
npx hardhat run scripts/2_enroll_students.js --network amoy
Grade a student. This action increments the internal counter and assigns the next available Gold JSON file.
- Open
scripts/3_certify_student.js. - Set
studentTokenIdandgrade. - Run:
npx hardhat run scripts/3_certify_student.js --network amoy
| Role | Permissions | Data Structure (Union Field) |
|---|---|---|
| Owner | addFaculty, setFolderHash |
N/A |
| Faculty | enroll, certify, revoke |
data stores Personal IPFS Hash |
| Student | burn (Self-destruct) |
data stores Academic Grade |