13 smart contract modules
Overview
The smart contract layer provides immutable, trustless functionality for project records, credit units, retirement, and governance. This document outlines the minimum viable on-chain set.
Contract Architecture
Core Contracts
ProjectRegistry
CarbonCredit1155
Retirement
Governance
Supporting Contracts
AccessControl
Pausable (optional)
ProjectRegistry Contract
Purpose: Store project records and PoAI anchors
Storage
Functions
mintProjectRecord
Validations:
PoAI hashes must be non-zero
Cap must be > 0
Project must not already exist
Actions:
Creates ProjectRecord
Assigns tokenId
Stores PoAI hashes
Emits
ProjectRecordMintedevent
isPoAIApproved
Returns: true if project has PoAI hashes attached
suspendProject
Actions:
Sets
active = falseEmits
ProjectSuspendedevent
reactivateProject
Actions:
Sets
active = trueEmits
ProjectReactivatedevent
Events
CarbonCredit1155 Contract
Purpose: Semi-fungible credit units (ERC-1155)
Storage
Functions
setProjectConfig
Validations:
ProjectRecord must exist
PoAI must be approved
Cap must be > 0
Actions:
Sets cap, policy, and active status
Emits
ProjectConfiguredevent
mintCredits
Validations:
Project must be active
issued[tokenId] + amountUnits <= cap[tokenId]
Actions:
Mints credits to
toaddressIncrements
issued[tokenId]Emits
CreditsMintedevent
retire
Validations:
balanceOf(msg.sender, tokenId) >= amountUnits
Actions:
Burns credits from
msg.senderIncrements
retired[tokenId]Emits
CreditsRetiredevent
balanceOf
Standard ERC-1155 balance query.
_beforeTokenTransfer
Transfer Policy Enforcement:
If
from == address(0): Mint (allowed)If
to == address(0): Burn (allowed)Otherwise: Check
transferPolicy[tokenId]OPEN: AllowRESTRICTED: Only approved operatorsDISABLED: Revert
Events
Retirement Contract (Optional Separate Contract)
Purpose: Dedicated retirement functionality (can be integrated into CarbonCredit1155)
Functions
retireCredits
Actions:
Calls
CarbonCredit1155.retire()Records retirement reason
Emits
RetirementRecordedevent
Events
Governance Contract
Purpose: DAO voting and proposal execution
Storage
Functions
createProposal
Actions:
Creates proposal
Sets voting window
Emits
ProposalCreatedevent
vote
Validations:
Proposal must be active
Voter must not have voted
Voting window must be open
Actions:
Records vote
Updates vote counts
Emits
VoteCastevent
executeProposal
Validations:
Proposal must be passed
Quorum must be met
Proposal must not be executed
Execution delay must have passed
Actions:
Executes proposal based on type
Marks proposal as executed
Emits
ProposalExecutedevent
Events
Access Control
Purpose: Role-based access control
Roles
Implementation
Use OpenZeppelin's AccessControl or similar:
Role assignment
Role revocation
Role checking
Pausable (Optional)
Purpose: Emergency pause mechanism
Functions
pause
unpause
Integration
Add
whenNotPausedmodifier to critical functionsAllows emergency halt of operations
Critical Enforcement Rules
No Issuance Beyond Cap
No Retirement Beyond Balance
Credits Segregated Per Project
Enforced by
tokenIdseparationCredits of Project A ≠ Credits of Project B
Project Cannot Be Issued Without PoAI
Retirement is Irreversible
Credits are burned (cannot be unminted)
Retirement events are permanent
Contract Interactions
Project Onboarding Flow
Governance → ProjectRegistry.mintProjectRecord()
Governance → CarbonCredit1155.setProjectConfig()
Issuer → CarbonCredit1155.mintCredits()
Retirement Flow
User → CarbonCredit1155.retire()
Event: CreditsRetired
Indexer → Certificate Generation
Governance Flow
Proposer → Governance.createProposal()
Voters → Governance.vote()
Executor → Governance.executeProposal()
Execution → Contract Function Calls
Security Considerations
Reentrancy Protection
Use
nonReentrantmodifierChecks-effects-interactions pattern
Integer Overflow Protection
Use Solidity 0.8+ (built-in overflow protection)
Or use SafeMath library
Access Control
Role-based access
Multi-sig for critical operations (optional)
Upgradeability
Consider upgradeable contracts (Proxy pattern)
Or immutable contracts (simpler, more secure)
Gas Optimization
Storage Optimization
Pack structs efficiently
Use events for historical data
Store only essential data on-chain
Function Optimization
Batch operations where possible
Minimize external calls
Use view functions for reads
Last updated