Community Solar Fund Contract
What it does:
Enables communities to collectively fund, own, and benefit from shared solar energy projects through transparent on-chain investment and revenue distribution.
Why it matters:
Lowers the barrier to renewable energy ownership, democratizes access to clean power, and ensures fair, auditable distribution of returns from solar projects.
How it works:
-
Community members contribute funds to a shared solar project
-
Contributions are recorded on-chain and represent ownership shares
-
Funds are used to deploy or expand solar installations
-
Energy revenue or savings are periodically reported via oracles
-
Smart contract distributes收益 to contributors proportional to shares
-
Governance decisions (maintenance, expansion) can be community-voted
-
All funding, ownership, and payouts 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 CommunitySolarFund
* @author Nam
* @notice Collective funding and revenue sharing for community solar projects
*/
contract CommunitySolarFund is Ownable {
IERC20 public payoutToken;
uint256 public totalShares;
uint256 public totalRevenue;
mapping(address => uint256) public shares;
mapping(address => uint256) public claimedRevenue;
// -------------------- EVENTS --------------------
event ContributionReceived(address indexed contributor, uint256 amount, uint256 sharesMinted);
event RevenueReported(uint256 amount);
event RevenueClaimed(address indexed contributor, uint256 amount);
// -------------------- CONSTRUCTOR --------------------
constructor(address _payoutToken) {
payoutToken = IERC20(_payoutToken);
}
// -------------------- FUNDING --------------------
function contribute(uint256 _amount) external {
require(_amount > 0, "Invalid amount");
payoutToken.transferFrom(msg.sender, address(this), _amount);
uint256 mintedShares = _amount; // 1:1 for simplicity
shares[msg.sender] += mintedShares;
totalShares += mintedShares;
emit ContributionReceived(msg.sender, _amount, mintedShares);
}
// -------------------- REVENUE REPORTING --------------------
function reportRevenue(uint256 _amount) external onlyOwner {
require(_amount > 0, "Invalid revenue amount");
payoutToken.transferFrom(msg.sender, address(this), _amount);
totalRevenue += _amount;
emit RevenueReported(_amount);
}
// -------------------- REVENUE CLAIM --------------------
function claimRevenue() external {
uint256 userShare = shares[msg.sender];
require(userShare > 0, "No shares owned");
uint256 entitled = (totalRevenue * userShare) / totalShares;
uint256 claimable = entitled - claimedRevenue[msg.sender];
require(claimable > 0, "Nothing to claim");
claimedRevenue[msg.sender] += claimable;
payoutToken.transfer(msg.sender, claimable);
emit RevenueClaimed(msg.sender, claimable);
}
}