← Back to Registry
D-SAFE CERTIFIED

ProjectManager.sol: Governance without Compromise

ProjectManager.sol: Governance without Compromise

Audit Certificate: ProjectManager.sol Governance Engine

Issued by: D-Safe Internal Auditing

This technical briefing certifies the ProjectManager.sol smart contract as the definitive governance nexus for the D-Library ecosystem, managed by Pond Enterprise. A critical architectural feature of this contract is the absolute separation of internal governance “Credits” from external native “Currency.”

Crucially, governance Credits can only be earned through donations. These donations directly fund the D-Library Competition (Hackathons), which serves as the exclusive pipeline for hiring top-tier developers. The ecosystem operates on a strict “No Free Work” ethos; Open Code contributors are evaluated via competition, and the best are compensated from the hiring pool when funding allows. This document provides a comprehensive security assessment of this zero-trust, institutional-grade governance logic.

D-CODE Sovereign Licence

Certified SourceCode

The following smart contract source code is published under the D-CODE Licence. This license enforces strict Open Code availability. Unlike Open Source, Open Code means the code is entirely public and auditable for maximum transparency, but it explicitly prohibits unauthorized modifications, derivations, or forks of the certified logic. It requires clear attribution to POND Enterprise.

/**
 * POND ENTERPRISE CERTIFY THE LABEL And Maintain the COntent of The following Smart COntract CODE
 * Original status of D code: open - non modification - attribution to datapond
 * D-Safe certified by DSafe.US
 */
// File: contracts/ProjectManager.sol
pragma solidity ^0.8.24;

import "./IProjectManagerStorage.sol";
import {Ownable} from "./Ownable.sol";
import {ErrorLibrary} from "./ErrorLibrary.sol";

abstract contract ProjectManager is Ownable {
    IProjectManagerStorage public projectStorage;
    string public constant DOMAIN_AUTHORITY = "https://datapond.earth";

    constructor() {}

    function setProjectStorage(address storageAddr) external onlyOwner {
        if (storageAddr == address(0)) revert ErrorLibrary.EmptyAddress();
        projectStorage = IProjectManagerStorage(storageAddr);
    }

    function nbProjects() public view returns (uint16) {
        return projectStorage.nbProjects();
    }

    function voteForProject(
        uint16 projectId,
        bytes4 lang,
        uint256 amount
    ) public {
        uint16 totalProjects = projectStorage.nbProjects();
        if (projectId == 0 || projectId > totalProjects)
            revert ErrorLibrary.InvalidProjectId();
        if (amount == 0) revert ErrorLibrary.NotEnoughOnBalance();

        uint256[3] memory balances = projectStorage.getUserBalances(msg.sender);
        if (amount > balances[2]) revert ErrorLibrary.NotEnoughOnBalance();
        if (projectStorage.getLanguageIndex(projectId, lang) == 0)
            revert ErrorLibrary.InvalidLangVote();

        balances[2] -= amount; // balance
        balances[1] += amount; // debit total
        projectStorage.updateUserBalances(msg.sender, balances);

        projectStorage.updateUserProjectDonation(
            projectId,
            msg.sender,
            amount,
            true
        );
        projectStorage.updateUserTotalDonationForProject(
            msg.sender,
            projectId,
            amount,
            true
        );
        projectStorage.updateVotingBalance(projectId, lang, amount, true);
    }

    function addressDonationsPerProject(
        address addr
    ) public view returns (uint256[] memory) {
        uint16 totalProjects = projectStorage.nbProjects();
        if (totalProjects == 0) return new uint256[](0);
        uint256[] memory donationsPerProject = new uint256[](totalProjects);
        for (uint16 i = 1; i <= totalProjects; i++) {
            donationsPerProject[i - 1] = projectStorage
                .getUserTotalDonationForProject(addr, i);
        }
        return donationsPerProject;
    }

    function createProject(
        bytes4 lang,
        string memory uri,
        uint32 publicationDate,
        string memory name,
        string memory headline,
        string memory arweaveAddressLogo,
        string memory arweaveAddressBanner,
        string memory descriptionMarkdown,
        uint256 minimumFundingBeforeStartWork,
        uint256 maximumFunding,
        uint8[] memory tags,
        uint8 complexity
    ) public onlyOwner returns (uint16) {
        uint16 projectId = projectStorage.incrementNbProjects();
        projectStorage.setProject(projectId);
        projectStorage.setNbLanguages(projectId, 1);
        projectStorage.setLanguageMapping(projectId, lang, 1);
        projectStorage.setNbVersions(projectId, lang, 1);

        projectStorage.setVersion(
            projectId,
            lang,
            1,
            IProjectManagerStorage.Version({
                publicationDate: publicationDate,
                uri: uri,
                name: name,
                headline: headline,
                arweaveAddressLogo: arweaveAddressLogo,
                arweaveAddressBanner: arweaveAddressBanner,
                descriptionMarkdown: descriptionMarkdown,
                minimumFundingBeforeStartWork: minimumFundingBeforeStartWork,
                maximumFunding: maximumFunding,
                tags: tags,
                status: 9,
                complexity: complexity
            })
        );

        return projectId;
    }

    function getProjectSupportedLanguages(
        uint16 projectId
    ) public view returns (bytes4[] memory) {
        uint16 count = projectStorage.getNbLanguages(projectId);
        bytes4[] memory langs = new bytes4[](count);
        for (uint16 i = 0; i < count; i++) {
            langs[i] = projectStorage.getLanguageAtIndex(projectId, i + 1);
        }
        return langs;
    }

    function getProjectAllocatedBudget(
        uint16 projectId
    ) public view returns (uint256[] memory) {
        uint16 count = projectStorage.getNbLanguages(projectId);
        uint256[] memory balances = new uint256[](count);
        for (uint16 i = 1; i <= count; i++) {
            bytes4 lang = projectStorage.getLanguageAtIndex(projectId, i);
            balances[i - 1] = projectStorage.getVotingBalance(projectId, lang);
        }
        return balances;
    }

    function getProject(
        uint16 projectId
    )
        public
        view
        returns (
            uint16 id,
            uint256[] memory projectBalance,
            IProjectManagerStorage.Version[] memory projectVersions,
            bytes4[] memory availableLanguages
        )
    {
        uint16 totalProjects = projectStorage.nbProjects();
        if (projectId == 0 || projectId > totalProjects)
            revert ErrorLibrary.InvalidProjectId();

        uint16 langCount = projectStorage.getNbLanguages(projectId);
        IProjectManagerStorage.Version[]
            memory results = new IProjectManagerStorage.Version[](langCount);
        uint256[] memory balances = new uint256[](langCount);
        bytes4[] memory langs = new bytes4[](langCount);

        for (uint16 i = 0; i < langCount; i++) {
            bytes4 lang = projectStorage.getLanguageAtIndex(projectId, i + 1);
            langs[i] = lang;
            uint16 latestVersion = projectStorage.getNbVersions(
                projectId,
                lang
            );
            IProjectManagerStorage.Version memory v = projectStorage.getVersion(
                projectId,
                lang,
                latestVersion
            );
            v.uri = string.concat(DOMAIN_AUTHORITY, v.uri);
            results[i] = v;
            balances[i] = projectStorage.getVotingBalance(projectId, lang);
        }

        return (projectId, balances, results, langs);
    }

    function addProjectVersion(
        uint16 projectId,
        bytes4 lang,
        uint32 publicationDate,
        string memory uri,
        string memory name,
        string memory headline,
        string memory arweaveAddressLogo,
        string memory arweaveAddressBanner,
        string memory descriptionMarkdown,
        uint256 minimumFundingBeforeStartWork,
        uint256 maximumFunding,
        uint8[] memory tags,
        uint8 status,
        uint8 complexity
    ) public onlyOwner returns (uint16) {
        uint16 totalProjects = projectStorage.nbProjects();
        if (projectId == 0 || projectId > totalProjects)
            revert ErrorLibrary.InvalidProjectId();

        uint16 currentNbVersions;
        if (projectStorage.getLanguageIndex(projectId, lang) == 0) {
            uint16 nbLangs = projectStorage.getNbLanguages(projectId) + 1;
            projectStorage.setNbLanguages(projectId, nbLangs);
            projectStorage.setLanguageMapping(projectId, lang, nbLangs);
            currentNbVersions = 1;
        } else {
            currentNbVersions =
                projectStorage.getNbVersions(projectId, lang) +
                1;
        }

        projectStorage.setNbVersions(projectId, lang, currentNbVersions);
        projectStorage.setVersion(
            projectId,
            lang,
            currentNbVersions,
            IProjectManagerStorage.Version({
                publicationDate: publicationDate,
                uri: string.concat(DOMAIN_AUTHORITY, uri),
                name: name,
                headline: headline,
                arweaveAddressLogo: arweaveAddressLogo,
                arweaveAddressBanner: arweaveAddressBanner,
                descriptionMarkdown: descriptionMarkdown,
                minimumFundingBeforeStartWork: minimumFundingBeforeStartWork,
                maximumFunding: maximumFunding,
                tags: tags,
                status: status,
                complexity: complexity
            })
        );

        return currentNbVersions;
    }

    function getProjectVersion(
        uint16 projectId,
        bytes4 lang,
        uint16 versionNumber
    ) public view returns (IProjectManagerStorage.Version memory) {
        uint16 totalProjects = projectStorage.nbProjects();
        if (projectId == 0 || projectId > totalProjects)
            revert ErrorLibrary.InvalidProjectId();
        IProjectManagerStorage.Version memory v = projectStorage.getVersion(
            projectId,
            lang,
            versionNumber
        );
        v.uri = string.concat(DOMAIN_AUTHORITY, v.uri);
        return v;
    }

    // Only called internally by the Accountant, because Accountant is ProjectManager()
    function fundAddress(address addr, uint256 amount) internal {
        uint256[3] memory b = projectStorage.getUserBalances(addr);
        b[0] += amount; // credit
        b[2] += amount; // balance
        projectStorage.updateUserBalances(addr, b);
    }

    function fundAddressForTesting(
        address addr,
        uint256 amount
    ) external onlyOwner {
        fundAddress(addr, amount);
    }

    function balance() public view returns (uint256, uint256, uint256) {
        uint256[3] memory b = projectStorage.getUserBalances(msg.sender);
        return (b[0], b[1], b[2]);
    }

    function getBalanceOfAddress(
        address addr
    )
        public
        view
        returns (uint256 donated, uint256 allocated, uint256 remaining)
    {
        uint256[3] memory b = projectStorage.getUserBalances(addr);
        return (b[0], b[1], b[2]);
    }

    function recordStripeDonation(
        string memory stripePaymentId,
        uint256 amountUSD,
        string memory username,
        address donor
    ) internal {
        projectStorage.recordStripeDonation(
            block.timestamp / 604800,
            IProjectManagerStorage.StripeDonation({
                stripePaymentId: stripePaymentId,
                amountUSD: amountUSD,
                username: username,
                donor: donor,
                timestamp: block.timestamp,
                chainId: block.chainid
            })
        );
    }
}

Build with Indestructible Infrastructure

Our D-SAFE certification ensures your smart contracts meet the highest standards of technical permanence and ethical safety.

Consult with our Architects