GovernanceLedger serves as the authoritative source of truth for maintainer incentives and capital distribution within the Drips ecosystem. It acts as a specialized ledger that maps project identities to their internal distribution configurations, known as Splits.
The "Splits" feature is the backbone of collaborative project funding. It enables a transition from "Solo-Preneur" funding to "Ecosystem-Scale" distribution. Instead of a single gateway address, GovernanceLedger allows projects to define a meritocratic or pre-agreed distribution model.
- Incoming Capital: Assets enter the ecosystem via the
DripVaultorTidalRegistry. - Lookup: The distribution logic queries
GovernanceLedger.projectSplits(projectAddress). - Pro-Rata Calculation: The system iterates through the
SplitMemberarray and calculates the exact amount for each member based on theirweightrelative to theTOTAL_WEIGHT(standardized at1,000,000or 100%). - Execution: Assets are pushed or streamed to the members' individual Drips accounts or wallets.
If the Drips Protocol streams 10,000 DAI/month to a project:
| Role | Address | Weight | Monthly DAI |
|---|---|---|---|
| Lead Engineer | 0xLead... |
600,000 (60%) | 6,000 DAI |
| Docs Writer | 0xDocs... |
300,000 (30%) | 3,000 DAI |
| Treasury (Gnosis Safe) | 0xSafe... |
100,000 (10%) | 1,000 DAI |
The GovernanceLedger is designed to be lean, immutable-friendly, and gas-efficient.
/**
* @dev SplitMember defines a single recipient in a distribution.
* member: The address to receive funds.
* weight: The relative share (denominator is usually 1,000,000).
*/
struct SplitMember {
address member;
uint32 weight;
}
/**
* @dev Mapping from project ID (address) to its list of beneficiaries.
*/
mapping(address => SplitMember[]) public projectSplits;graph TD
A[Capital Source: Drips/Vault] -->|Queries Splits| B(GovernanceLedger)
B -->|Returns Array| C{Distribution Logic}
C -->|60%| D[Lead Maintainer]
C -->|30%| E[Technical Writer]
C -->|10%| F[Community Treasury]
subgraph "Governance Control"
G[Project Owner/Multisig] -->|Update Splits| B
end
The project owner or a authorized governance contract calls setSplits to update the distribution.
function setSplits(address project, SplitMember[] calldata members) external {
// 1. Authorization Check (e.g., only project owner)
// 2. Validation: Ensure total weight == 1,000,000
// 3. Update Storage
delete projectSplits[project];
for (uint256 i = 0; i < members.length; i++) {
projectSplits[project].push(members[i]);
}
emit SplitsUpdated(project, members);
}External contracts use getSplits to perform calculations.
function getSplits(address project) external view returns (SplitMember[] memory) {
return projectSplits[project];
}- Weight Standardization: All weights MUST sum to
1,000,000to ensure 100% of the funds are accounted for. - Access Control: The
setSplitsfunction should ideally be controlled by the project's own governance (DAO) or a Multi-Sig (Gnosis Safe) to prevent unauthorized distribution changes. - Array Limits: To prevent gas limit issues during distribution, the number of
SplitMembers per project should be capped (e.g., max 50 members).
git clone https://github.com/your-org/GovernanceLedger
cd GovernanceLedger
forge buildWe use Foundry for high-fidelity smart contract testing.
forge test -vvvThis project is licensed under the MIT License.