Climate Research Funding DAO
What it does:
Funds climate-related scientific research through a decentralized, transparent DAO that allocates capital to high-impact studies and innovations.
Why it matters:
Accelerates climate science by removing bureaucratic bottlenecks, improves trust in research funding, and aligns incentives around measurable scientific and environmental outcomes.
How it works:
-
Researchers and institutions submit funding proposals on-chain
-
Proposals include research goals, methodology, budget, and impact metrics
-
DAO members hold governance tokens and review proposals
-
Token holders vote to approve or reject funding requests
-
Approved funds are held in escrow and released by milestones
-
Research outputs and data are published via on-chain references
-
All funding decisions and results are transparent and auditable
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
/**
* @title ClimateResearchFundingDAO
* @author Nam
* @notice DAO for funding climate research with milestone-based payouts
*/
contract ClimateResearchFundingDAO is Ownable {
IERC20 public governanceToken;
uint256 public proposalCount;
uint256 public votingPeriod = 7 days;
uint256 public quorumPercentage = 15; // % of total supply
struct Proposal {
address proposer;
address payable recipient;
uint256 totalAmount;
uint256 releasedAmount;
string description;
string impactMetrics;
uint256 endTime;
uint256 votesFor;
uint256 votesAgainst;
bool approved;
}
mapping(uint256 => Proposal) public proposals;
mapping(uint256 => mapping(address => bool)) public hasVoted;
// -------------------- EVENTS --------------------
event ProposalSubmitted(uint256 indexed proposalId, address proposer, uint256 amount);
event Voted(uint256 indexed proposalId, address voter, bool support, uint256 weight);
event FundsReleased(uint256 indexed proposalId, uint256 amount);
// -------------------- CONSTRUCTOR --------------------
constructor(address _governanceToken) {
governanceToken = IERC20(_governanceToken);
}
// -------------------- PROPOSAL SUBMISSION --------------------
function submitProposal(
address payable _recipient,
uint256 _amount,
string calldata _description,
string calldata _impactMetrics
) external {
require(governanceToken.balanceOf(msg.sender) > 0, "Not a DAO member");
require(_amount > 0, "Invalid amount");
proposalCount += 1;
proposals[proposalCount] = Proposal({
proposer: msg.sender,
recipient: _recipient,
totalAmount: _amount,
releasedAmount: 0,
description: _description,
impactMetrics: _impactMetrics,
endTime: block.timestamp + votingPeriod,
votesFor: 0,
votesAgainst: 0,
approved: false
});
emit ProposalSubmitted(proposalCount, msg.sender, _amount);
}
// -------------------- VOTING --------------------
function vote(uint256 _proposalId, bool _support) external {
Proposal storage p = proposals[_proposalId];
require(block.timestamp <p> 0, "No voting power");
hasVoted[_proposalId][msg.sender] = true;
if (_support) {
p.votesFor += weight;
} else {
p.votesAgainst += weight;
}
emit Voted(_proposalId, msg.sender, _support, weight);
}
// -------------------- APPROVAL & ESCROW --------------------
function finalizeProposal(uint256 _proposalId) external {
Proposal storage p = proposals[_proposalId];
require(block.timestamp >= p.endTime, "Voting not ended");
require(!p.approved, "Already finalized");
uint256 totalVotes = p.votesFor + p.votesAgainst;
uint256 quorum = (governanceToken.totalSupply() * quorumPercentage) / 100;
require(totalVotes >= quorum, "Quorum not reached");
require(p.votesFor > p.votesAgainst, "Proposal rejected");
p.approved = true;
}
// -------------------- MILESTONE PAYOUT --------------------
function releaseFunds(uint256 _proposalId, uint256 _amount) external onlyOwner {
Proposal storage p = proposals[_proposalId];
require(p.approved, "Not approved");
require(p.releasedAmount + _amount = _amount, "Insufficient DAO funds");
p.releasedAmount += _amount;
p.recipient.transfer(_amount);
emit FundsReleased(_proposalId, _amount);
}
// -------------------- TREASURY --------------------
receive() external payable {}
}