Community Investment Pool
What it does:
A smart contract that allows a community to pool funds together and collectively invest, manage, and share profits according to predefined contribution-based rules.
Why it matters:
Small investors often lack access to high-quality opportunities. By pooling capital and enforcing transparent governance, this contract enables collective investing without centralized fund managers.
How it works:
-
Members deposit funds into a shared investment pool.
-
Each member’s ownership share is calculated proportionally to contributions.
-
Profits (or losses) are reflected in the pool’s total value.
-
Members can withdraw their share based on current pool valuation.
-
All balances and ownership ratios are tracked transparently on-chain.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
/**
* @title CommunityInvestmentPool
* @author Nam
* @notice Collective investment pool with proportional ownership
*/
contract CommunityInvestmentPool {
// -------------------- DATA STRUCTURES --------------------
struct Member {
uint256 shares; // Ownership shares
bool active;
}
mapping(address => Member) public members;
address[] public memberList;
address public manager;
uint256 public totalShares;
uint256 public totalPoolValue;
// -------------------- EVENTS --------------------
event Joined(address indexed member, uint256 amount, uint256 shares);
event PoolValueUpdated(uint256 newValue);
event Withdrawn(address indexed member, uint256 amount);
// -------------------- MODIFIERS --------------------
modifier onlyManager() {
require(msg.sender == manager, "Not manager");
_;
}
modifier onlyMember() {
require(members[msg.sender].active, "Not member");
_;
}
// -------------------- CONSTRUCTOR --------------------
constructor() {
manager = msg.sender;
}
// -------------------- CORE LOGIC --------------------
/**
* @notice Join the investment pool
*/
function joinPool() external payable {
require(msg.value > 0, "Zero contribution");
uint256 newShares;
if (totalShares == 0) {
newShares = msg.value;
} else {
newShares =
(msg.value * totalShares) / totalPoolValue;
}
if (!members[msg.sender].active) {
members[msg.sender] = Member({
shares: newShares,
active: true
});
memberList.push(msg.sender);
} else {
members[msg.sender].shares += newShares;
}
totalShares += newShares;
totalPoolValue += msg.value;
emit Joined(msg.sender, msg.value, newShares);
}
/**
* @notice Manager updates pool value (profits/losses)
* @dev In real systems, this reflects external investments
*/
function updatePoolValue(uint256 _newValue)
external
onlyManager
{
require(_newValue > 0, "Invalid value");
totalPoolValue = _newValue;
emit PoolValueUpdated(_newValue);
}
/**
* @notice Withdraw proportional share from pool
*/
function withdraw() external onlyMember {
Member storage member = members[msg.sender];
uint256 amount =
(member.shares * totalPoolValue) / totalShares;
totalShares -= member.shares;
totalPoolValue -= amount;
member.shares = 0;
member.active = false;
payable(msg.sender).transfer(amount);
emit Withdrawn(msg.sender, amount);
}
// -------------------- VIEW FUNCTIONS --------------------
/**
* @notice Get member info
*/
function getMember(address _member)
external
view
returns (
uint256 shares,
bool active
)
{
Member memory m = members[_member];
return (
m.shares,
m.active
);
}
/**
* @notice Get pool overview
*/
function getPoolStats()
external
view
returns (
uint256 _totalPoolValue,
uint256 _totalShares,
uint256 _memberCount
)
{
return (
totalPoolValue,
totalShares,
memberList.length
);
}
}