DAO Constitution Contract
What it does:
Defines the fundamental rules, governance structure, and operational procedures of a DAO in a transparent and immutable way.
Why it matters:
Ensures clarity on member rights, decision-making processes, proposal approvals, and dispute resolution, reducing ambiguity and conflicts in DAO operations.
How it works:
-
DAO founders define a constitution including voting rules, quorum, and member rights
-
Constitution text and metadata are stored on-chain for immutability
-
Smart contract enforces core governance rules like proposal submission and voting eligibility
-
Amendments can be proposed and approved through on-chain voting
-
Members’ roles and privileges are managed according to the constitution
-
Public access to the constitution ensures accountability and transparency
-
Integration with treasury, proposals, and other DAO modules is enabled
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "@openzeppelin/contracts/access/Ownable.sol";
/**
* @title DAOConstitution
* @author Nam
* @notice On-chain constitution and governance framework for a DAO
*/
contract DAOConstitution is Ownable {
string public constitutionURI; // IPFS/Arweave link to full constitution
uint256 public amendmentCount;
struct Amendment {
string description;
string amendmentURI;
uint256 votesFor;
uint256 votesAgainst;
bool executed;
}
mapping(uint256 => Amendment) public amendments;
mapping(address => uint256) public votingPower;
mapping(address => mapping(uint256 => bool)) public hasVoted;
// -------------------- EVENTS --------------------
event ConstitutionUpdated(string constitutionURI);
event AmendmentProposed(uint256 indexed amendmentId, string description);
event Voted(uint256 indexed amendmentId, address voter, bool support);
event AmendmentExecuted(uint256 indexed amendmentId);
// -------------------- CONSTRUCTOR --------------------
constructor(string memory _constitutionURI) {
constitutionURI = _constitutionURI;
}
// -------------------- VOTING POWER MANAGEMENT --------------------
function setVotingPower(address _member, uint256 _power) external onlyOwner {
votingPower[_member] = _power;
}
// -------------------- AMENDMENTS --------------------
function proposeAmendment(string calldata _description, string calldata _amendmentURI) external {
amendmentCount += 1;
amendments[amendmentCount] = Amendment({
description: _description,
amendmentURI: _amendmentURI,
votesFor: 0,
votesAgainst: 0,
executed: false
});
emit AmendmentProposed(amendmentCount, _description);
}
// -------------------- VOTING --------------------
function voteOnAmendment(uint256 _amendmentId, bool _support) external {
require(votingPower[msg.sender] > 0, "No voting power");
require(!hasVoted[msg.sender][_amendmentId], "Already voted");
Amendment storage a = amendments[_amendmentId];
require(!a.executed, "Already executed");
if (_support) {
a.votesFor += votingPower[msg.sender];
} else {
a.votesAgainst += votingPower[msg.sender];
}
hasVoted[msg.sender][_amendmentId] = true;
emit Voted(_amendmentId, msg.sender, _support);
}
// -------------------- EXECUTION --------------------
function executeAmendment(uint256 _amendmentId) external {
Amendment storage a = amendments[_amendmentId];
require(!a.executed, "Already executed");
require(a.votesFor > a.votesAgainst, "Not approved");
a.executed = true;
constitutionURI = a.amendmentURI;
emit AmendmentExecuted(_amendmentId);
emit ConstitutionUpdated(a.amendmentURI);
}
}