# Builder DAO Contribution Issues This document contains ready-to-submit GitHub issues for [BuilderOSS/nouns-builder](https://github.com/BuilderOSS/nouns-builder), drafted by the Gnars team as part of a retrofunding + workstream proposal to Builder DAO. Each issue is based on deep analysis of both repositories. Gnars serves as a live reference implementation for all proposed features. --- ## Index | # | Title | Type | Effort | Priority | |---|-------|------|--------|----------| | [1](#1-treasury-analytics-package) | Treasury Analytics Package | New package | 3–4 days | High | | [2](#2-builder-dao-cli) | Builder DAO CLI | New tool | 2–3 weeks | High | | [3](#3-active-member-detection-hook) | Active Member Detection Hook | New hook + API | 2–3 days | Medium | | [4](#4-time-based-feed-alerts) | Time-based Feed Alerts | New component | 3–4 days | Medium | | [5](#5-0xsplits-as-proposal-transaction-type) | 0xSplits as Proposal Transaction Type | Enhancement | 3–5 days | Medium | | [6](#6-voting-power-explanation-component) | Voting Power Explanation Component | New component | 2–3 days | Medium | | [7](#7-vote-metrics-component-suite) | Vote Metrics Component Suite | New component | 2–3 days | Medium | > **Reference implementation**: All issues point to [gnars.com](https://gnars.com) and [github.com/r4topunk/gnars-website](https://github.com/r4topunk/gnars-website) as a live, production-tested reference. --- ## 1. Treasury Analytics Package **Labels**: `enhancement`, `feature-request`, `analytics`, `good first issue` ### Is your feature request related to a problem? The Builder treasury dashboard (`packages/dao-ui/Treasury/`) currently shows only static point-in-time metrics: ETH balance, total auction sales, and USD conversion. DAOs have no way to understand how their treasury has evolved over time, whether auction revenue is growing or declining, or how governance participation trends. The existing `packages/analytics/` package covers only web analytics (Google Analytics, Segment, Vercel) — there is no financial analytics layer for DAOs. As a result, DAO contributors must rely on external tools like Dune dashboards to answer basic questions like "is our treasury growing?" or "are members participating more or less in governance?" This is directly related to Builder issue [#831](https://github.com/BuilderOSS/nouns-builder/issues/831). ### Describe the solution you'd like Create a new `@buildeross/treasury-analytics` package providing reusable, chain-agnostic hooks and chart components for DAO financial intelligence: **Hooks:** - `useTreasuryHistory(address, chainId, months?)` — historical ETH + token balances using block-level lookups via chain explorer - `useAuctionMetrics(address, chainId, months?)` — monthly auction revenue aggregation from subgraph - `useProposalEngagement(address, chainId, limit?)` — unique voter counts per proposal for participation tracking **Chart Components** (styled in Zord to match Builder design system): - `TreasuryTrendChart` — area chart showing ETH + stablecoin balances over time - `AuctionRevenueChart` — bar chart of monthly auction revenue (ETH) - `ProposalActivityChart` — bar chart of monthly proposal counts - `MemberParticipationChart` — bar chart of unique voters per proposal with quorum line **Backend patterns:** - Timestamp → block number lookup (using chain explorer APIs) - In-memory caching with configurable TTL (default 24h for historical data) - Subgraph-first queries via Builder SDK ### Reference implementation Gnars DAO has all five charts running in production: - **Live**: https://gnars.com/treasury - **Repository**: https://github.com/r4topunk/gnars-website - **Components**: `src/components/treasury/AuctionTrendChart.tsx`, `TreasuryAllocationChart.tsx`, `ProposalsPerMonthChart.tsx`, `MemberActivityChart.tsx` - **Hooks**: `src/hooks/use-treasury-performance.ts`, `use-auction-bids-per-month.ts`, `use-member-activity.ts` - **API**: `src/app/api/treasury/performance/route.ts` **Charting library**: `recharts` v2 (already used in Gnars; compatible with React 19) ### Implementation notes - Components need Zord-compatible wrappers (Gnars uses Tailwind; direct import not possible) - All data sourced from existing Builder subgraph — no new indexing required - Multi-chain compatible: queries require both DAO address and chainId to query the correct subgraph - Suggested integration point: `packages/dao-ui/src/components/Treasury/` alongside existing balance views ### Contribution offer The Gnars team (@gnarlyvlad, @r4topunk) can provide production component code, hook patterns, API route templates, and integration support. --- ## 2. Builder DAO CLI **Labels**: `enhancement`, `feature-request`, `developer-experience`, `tooling` ### Is your feature request related to a problem? Builder has a comprehensive SDK (`@buildeross/sdk`) with 36+ subgraph queries, 68 React hooks, and 20 contract ABIs — but everything requires a React context to run. There is currently no way to: - Query DAO data from a Node.js script or server environment - Export governance data to CSV, JSON, or Markdown - Automate proposal monitoring or reporting - Provide structured DAO context to AI agents Power users and developers who want to build automations, generate reports, or integrate DAO data into non-browser environments have no official tooling. ### Describe the solution you'd like Create a `builder-dao-cli` npm package providing terminal access to Builder DAO operations: **Core command groups:** ``` dao info <address> --chain <chainId> # DAO metadata, token supply, config proposals list <address> --chain <chainId> # List proposals with state filters proposals get <address> <id> --chain <chainId> # Full proposal detail with votes auction current <address> --chain <chainId> # Active auction status auction history <address> --chain <chainId> [--limit] # Recent settled auctions members list <address> --chain <chainId> # Token holders with voting power members delegates <address> --chain <chainId> # Delegation tree voting-power <address> <wallet> --chain <chainId> # User voting power + delegation status treasury stats <address> --chain <chainId> # ETH balance, auction totals ``` **Output modes:** - Human-readable: formatted tables, color coding, progress bars - Machine-readable: `--json` flag for structured output (for AI agents and scripts) - Export: `--csv` and `--md` for data analysis **Technical stack:** - `commander` for CLI framework - `graphql-request` for subgraph queries (no React dependency) - `viem` for contract reads - `chalk` + `cli-table3` for terminal formatting - Built on `@buildeross/sdk` types and constants **Architecture:** ``` src/ ├── queries/ # Subgraph query wrappers (no React hooks) ├── commands/ # CLI command handlers ├── formatters/ # Output adapters (table, JSON, CSV, Markdown) └── config/ # Chain configs, DAO address resolution ``` ### Reference implementation Gnars DAO has a working CLI at https://github.com/r4topunk/builder-dao-cli with commands for proposals, auctions, voting, and member management, already using Builder SDK patterns. ### Why this matters for the ecosystem - **Power users**: Scriptable DAO operations without browser dependency - **Developers**: Build automations, bots, and integrations using a stable CLI interface - **AI agents**: Structured, queryable DAO context for governance reasoning and decision support - **Retroactive funding**: Enables transparent reporting of DAO metrics over time ### Contribution offer The Gnars team (@gnarlyvlad, @r4topunk) can contribute the existing codebase, maintain the package, and extend coverage as the Builder SDK evolves. --- ## 3. Active Member Detection Hook **Labels**: `enhancement`, `feature-request`, `governance`, `hooks` ### Is your feature request related to a problem? Builder shows token holders and basic member counts, but has no mechanism to distinguish *active* members from dormant holders. For governance health, it matters not just how many members a DAO has, but how many are actually participating. Without active member detection, DAOs cannot: - Understand true governance participation rates - Identify engagement patterns over time - Surface engaged members in voting UIs - Calculate realistic quorum targets ### Describe the solution you'd like Add a `useActiveMembers` hook to `@buildeross/hooks` with configurable sliding window: ```typescript const { activeMembers, totalMembers, participationRate } = useActiveMembers({ daoAddress: "0x...", chainId: 8453, windowSize: 10, // last N proposals activityThreshold: 1, // minimum votes to be considered active }) ``` **Returns:** - `activeMembers: Address[]` — wallets that voted at least `activityThreshold` times in the last `windowSize` proposals - `totalMembers: number` — total token holders - `participationRate: number` — percentage active (0–100) - `memberActivity: Record<Address, number>` — vote count per member **Suggested integration points:** - DAO dashboard: "X of Y members active in last 10 proposals" - Voting UI: highlight active members in delegation list - Analytics: participation trend over time (combine with proposal history) ### Reference implementation - **Live**: https://gnars.com/treasury (member activity chart) - **Hook**: `src/hooks/use-active-members.ts` - **API**: `src/app/api/members/active/route.ts` - **Component**: `src/components/treasury/MemberActivityChart.tsx` ### Implementation notes - All data available from existing subgraph: `votes` entities linked to `proposal` and `voter` - No new indexing required - Chain-agnostic: takes DAO address and chainId as parameters to query the correct subgraph - Estimated effort: 2–3 days (hook + subgraph query + basic UI integration) ### Contribution offer Gnars team (@gnarlyvlad, @r4topunk) can provide hook code, subgraph query patterns, and production usage examples. --- ## 4. Time-based Feed Alerts **Labels**: `enhancement`, `feature-request`, `feed`, `ux` ### Is your feature request related to a problem? The Builder feed (`packages/feed-ui/`) displays on-chain events reactively — it shows what *has happened*. It does not alert members about what is *about to happen*. Common DAO participation failures: - Member misses a vote because they didn't know voting was closing soon - Bidder misses an auction because they didn't notice it was ending in minutes - Proposal reaches quorum failure because there was no urgency signal ### Describe the solution you'd like Add computed time-based alert events to the feed system: **New event types:** - `VOTING_CLOSING_SOON` — proposal voting ends within configurable window (default: 6h) - `AUCTION_ENDING_SOON` — auction ends within configurable window (default: 30min) - `PROPOSAL_QUEUED` — proposal passed and entered timelock queue - `PROPOSAL_CANCELED` — proposal was canceled before execution - `PROPOSAL_VETOED` — proposal was vetoed (for DAOs with veto power) - `DELEGATE_CHANGED` — delegation transfer event (already implemented in Gnars, missing in Builder) **Technical approach:** - Computed client-side from existing subgraph data (no new indexing) - Add to `FeedItemTypes` enum in `packages/feed-ui/src/types.ts` - Priority-aware: alert events surfaced above regular events in feed - Configurable time windows per event type **Alert component:** ```tsx <FeedEventAlerts daoAddress="0x..." chainId={8453} votingAlertWindow={6 * 60 * 60} // 6 hours in seconds auctionAlertWindow={30 * 60} // 30 minutes /> ``` ### Reference implementation - **Live**: https://gnars.com (feed section) - **Event types**: `src/components/feed/` — `GovernanceEventCard.tsx`, `AuctionEventCard.tsx` - **Computed events**: `VOTING_CLOSING_SOON`, `VOTING_OPENED`, `AUCTION_ENDING_SOON`, `DELEGATE_CHANGED` already implemented ### Implementation notes - Complements the existing v0.2.2 feed redesign — does not replace anything - Works with existing `FeedFiltersModal` by adding new event type checkboxes - Potential standalone package: `@buildeross/feed-alerts` - Estimated effort: 3–4 days ### Contribution offer Gnars team (@gnarlyvlad, @r4topunk) can provide the alert computation logic, event type definitions, and production-tested time window defaults. --- ## 5. 0xSplits as Proposal Transaction Type **Labels**: `enhancement`, `feature-request`, `governance`, `proposals` ### Is your feature request related to a problem? Builder's proposal creation supports 19 transaction types (Send ETH, NFTs, Sablier streams, airdrops, etc.), but has no native way to create revenue split contracts as a governance action. Currently, if a DAO wants to distribute funds to multiple contributors, they must: 1. Manually deploy a split contract on 0xSplits outside of Builder 2. Copy the contract address into the proposal as a recipient 3. Document the split configuration separately — with no on-chain validation The only 0xSplits mention in the Builder codebase is hint text: *"can be a splits contract"* — no tooling exists. ### Describe the solution you'd like Add `CREATE_SPLIT` as a new transaction type in the proposal creation wizard: **Proposed transaction type:** ```typescript { type: "create-split", recipients: [ { address: "0x...", percentage: 60 }, { address: "0x...", percentage: 40 }, ], distributorFee: 0, // optional } ``` **UI Components:** - `SplitRecipientsSection` — add/remove recipients with percentage inputs - Real-time validation: percentages must sum to 100%, min 2 recipients, max 100 - "Distribute evenly" button for equal splits - Preview showing allocation before submission **SDK integration:** - Uses `@0xsplits/splits-sdk` for contract deployment - Multi-chain: 0xSplits is deployed on Ethereum, Base, Optimism, Zora, Polygon, Arbitrum - Returns split contract address as transaction output ### Reference implementation Gnars DAO has full 0xSplits integration in production for droposal revenue splits: - **Live**: https://gnars.com/proposals/create (droposal flow) - **Hook**: `src/hooks/use-split-creation.ts` - **Utils**: `src/lib/splits-utils.ts` (validation, percentage auto-adjustment, SDK formatting) - **UI**: `src/components/proposals/builder/forms/droposal/SplitRecipientsSection.tsx` ### Implementation notes - Gnars implementation is hardcoded to Base (chain 8453) — needs chain-agnostic abstraction for Builder - 0xSplits SDK supports all chains Builder targets - Can be implemented as optional alongside existing `fundsRecipient` single-address field - Estimated effort: 3–5 days ### Contribution offer Gnars team (@gnarlyvlad, @r4topunk) can provide full component code, multi-chain abstraction patterns, and SDK integration examples. --- ## 6. Voting Power Explanation Component **Labels**: `enhancement`, `ux`, `governance`, `onboarding` ### Is your feature request related to a problem? New DAO members frequently encounter confusing states when trying to vote: - They hold a token but have 0 voting power at the proposal snapshot - They delegated their vote but still see 0 voting power - They have incoming delegations but don't understand their voting power Builder's current voting UI does not explain these states. Users either abandon the voting flow or ask in Discord — creating unnecessary friction and support burden. ### Describe the solution you'd like Add a `<VotingPowerStatus />` component and `useVotingPowerExplanation()` hook to `@buildeross/proposal-ui`: **Hook:** ```typescript const { canVote, reason, explanation, suggestion } = useVotingPowerExplanation({ proposalId: "...", voterAddress: "0x...", chainId: 8453, snapshotBlock: 12345678, }) ``` **Returns contextual explanations:** - `"Your voting power at proposal snapshot (block 12345678) was 0. Your current token was acquired after this block."` - `"You have delegated your votes to 0x1234.... Your delegate can vote on your behalf."` - `"You have X voting power from incoming delegations. You can vote on this proposal."` - `"You have Y votes and can vote on this proposal."` (happy path) **Component states:** - No voting power at snapshot → explain snapshot block with date - Token acquired after snapshot → explain timing with link to next proposal - Delegated away → show delegate address with action to undelegate - Incoming delegation → show current voting power from delegations - Sufficient power → show vote count and enable voting ### Reference implementation - **Live**: https://gnars.com (voting controls on any active proposal) - **Component**: `src/components/common/VotingControls.tsx` - **Hook**: `src/hooks/use-proposal-eligibility.ts` Gnars allows "signal voting" (0 voting power users can record a non-binding vote) — this pattern could be optional in Builder. ### Implementation notes - Uses existing `useVotes` hook data — no new queries needed - Complements the current voting UI without replacing it - Addresses a consistent pain point for new members across all Builder DAOs - Estimated effort: 2–3 days ### Contribution offer Gnars team (@gnarlyvlad, @r4topunk) can provide the eligibility hook, explanation logic, and UI component with all edge cases covered. --- ## 7. Vote Metrics Component Suite **Labels**: `enhancement`, `ux`, `governance`, `proposals` ### Is your feature request related to a problem? Builder's proposal pages show vote counts but lack visual communication of voting outcomes. Members need to quickly understand: - How far a proposal is from quorum - The ratio between For / Against / Abstain votes - Whether the proposal will pass based on current participation Text-only vote counts create cognitive load. A visual representation makes proposal status immediately legible. ### Describe the solution you'd like Add a `<ProposalVoteMetrics />` component to `@buildeross/proposal-ui`: **Features:** - Color-coded vote cards: green (For), red (Against), gray (Abstain) - Progress bars showing each vote type relative to total supply - Quorum threshold line: dashed line on the bar showing minimum required participation - Percentage labels: "42% For (1,203 votes)" - Responsive grid: 2 columns on mobile, 3 columns on desktop - State-aware display: - `ACTIVE`: shows live vote counts with progress animation - `SUCCEEDED`/`DEFEATED`: shows final result with outcome badge - `PENDING`: shows threshold required to submit **Props:** ```typescript <ProposalVoteMetrics forVotes={1203n} againstVotes={412n} abstainVotes={89n} quorumVotes={800n} proposalThreshold={10n} totalSupply={12000n} state={ProposalState.Active} /> ``` ### Reference implementation - **Live**: https://gnars.com/proposals (any proposal detail page) - **Component**: `src/components/proposals/ProposalMetrics.tsx` Gnars' implementation uses Tailwind + Shadcn progress components. A Builder contribution would use Zord styling. ### Implementation notes - Pure display component — no contract interaction required - All data available from existing proposal queries - Integrates directly into `packages/proposal-ui/` alongside existing proposal components - Estimated effort: 2–3 days ### Contribution offer Gnars team (@gnarlyvlad, @r4topunk) can provide component code, responsive layout patterns, and accessibility (a11y) implementation including keyboard navigation and screen reader support.