FellowFund: Decentralized Fellowship Funding Through Prediction Markets
A revolutionary Web3 platform leveraging prediction market primitives to transform fellowship selection and accountability. Built for ETHGlobal Bangkok hackathon with multi-chain smart contracts, real-time oracles, and community-driven decision making through skin-in-the-game mechanics.


Traditional fellowship programs suffer from subjective selection criteria, limited accountability, and opaque decision-making processes. FellowFund revolutionizes this landscape by introducing prediction market primitives into fellowship funding, creating a transparent, incentive-aligned ecosystem where community wisdom drives both selection and accountability.
Built for ETHGlobal Bangkok 2024, FellowFund demonstrates how financial stakes can transform decision-making quality while fostering genuine accountability among builders, funders, and community members.
The Problem: Broken Fellowship Funding
Current fellowship programs face systemic challenges that limit their effectiveness:
- Subjective Selection: Traditional committees make decisions behind closed doors
- No Accountability: Fellows receive funds upfront with minimal performance tracking
- Binary Outcomes: Projects are simply "funded" or "rejected" with no nuanced evaluation
- Limited Community Input: Decisions rest with small groups of gatekeepers
- No Skin in the Game: Evaluators face no consequences for poor decisions
FellowFund addresses these fundamental issues by introducing market-based mechanisms that align incentives and harness collective intelligence.
User Flow: Complete Fellowship Journey
The FellowFund platform guides users through a comprehensive journey from fellowship creation to final resolution. The complete user flow demonstrates how different stakeholders interact with the system:

This flow illustrates the multi-stakeholder interaction model where organizations create fellowships, builders apply with clear KPIs, the community evaluates through prediction markets, and verified outcomes determine final payouts.
Architecture Overview: Prediction Markets as Information Engines
FellowFund operates on a sophisticated multi-phase lifecycle that transforms fellowship funding from subjective evaluation to market-driven consensus:
Technology Stack
const FELLOWFUND_STACK = {
// Blockchain Layer
smartContracts: 'Solidity + OpenZeppelin',
networks: ['Ethereum', 'Polygon', 'Optimism', 'Base', 'Celo', 'Flow', 'Rootstock'],
// Oracle & Verification
oracle: 'Phala Network TEE',
identity: 'WorldCoin ID verification',
proofSystem: 'vLayer ZK proofs',
// Data Infrastructure
indexing: 'The Graph Protocol',
subgraphs: 'Multi-chain event indexing',
// Frontend & Integration
web: 'Next.js + TypeScript',
auth: 'Web3Auth + Social Login',
messaging: 'Push Protocol',
// Backend Services
api: 'Express.js + Node.js',
automation: 'Operator service polling',
// Infrastructure
deployment: 'Hardhat + Ignition'
};
Smart Contract Architecture: The Trust Foundation
Core Contract Design
The FellowFund.sol contract serves as the orchestration layer for the entire fellowship lifecycle:
contract FellowFund is IFellowFund, Ownable {
uint256 public fellowshipCount;
mapping(uint256 => Fellowship) public fellowships;
mapping(uint256 => Application[]) public applications;
mapping(uint256 => mapping(uint256 => IMarket)) public markets;
address public phalaVerifier;
address public operator;
constructor(address _phalaVerifier, address _operator) Ownable(msg.sender) {
phalaVerifier = _phalaVerifier;
operator = _operator;
}
Fellowship Lifecycle States
The platform implements a sophisticated state machine that guides fellowships through distinct phases:
enum FellowshipStatus {
Created,
AcceptingApplications,
MarketOpen,
EpochStarted,
Resolved
}
struct Fellowship {
string metadata;
uint256 funds;
uint256 applicationDeadline;
uint256 marketDeadline;
uint256 epochEndTime;
FellowshipStatus status;
}
struct Application {
address applicant;
string metadata;
bool achieved;
bool verified;
bool accepted;
uint256 grantAmount;
}
Fellowship Creation with Funding Commitment
Organizations create fellowships by committing funds upfront, ensuring serious intent:
function createFellowship(
string calldata _metadata,
uint256 _funds,
uint256 _applicationDeadline,
uint256 _marketDeadline,
uint256 _epochDeadline
) external payable {
require(msg.value == _funds, "Incorrect funds sent");
uint256 fellowshipId = fellowshipCount;
fellowshipCount++;
Fellowship storage fellowship = fellowships[fellowshipId];
fellowship.metadata = _metadata;
fellowship.funds = _funds;
fellowship.applicationDeadline = _applicationDeadline;
fellowship.marketDeadline = _marketDeadline;
fellowship.epochEndTime = _epochDeadline;
fellowship.status = FellowshipStatus.Created;
fellowships[fellowshipId] = fellowship;
fellowships[fellowshipId].status = FellowshipStatus.AcceptingApplications;
emit FellowshipCreated(fellowshipId, fellowships[fellowshipId]);
}
Prediction Market Mechanics: Skin in the Game
Market Contract Design
Each applicant gets their own dedicated prediction market where community members can stake on success probability:
contract Market is IMarket {
address public immutable operator;
address public immutable applicant;
uint256 public immutable fellowshipId;
Side public result;
bool public isMarketResolved;
mapping(Side => uint256) public bets;
mapping(address => mapping(Side => uint256)) public betsPerBettor;
address[] public bettors;
mapping(address => bool) private isBettor;
Betting Mechanism with Proportional Payouts
Community members stake ETH on whether applicants will achieve their stated KPIs:
function placeBet(Side _side) external payable {
if (isMarketResolved) revert MarkedAlreadyResolved();
if (msg.value == 0) revert InvalidBetAmount();
bets[_side] += msg.value;
betsPerBettor[msg.sender][_side] += msg.value;
if (!isBettor[msg.sender]) {
bettors.push(msg.sender);
isBettor[msg.sender] = true;
}
emit BetPlaced(msg.sender, _side, msg.value);
}
Market Resolution with Winner-Take-All Distribution
Winners receive proportional shares of the entire betting pool:
function resolve(Side _winner) external onlyOperator {
if (isMarketResolved) revert MarkedAlreadyResolved();
if (bettors.length == 0) revert NoBetsPlaced();
result = _winner;
isMarketResolved = true;
uint256 totalWinningBets = bets[_winner];
if (totalWinningBets > 0) {
uint256 totalPot = address(this).balance;
uint256 nrBettors = bettors.length;
for (uint256 i = 0; i < nrBettors; i++) {
address bettor = bettors[i];
uint256 winningBets = betsPerBettor[bettor][_winner];
if (winningBets > 0) {
uint256 winnings = (winningBets * totalPot) / totalWinningBets;
betsPerBettor[bettor][Side.Yes] = 0;
betsPerBettor[bettor][Side.No] = 0;
(bool success,) = payable(bettor).call{value: winnings}("");
if (!success) revert TransferFailed();
emit WinningsDistributed(bettor, winnings);
}
}
}
emit MarketResolved(_winner);
}
Market-Based Selection Process
Opening Markets for Community Evaluation
After the application period ends, markets open for each applicant:
function openFellowshipMarkets(uint256 fellowshipId) external onlyOperator {
Fellowship storage fellowship = fellowships[fellowshipId];
require(fellowship.status == FellowshipStatus.AcceptingApplications, "Invalid status");
Application[] storage apps = applications[fellowshipId];
require(apps.length > 0, "No applications to create markets for");
// Create market for each applicant
for (uint256 i = 0; i < apps.length; i++) {
Market market = new Market(address(this), fellowshipId, apps[i].applicant);
markets[fellowshipId][i] = IMarket(address(market));
emit MarketOpened(fellowshipId, address(market), i);
}
fellowship.status = FellowshipStatus.MarketOpen;
}
Grant Distribution Based on Market Consensus
Applicants with >50% "YES" stakes receive proportional funding:
function evaluateMarket(uint256 fellowshipId) external onlyOperator {
Fellowship storage fellowship = fellowships[fellowshipId];
require(fellowship.status == FellowshipStatus.MarketOpen, "Invalid status");
Application[] storage apps = applications[fellowshipId];
uint256 acceptedApplicantsCount = 0;
uint256 nrApps = apps.length;
// Evaluate each application based on market stakes
for (uint256 i = 0; i < nrApps; i++) {
Application storage app = apps[i];
IMarket market = markets[fellowshipId][i];
uint256 yesBets = market.getBet(Side.Yes);
uint256 noBets = market.getBet(Side.No);
uint256 totalBets = yesBets + noBets;
if (totalBets > 0) {
if (yesBets > noBets) {
app.accepted = true;
acceptedApplicantsCount++;
emit ApplicantAccepted(fellowshipId, i);
}
}
}
uint256 grantPerAccepted = 0;
if (acceptedApplicantsCount > 0) {
grantPerAccepted = fellowship.funds / acceptedApplicantsCount;
}
// Calculate grant amount for accepted applications
if (acceptedApplicantsCount > 0) {
for (uint256 i = 0; i < nrApps; i++) {
if (apps[i].accepted) {
apps[i].grantAmount = grantPerAccepted;
(bool success,) = payable(apps[i].applicant).call{value: grantPerAccepted}("");
require(success, "Transfer failed");
}
}
}
fellowship.status = FellowshipStatus.EpochStarted;
emit EpochStarted(fellowshipId, grantPerAccepted, acceptedApplicantsCount, apps.length);
}
Oracle Integration: Phala Network TEE Verification
Trusted Execution Environment for Impact Verification
FellowFund integrates with Phala Network's TEE to provide tamper-proof verification of applicant achievements:
function setApplicantImpact(uint256 fellowshipId, uint256 applicationId, bool achieved, bytes calldata proof)
external
onlyVerifier
{
require(fellowships[fellowshipId].status == FellowshipStatus.EpochStarted, "Invalid status");
// Verify TEE proof
(bool success,) = phalaVerifier.call(proof);
require(success, "Invalid achievement proof");
Application storage application = applications[fellowshipId][applicationId];
application.achieved = achieved;
application.verified = true;
emit ApplicationEvaluated(fellowshipId, applicationId, achieved);
}
Automated KPI Tracking
The Phala oracle can automatically verify various achievement metrics:
const sampleFellowship = {
metadata: `{
"githubOrg": "fellowfund",
"kpiTargets": {
"totalCommits": {
"targetValue": 3,
"weight": 0.7
},
"poapEvents": {
"targetValue": 1,
"weight": 0.3
}
}
}`,
funds: 1000000000000000000n, // 1 ETH in wei
applicationDeadline: BigInt(Math.floor(Date.now() / 1000)),
marketDeadline: BigInt(Math.floor(Date.now() / 1000) + 60),
epochEndTime: BigInt(Math.floor(Date.now() / 1000) + 180),
status: 0, // FellowshipStatus.AcceptingApplications
maxApplicants: 2
};
Multi-Chain Infrastructure: Global Accessibility
Comprehensive Network Support
FellowFund deploys across 8+ blockchain networks to maximize accessibility and reduce friction:
* Polygon Amoy
* 0x54668Ac3E509020b2349b5e66851d9bf9Ee88B5A
* Optimism Sepolia
* 0x54668Ac3E509020b2349b5e66851d9bf9Ee88B5A
* Flow Testnet
* 0xc6197dF92872B6665B7A3ba6857e3D8580D1A6d5
* Mantle Sepolia
* 0x2323Cd8097708f4C8D4BA37aE72644Af712bAD76
* Celo Alfajores Testnet
* 0x0810B2d3C23d7207C6B15fb6B3303e99561cb80f
* Unichain Sepolia
* 0x0810B2d3C23d7207C6B15fb6B3303e99561cb80f
* Rootstock Testnet
* 0x2323Cd8097708f4C8D4BA37aE72644Af712bAD76
* Base Sepolia
* 0x54668Ac3E509020b2349b5e66851d9bf9Ee88B5A
The Graph Protocol Integration
Real-time blockchain data indexing across all supported networks:
type Fellowship @entity {
id: ID!
metadata: String!
funds: BigInt!
applicationDeadline: BigInt!
marketDeadline: BigInt!
epochEndTime: BigInt!
status: FellowshipStatus!
applications: [Application!]! @derivedFrom(field: "fellowship")
markets: [Market!]! @derivedFrom(field: "fellowship")
}
type Application @entity {
id: ID!
fellowship: Fellowship!
applicant: Bytes!
metadata: String!
achieved: Boolean!
verified: Boolean!
accepted: Boolean!
grantAmount: BigInt!
}
type Market @entity {
id: ID!
fellowship: Fellowship!
applicant: Bytes!
yesVotes: BigInt!
noVotes: BigInt!
resolved: Boolean!
winner: Side
}
Frontend Architecture: Web3-Native User Experience
Next.js Application with Multi-Provider Integration
The frontend seamlessly integrates multiple Web3 technologies:
"@headlessui/react": "^2.1.3",
"@heroicons/react": "^2.1.5",
"@pushprotocol/restapi": "^1.7.29",
"@pushprotocol/socket": "^0.5.3",
"@vlayer/sdk": "^0.1.0-nightly-20241115-70dfc11",
"@worldcoin/idkit": "^1.3.0",
"@xmtp/consent-proof-signature": "^0.1.3",
"@web3auth/base": "^9.4.0",
"@web3auth/ethereum-provider": "^9.4.0",
"@web3auth/modal": "^9.4.0"
WorldCoin Identity Verification
Sybil-resistant identity verification using WorldCoin's proof-of-personhood:
{
worldIdVerified ? (
<button
className="text-primary-900 hover:bg-primary-50 flex items-center justify-center rounded-md border border-transparent bg-white px-4 py-3 text-base font-medium shadow-sm sm:px-8"
onClick={login}
>
Login
</button>
) : (
<WorldCoinConnect onAction={setWorldcoinVerified} />
);
}
Landing Page with Technology Showcase
The platform prominently features its comprehensive Web3 technology stack:
<div className="bg-zinc-100/70">
<div className="mx-auto max-w-7xl px-6 py-16 lg:px-8">
<p className="text-center text-base font-semibold text-zinc-500">
FellowFund is built on some of the best web3 technologies
</p>
<div className="mt-6 grid grid-cols-2 gap-8 md:grid-cols-5 lg:grid-cols-5">
{/* Technology logos: Blockscout, Celo, The Graph, Ledger, Nouns DAO,
Rootstock, vLayer, Web3Auth, WorldCoin, Phala, Polygon, Protocol Labs, Flow */}
</div>
</div>
</div>
Comprehensive Testing Suite
Smart Contract Testing with Complex Scenarios
The platform includes extensive testing covering all lifecycle phases:
it('should evaluate markets and distribute grants', async function () {
await time.increaseTo(applicationDeadline + 1);
const fellowshipId = 0;
const applicationId = 0;
await fellowFund.connect(operator).openFellowshipMarkets(fellowshipId);
// Get market address and place bets
const marketAddress = await fellowFund.markets(fellowshipId, applicationId);
const market = (await ethers.getContractAt('Market', marketAddress)) as Market;
await market.connect(bettor1).placeBet(Side.Yes, { value: ethers.parseEther('0.1') });
await market.connect(bettor2).placeBet(Side.No, { value: ethers.parseEther('0.05') });
await time.increaseTo(marketDeadline + 1);
const initialBalance = await ethers.provider.getBalance(applicant1.address);
await fellowFund.connect(operator).evaluateMarket(fellowshipId);
const application = await fellowFund.applications(fellowshipId, applicationId);
expect(application.accepted).to.be.true;
// Check if grant was distributed
const finalBalance = await ethers.provider.getBalance(applicant1.address);
expect(finalBalance - initialBalance).to.equal(ethers.parseEther('1')); // Full grant amount
});
Multi-Winner Payout Testing
Advanced testing scenarios validate complex payout mechanics:
const winningPercentageBidder2 = (noBetBidder2 * factor) / noBetAmount;
const winningsBidder2 = (winningPercentageBidder2 * totalBetAmount) / factor;
const winningPercentageBidder3 = (noBetBidder3 * factor) / noBetAmount;
const winningsBidder3 = (winningPercentageBidder3 * totalBetAmount) / factor;
expect(await ethers.provider.getBalance(await market.getAddress())).to.equal(
totalBetAmount - winningsBidder2 - winningsBidder3
);
expect(await ethers.provider.getBalance(bettor1.address)).to.equal(balanceBeforeResolveBettor1);
expect(await ethers.provider.getBalance(bettor2.address)).to.equal(
balanceBeforeResolveBettor2 + winningsBidder2
);
expect(await ethers.provider.getBalance(bettor3.address)).to.equal(
balanceBeforeResolveBettor3 + winningsBidder3
);
Automated Operations Layer
Operator Service Architecture
The platform includes a sophisticated automation service that manages fellowship lifecycle transitions:
const listenForFellowshipEvents = () => {
console.log('Listening for fellowship events');
if (fellowshipEvents.length == 0) {
// Create a sample fellowship event
const sampleFellowship = {
metadata: `{
"githubOrg": "fellowfund",
"kpiTargets": {
"totalCommits": {
"targetValue": 3,
"weight": 0.7
},
"poapEvents": {
"targetValue": 1,
"weight": 0.3
}
}
}`,
funds: 1000000000000000000n, // 1 ETH in wei
applicationDeadline: BigInt(Math.floor(Date.now() / 1000)),
marketDeadline: BigInt(Math.floor(Date.now() / 1000) + 60),
epochEndTime: BigInt(Math.floor(Date.now() / 1000) + 180),
status: 0, // FellowshipStatus.AcceptingApplications
maxApplicants: 2
};
fellowshipEvents.push(sampleFellowship);
executeEveryXSeconds(listenForFellowshipApplications, 5, sampleFellowshipId);
}
};
Smart Contract Integration for State Transitions
Automated contract interactions manage fellowship lifecycle:
const callOpenFellowshipMarkets = (fellowshipId) => {
console.log(`Calling openFellowshipMarkets() for fellowshipId=${fellowshipId}`);
const fellowFundAddress = process.env.FELLOWFUND_CONTRACT_ADDRESS;
const provider = operatorWallet.provider;
const fellowFundContract = new ethers.Contract(fellowFundAddress, fellowFundAbi, provider);
fellowFundContract
.connect(operatorWallet)
.openFellowshipMarkets(fellowshipId)
.then((tx) => {
console.log(`Transaction sent: ${tx.hash}`);
return tx.wait();
})
.then((receipt) => {
console.log(`Transaction confirmed: ${receipt.transactionHash}`);
})
.catch((error) => {
console.error(`Failed to evaluate market: ${error}`);
});
};
Key Innovation Highlights
1. Market-Driven Selection
FellowFund replaces subjective committee decisions with objective market consensus, where financial stakes ensure thoughtful evaluation.
2. Continuous Accountability
Unlike traditional programs where fellows receive funds upfront, FellowFund ties final payouts to verified achievement of stated KPIs.
3. Community Wisdom Aggregation
Prediction markets harness distributed intelligence, often producing more accurate assessments than expert panels.
4. Incentive Alignment
All participants have financial skin in the game:
- Organizations commit funds upfront
- Community members stake on their predictions
- Fellows earn based on actual achievement
5. Transparent Operations
Every decision, vote, and outcome is recorded on-chain, creating unprecedented transparency in fellowship funding.
ETHGlobal Bangkok Hackathon Development
Built for Innovation
FellowFund was developed during ETHGlobal Bangkok 2024, demonstrating rapid innovation capabilities while integrating cutting-edge Web3 technologies.
Technology Integration Challenges
The 48-hour hackathon timeline required seamless integration across:
- Smart Contract Development: Multi-chain Solidity contracts with complex state management
- Oracle Integration: Phala Network TEE for trusted impact verification
- Identity Systems: WorldCoin proof-of-personhood integration
- Multi-Chain Deployment: Simultaneous deployment across 8+ networks
- Real-Time Indexing: The Graph Protocol subgraph development
- Frontend Development: Next.js application with Web3 authentication
Deployment Metrics
Multi-Chain Deployment Success:
- 8 Networks: Successfully deployed across testnets
- Consistent Addresses: Deterministic deployment addresses where possible
- Full Functionality: All core features operational across networks
Results & Impact
Technical Achievements
- Complete Prediction Market Implementation: Fully functional betting, resolution, and payout mechanisms
- Multi-Phase Lifecycle Management: Sophisticated state machine handling all fellowship phases
- Oracle Integration: Working Phala Network TEE verification system
- Multi-Chain Architecture: Seamless operation across 8+ blockchain networks
- Real-Time Data Processing: Live blockchain event indexing and aggregation
Innovation Metrics
- Market Efficiency: Automated price discovery through community prediction markets
- Accountability Enhancement: 100% on-chain verification of achievement claims
- Decision Quality: Community-driven selection based on financial stakes
- Transparency: Complete audit trail of all decisions and transactions
Hackathon Recognition
FellowFund demonstrates several key innovations in decentralized funding mechanisms:
- Prediction Market Primitives: First application of prediction markets to fellowship funding
- Continuous Verification: Ongoing accountability throughout fellowship periods
- Multi-Stakeholder Alignment: Economic incentives that align all participants
- Scalable Decision Making: Market mechanisms that scale beyond committee bottlenecks
Future Development Roadmap
Phase 1: Mainnet Launch
- Production deployment across major L1s and L2s
- Integration with major fellowship programs
- Advanced KPI tracking and verification systems
- Mobile application development
Phase 2: Advanced Features
- Dynamic market making and liquidity provision
- Reputation systems for consistent predictors
- Multi-token support for diverse funding models
- Advanced analytics and reporting dashboards
Phase 3: Ecosystem Expansion
- Integration with existing DAO governance systems
- Cross-chain fellowship coordination protocols
- Institutional adoption and compliance features
- Advanced risk management and insurance products
Phase 4: Market Evolution
- Prediction market aggregation and meta-markets
- AI-powered KPI definition and verification
- Dynamic funding allocation based on market signals
- Global fellowship funding marketplace
Technical Lessons Learned
1. Prediction Market Design
Implementing fair, efficient prediction markets requires careful consideration of market maker mechanisms, resolution criteria, and payout structures.
2. Multi-Chain Complexity
Deploying across multiple networks simultaneously requires sophisticated tooling and careful state management across different execution environments.
3. Oracle Integration Challenges
Connecting off-chain data sources with on-chain contracts requires robust security measures and clear verification criteria.
4. User Experience Optimization
Balancing Web3 functionality with user-friendly interfaces requires thoughtful abstraction of complex technical details.
Conclusion
FellowFund represents a paradigm shift in fellowship funding – from subjective, centralized decision-making to objective, market-driven allocation. By introducing financial stakes into the evaluation process, the platform creates powerful incentives for accurate assessment while ensuring continuous accountability throughout fellowship periods.
Key Technical Contributions
- Prediction Market Infrastructure: Complete implementation of market-based selection mechanisms
- Multi-Chain Smart Contract Architecture: Sophisticated state management across multiple blockchain networks
- Oracle-Verified Impact Tracking: Integration with Phala Network TEE for tamper-proof verification
- Comprehensive Web3 Integration: Seamless combination of identity, payments, and governance systems
Broader Implications
FellowFund demonstrates how market-based mechanisms can enhance decision-making quality in traditionally subjective domains. The principles pioneered here – skin in the game evaluation, continuous accountability, and transparent operations – can be applied to numerous other funding and governance challenges.
The platform proves that hackathon-speed development can produce sophisticated, multi-faceted applications when built on solid Web3 foundations and clear incentive design principles.
The Future of Funding
As Web3 infrastructure matures and prediction market adoption grows, platforms like FellowFund will become essential tools for organizations seeking to improve their funding decisions while building stronger accountability relationships with recipients.
The combination of community wisdom, financial incentives, and transparent verification represents the next evolution of how we identify, support, and track the success of promising builders in the Web3 ecosystem.
FellowFund demonstrates that the future of funding is transparent, accountable, and community-driven. By aligning incentives through prediction markets and continuous verification, we can create funding systems that are more effective, fair, and impactful than traditional approaches.
Tags
Subscribe to my newsletter
I occasionally write about engineering, books, and the intersection of technology and human nature. No spam, just thoughtful conversations.