Governace Contract

// Governance Contract : Built By DAO V 0.01.0
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.28;

import "@openzeppelin/contracts/access/AccessControl.sol";
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC721/IERC721.sol";

contract GovernanceContract is AccessControl, ReentrancyGuard {
    bytes32 public constant PROPOSER_ROLE = keccak256("PROPOSER_ROLE");
    bytes32 public constant LEADERSHIP_ROLE = keccak256("LEADERSHIP_ROLE");
    bytes32 public constant FOUNDER_DIRECTOR_ROLE = keccak256("FOUNDER_DIRECTOR_ROLE");

    IERC20 public bltbyToken;
    IERC721 public membershipNFT;
    IERC721 public investorNFT;

    uint256 public proposalCounter;
    uint256 public constant STAKE_AMOUNT = 2 * 10 ** 18; // 2 BLTBY tokens

    struct Proposal {
        uint256 id;
        address proposer;
        string description;
        uint256 creationTime;
        uint256 endTime;
        uint8 category; // 0 = Standard, 1 = Critical, 2 = Judicial
        bool resolved;
        bool vetoed;
        mapping(uint256 => uint8) rankedVotes; // Maps NFT ID to rank choice
        uint256 totalVotes;
        uint256 leadershipVotes;
        uint256 yesVotes;
        uint256 noVotes;
    }

    mapping(uint256 => Proposal) public proposals;
    mapping(address => uint256) public stakedBLTBY; // Tracks BLTBY tokens staked for proposal submissions

    event ProposalCreated(uint256 proposalId, address proposer, string description, uint256 endTime);
    event Voted(uint256 proposalId, address voter, uint256 nftId, uint8 vote);
    event ProposalResolved(uint256 proposalId, bool approved);
    event ProposalVetoed(uint256 proposalId);

    error Unauthorized();
    error AlreadyVoted(uint256 proposalId);
    error ProposalNotFound(uint256 proposalId);
    error InvalidCategory(uint8 category);
    error VotingPeriodOver(uint256 proposalId);
    error InsufficientStake();
    error ProposalAlreadyResolved(uint256 proposalId);
    error LeadershipQuorumNotMet(uint256 proposalId);

    constructor(address _bltbyToken, address _membershipNFT, address _investorNFT) {
        _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);
        _setupRole(FOUNDER_DIRECTOR_ROLE, msg.sender);
        bltbyToken = IERC20(_bltbyToken);
        membershipNFT = IERC721(_membershipNFT);
        investorNFT = IERC721(_investorNFT);
        proposalCounter = 1;
    }

    /**
     * @dev Create a new proposal.
     * Proposers must stake 2 BLTBY tokens to submit a proposal.
     * @param description The proposal description.
     * @param duration The voting duration for the proposal.
     * @param category The category of the proposal (0 = Standard, 1 = Critical, 2 = Judicial).
     */
    function createProposal(string memory description, uint256 duration, uint8 category) external nonReentrant {
        if (!hasRole(PROPOSER_ROLE, msg.sender)) {
            revert Unauthorized();
        }
        if (category > 2) {
            revert InvalidCategory(category);
        }
        if (bltbyToken.balanceOf(msg.sender) < STAKE_AMOUNT) {
            revert InsufficientStake();
        }

        bltbyToken.transferFrom(msg.sender, address(this), STAKE_AMOUNT);
        stakedBLTBY[msg.sender] += STAKE_AMOUNT;

        uint256 proposalId = proposalCounter++;
        Proposal storage newProposal = proposals[proposalId];
        newProposal.id = proposalId;
        newProposal.proposer = msg.sender;
        newProposal.description = description;
        newProposal.creationTime = block.timestamp;
        newProposal.endTime = block.timestamp + duration;
        newProposal.category = category;
        newProposal.resolved = false;
        newProposal.vetoed = false;
        newProposal.totalVotes = 0;
        newProposal.leadershipVotes = 0;

        emit ProposalCreated(proposalId, msg.sender, description, newProposal.endTime);
    }

    /**
     * @dev Vote on a proposal using ranked choice.
     * @param proposalId The ID of the proposal to vote on.
     * @param nftId The ID of the NFT representing the voter.
     * @param vote The rank choice (1 for Yes, 2 for No).
     */
    function vote(uint256 proposalId, uint256 nftId, uint8 vote) external nonReentrant {
        if (block.timestamp > proposals[proposalId].endTime) {
            revert VotingPeriodOver(proposalId);
        }
        if (proposals[proposalId].resolved) {
            revert ProposalAlreadyResolved(proposalId);
        }
        if (!_canVote(msg.sender, nftId)) {
            revert Unauthorized();
        }

        Proposal storage proposal = proposals[proposalId];
        proposal.rankedVotes[nftId] = vote;
        proposal.totalVotes++;

        if (hasRole(LEADERSHIP_ROLE, msg.sender)) {
            proposal.leadershipVotes++;
        }

        emit Voted(proposalId, msg.sender, nftId, vote);
    }

    /**
     * @dev Resolve a proposal by determining if it passed based on votes.
     * Leadership quorum must be met for the proposal to be valid.
     * @param proposalId The ID of the proposal to resolve.
     */
    function resolveProposal(uint256 proposalId) external nonReentrant {
        Proposal storage proposal = proposals[proposalId];
        if (proposal.resolved) {
            revert ProposalAlreadyResolved(proposalId);
        }
        if (proposal.leadershipVotes < _requiredLeadershipQuorum()) {
            revert LeadershipQuorumNotMet(proposalId);
        }

        bool approved = false;
        uint256 approvalThreshold = _getApprovalThreshold(proposal.category);
        if (proposal.totalVotes >= approvalThreshold) {
            approved = true;
        }

        proposal.resolved = true;
        if (approved) {
            stakedBLTBY[proposal.proposer] -= STAKE_AMOUNT;
            bltbyToken.transfer(proposal.proposer, STAKE_AMOUNT);
        }

        emit ProposalResolved(proposalId, approved);
    }

    /**
     * @dev Veto a proposal.
     * Requires the Founding Director and one Leadership Council member.
     * @param proposalId The ID of the proposal to veto.
     */
    function vetoProposal(uint256 proposalId) external nonReentrant onlyRole(FOUNDER_DIRECTOR_ROLE) {
        if (!hasRole(LEADERSHIP_ROLE, msg.sender)) {
            revert Unauthorized();
        }

        Proposal storage proposal = proposals[proposalId];
        proposal.vetoed = true;
        proposal.resolved = true;
        emit ProposalVetoed(proposalId);
    }

    /**
     * @dev Helper function to determine if an address can vote with a given NFT ID.
     * @param voter The address of the voter.
     * @param nftId The ID of the NFT to verify voting rights.
     * @return True if the voter is authorized to vote, otherwise false.
     */
    function _canVote(address voter, uint256 nftId) internal view returns (bool) {
        return (membershipNFT.ownerOf(nftId) == voter || investorNFT.ownerOf(nftId) == voter);
    }

    /**
     * @dev Helper function to determine the required leadership quorum.
     * @return The required leadership votes for a proposal to be valid.
     */
    function _requiredLeadershipQuorum() internal view returns (uint256) {
        // Placeholder: Define the quorum logic
        return 2; // For demonstration, at least two leadership votes are needed
    }

    /**
     * @dev Helper function to get the approval threshold based on the category.
     * @param category The category of the proposal.
     * @return The approval threshold.
     */
    function _getApprovalThreshold(uint8 category) internal pure returns (uint256) {
        if (category == 0) return 50;
        if (category == 1) return 60;
        if (category == 2) return 65;
        return 100;
    }
}

/*
 Key Features:
 - Proposal-based governance with ranked choice voting.
 - Only NFT holders can vote; BLTBY tokens are staked for submitting proposals but not used directly for voting power.
 - Proposals must reach a quorum from Leadership Council votes to be resolved.
 - Proposal staking mechanism requires proposers to stake 2 BLTBY tokens.
 - Founding Director plus a Leadership Council member can veto proposals.
 - Weighted voting for NFT holders, independent voting roles for members holding multiple NFTs.
*/

The Governance Contract is a cornerstone of the Built By DAO ecosystem, providing a robust framework for managing proposals, voting, and decision-making processes. It ensures that community members have a structured way to influence the DAO's operations, policies, and direction. By leveraging NFTs and integrating BLTBY tokens for proposal staking, the governance system balances inclusivity, accountability, and transparency.

Key Components of the Governance Contract

  1. NFT-Based Voting Power:

    • In the Built By DAO ecosystem, voting rights are exclusively linked to NFT ownership. The General Membership NFTs, Investor NFTs, and Leadership Council NFTs define a member's ability to participate in governance.

    • Unlike traditional governance models, BLTBY tokens do not directly grant voting power. This decision helps to decouple wealth from influence, creating a fairer voting environment where participation and role within the DAO take precedence over token accumulation.

    • Members holding multiple NFTs have their voting power calculated independently for each role, allowing them to influence different types of proposals proportionally to their involvement.

  2. Proposal Creation and Voting System:

    • Proposal Submission: Only members who are in the top 20% of equity token holders are allowed to create proposals. This helps ensure that those who have a significant vested interest in the DAO are the ones initiating changes.

    • To submit a proposal, proposers must stake 2 BLTBY tokens, which ensures that the proposal is serious and not frivolous. These tokens are held until the proposal is resolved and then returned if the proposal is successful.

    • Ranked Choice Voting is used as the voting mechanism for most decisions. This allows members to rank their preferences, ensuring that the options with broad support are chosen.

  3. Proposal Categories and Voting Thresholds:

    • There are three categories of proposals, each requiring different approval thresholds based on their level of impact:

      • Standard Proposals (operational or routine matters) require >50% approval.

      • Critical Proposals (financial or strategic decisions) require >60% approval.

      • Judicial Proposals (changes to foundational rules or major disputes) require >65% approval.

    • Each proposal can set a custom voting duration, allowing flexibility in decision-making speed depending on the urgency of the matter at hand.

  4. Leadership Council and Special Powers:

    • For a proposal to be considered valid, at least two-thirds of the Leadership Council must participate in the vote. This quorum ensures that significant proposals receive due consideration by the DAO's leadership.

    • Leadership Council members have the option to abstain from voting. This abstention can be used strategically to prevent certain votes from proceeding if they are seen as potentially harmful to the DAO.

    • Veto Power: The Founding Director, along with one additional Leadership Council member, has the power to veto any proposal. This veto power serves as an important check to ensure that actions contrary to the core values of the DAO can be halted before they cause harm.

  5. Stakeholder-Specific Proposals:

    • Some proposals are exclusive to Investor NFTs holders, specifically when the proposal relates to investment, funding rounds, or dividend distributions. This ensures that those with a financial stake in the DAO have a stronger say in investment-related decisions.

  6. Accountability and Security Measures:

    • The staking requirement for proposal submission serves as a safeguard to filter out unserious proposals. If a proposal fails, the staked BLTBY tokens are forfeited, creating a direct consequence for submitting proposals that do not align with the broader community's interests.

    • The contract includes a ReentrancyGuard to protect against reentrancy attacks during proposal creation, voting, and resolution. This ensures that all transactions and interactions remain secure and reliable.

    • Custom Errors have been utilized to efficiently handle exceptions, saving gas fees and providing clear reasons for failed operations, making the governance process both cost-effective and user-friendly.

Summary of Governance Flow

  • Proposal Creation: Top equity holders can create proposals by staking 2 BLTBY tokens. Proposals can vary in type—operational, critical, or judicial—with corresponding voting thresholds.

  • Voting Mechanism: All votes are conducted using ranked choice voting to capture the preferences of members more accurately. Voting power is based on the type and duration of NFT ownership, and weighted to favor active and long-standing members.

  • Leadership Quorum and Special Actions: To be considered, a proposal must reach a two-thirds quorum from the Leadership Council. Furthermore, the Founding Director, in conjunction with one Leadership Council member, can veto proposals to protect the DAO from potentially harmful decisions.

Encouraging Balanced Participation

This Governance Contract is designed to strike a balance between empowering members and ensuring that those with deep involvement in the ecosystem have a voice proportional to their contributions. By requiring staking to submit proposals, it guarantees that participants are serious about their contributions and have a stake in the DAO's success.

Furthermore, by utilizing ranked choice voting, the contract ensures that decisions are aligned with the broadest support from the community. The veto powers and the ability of Leadership Council members to abstain provide additional checks and balances, protecting the DAO from decisions that may negatively impact its long-term goals.

Ultimately, the Governance Contract provides a fair and transparent system that fosters collaborative decision-making, facilitates meaningful participation, and ensures that Built By DAO grows with the involvement of all its stakeholders.

Last updated

Logo

© Built By DAO Holdings LLC