Community-Owned Media DAO
What it does:
Enables a community to collectively own, fund, govern, and monetize a media platform using on-chain governance and transparent revenue distribution.
Why it matters:
Breaks the centralized media model, aligns creators and audiences economically, enables censorship-resistant publishing, and ensures revenue and decision-making power belong to the community.
How it works:
-
Community members join by holding governance tokens or NFTs
-
Members propose and vote on editorial decisions, funding allocations, and platform rules
-
Treasury collects revenue from ads, subscriptions, licensing, or sponsorships
-
Smart contracts distribute revenue to contributors, editors, and the DAO treasury
-
Voting power and payouts are enforced on-chain via transparent rules
-
Contributors are rewarded based on participation, content impact, or DAO-defined metrics
-
DAO governance can evolve via on-chain proposals and upgrades
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
/**
* @title CommunityOwnedMediaDAO
* @author Nam
* @notice Community-owned media platform with governance and revenue distribution
*/
contract CommunityOwnedMediaDAO {
address public admin;
uint256 public proposalCount;
uint256 public memberCount;
constructor() {
admin = msg.sender;
}
// -------------------- STRUCTS --------------------
struct Member {
bool active;
uint256 votingPower;
uint256 rewardBalance;
}
struct Proposal {
string description;
uint256 yesVotes;
uint256 noVotes;
uint256 deadline;
bool executed;
}
mapping(address => Member) public members;
mapping(uint256 => Proposal) public proposals;
// -------------------- EVENTS --------------------
event MemberJoined(address indexed member, uint256 votingPower);
event ProposalCreated(uint256 indexed proposalId, string description);
event Voted(uint256 indexed proposalId, address indexed voter, bool support, uint256 weight);
event ProposalExecuted(uint256 indexed proposalId);
event RevenueDistributed(uint256 amount);
event RewardWithdrawn(address indexed member, uint256 amount);
// -------------------- MODIFIERS --------------------
modifier onlyMember() {
require(members[msg.sender].active, "Not a member");
_;
}
// -------------------- MEMBERSHIP --------------------
function joinDAO(uint256 _votingPower) external {
require(!members[msg.sender].active, "Already member");
require(_votingPower > 0, "Invalid voting power");
members[msg.sender] = Member({
active: true,
votingPower: _votingPower,
rewardBalance: 0
});
memberCount += 1;
emit MemberJoined(msg.sender, _votingPower);
}
// -------------------- GOVERNANCE --------------------
function createProposal(string calldata _description, uint256 _votingDuration)
external
onlyMember
{
require(_votingDuration > 0, "Invalid duration");
proposalCount += 1;
proposals[proposalCount] = Proposal({
description: _description,
yesVotes: 0,
noVotes: 0,
deadline: block.timestamp + _votingDuration,
executed: false
});
emit ProposalCreated(proposalCount, _description);
}
function vote(uint256 _proposalId, bool _support) external onlyMember {
Proposal storage p = proposals[_proposalId];
require(block.timestamp <p>= p.deadline, "Voting ongoing");
require(!p.executed, "Already executed");
require(p.yesVotes > p.noVotes, "Proposal rejected");
p.executed = true;
emit ProposalExecuted(_proposalId);
}
// -------------------- TREASURY & REVENUE --------------------
receive() external payable {}
function distributeRevenue(address[] calldata _contributors, uint256[] calldata _amounts)
external
payable
{
require(_contributors.length == _amounts.length, "Length mismatch");
uint256 total;
for (uint256 i = 0; i < _amounts.length; i++) {
total += _amounts[i];
}
require(total == msg.value, "Invalid distribution");
for (uint256 i = 0; i 0, "No rewards");
members[msg.sender].rewardBalance = 0;
payable(msg.sender).transfer(amount);
emit RewardWithdrawn(msg.sender, amount);
}
}