Development of Decentralized Crowdfunding Platform for Creators
Mirror.xyz raised $10M for independent authors through NFT-based crowdfunding back in 2021. Unique approach: instead of Kickstarter model with promises, authors sell share of future revenue or release NFTs giving content access. Decentralized crowdfunding platform — it's not just "Kickstarter on blockchain". It's fundamentally different economic model: transparent fund distribution through smart contracts, verifiable milestones, money return without intermediaries.
Key Mechanics and Implementation
Campaign Contract: Escrow with Milestone Logic
Naive implementation: collect ETH to creator's address. That doesn't work in Web3 — users don't trust unknown address. Need escrow contract that holds funds and releases only on conditions.
Milestone-based escrow architecture:
struct Campaign {
address creator;
uint256 goal; // goal in ETH/tokens
uint256 deadline; // unix timestamp
uint256 raised;
bool goalReached;
Milestone[] milestones;
}
struct Milestone {
string description;
uint256 releaseAmount; // amount to pay on completion
bool completed;
uint256 votes; // backer votes for confirmation
uint256 votesAgainst;
}
Instead of automatic fund transfer on goal achievement — voting by backers on milestone completion. If 50%+ backers (weighted by contribution amount) confirm — escrow sends releaseAmount to creator. If majority against — funds return proportionally to contributions.
This mechanism was implemented in Giveth and The DAO (before the hack) — and it works while governance is active.
NFT as Proof-of-Backing and Access Token
Each contribution creates NFT (ERC-721 or ERC-1155) for backer. NFT carries metadata: contribution amount, date, campaign ID. Functions of NFT:
Access control: content platform checks balanceOf(address, campaignId) to unlock exclusive content. Without NFT — no access.
Revenue sharing: if campaign involves royalty from future sales or publications, NFT serves as claim token. Contract distributes incoming ETH proportionally by NFT weight.
Transferability: backer can sell position on secondary market (OpenSea, Blur). This creates real liquidity for crowd-financing, which traditional crowdfunding lacks.
Standard: ERC-1155 preferable to ERC-721 for crowdfunding — one contract for all campaigns, cheaper mint (batch), fungible tier support (fungible outcomes for equal contributions).
Refund Mechanism Without Trust
If campaign doesn't reach goal by deadline — each backer can call refund() and get their funds back. No intermediaries, no support requests.
Implementation pattern — pull refund (not push): contract doesn't send funds automatically to all backers (gas griefing with thousands of participants). Each backer calls refund() themselves, contract transfers their share.
function refund(uint256 campaignId) external {
Campaign storage c = campaigns[campaignId];
require(block.timestamp > c.deadline, "Campaign active");
require(!c.goalReached, "Goal was reached");
uint256 amount = contributions[campaignId][msg.sender];
require(amount > 0, "No contribution");
contributions[campaignId][msg.sender] = 0; // CEI pattern
(bool success,) = msg.sender.call{value: amount}("");
require(success, "Transfer failed");
}
Zero balance before transfer — this is Checks-Effects-Interactions. Without it: reentrancy via receive() in backer contract.
Platform Level: Campaign Factory and Indexing
Factory + Clone Pattern for Gas-Efficient Deploy
Each campaign is separate contract. Deploy via new Campaign() costs 500k–800k gas. On Ethereum mainnet at $2000 ETH and 30 gwei — $30–50 per campaign. Unacceptable for indie authors.
Solution: EIP-1167 Minimal Proxy (Clone). CampaignFactory deploys lightweight proxy-clone in 45k gas. Proxy delegatecalls to implementation contract. Campaign creation cost — $3–5.
Downside: proxy can't be upgraded separately. All clones use one implementation. To update logic — deploy new factory, old campaigns stay on old logic (not a bug, a feature — immutability of completed campaigns).
The Graph Subgraph for Indexing
Platform with hundreds of campaigns needs efficient search and filtering. On-chain view functions don't scale. Solution — The Graph subgraph indexing events:
type Campaign @entity {
id: ID!
creator: Bytes!
goal: BigInt!
raised: BigInt!
deadline: BigInt!
backers: [Backer!]! @derivedFrom(field: "campaign")
milestones: [Milestone!]! @derivedFrom(field: "campaign")
}
Frontend makes GraphQL queries to subgraph instead of direct RPC calls. This allows filtering campaigns by author, status, category, sorting by amount — everything impossible efficiently on-chain.
Multi-Currency Crowdfunding
Accepting only ETH — lose audience. ERC-20 integration (USDC, DAI) via SafeERC20 from OpenZeppelin. One campaign = one currency (simplifies escrow logic). For multi-currency campaigns — conversion via Uniswap v3 on contribution.
Important nuance: USDC has blacklist functionality — recipient contract can be blocked by Circle. For long-term escrow this is rare but real risk. Use DAI or mention USDC caveat in docs.
Moderation and Dispute Resolution
On-Chain Arbitration via Kleros
If backers and creator can't reach consensus on milestone — need arbitration. Kleros Protocol provides decentralized court: deposits from both sides, randomly selected jurors from Kleros PNK stakers make verdict, loser loses deposit.
Integration via IArbitrable interface: campaign contract implements rule(uint256 disputeId, uint256 ruling) — called by Kleros after voting. Based on ruling contract either releases milestone payment or initiates refund.
Development Process
Design mechanics (3–5 days): milestone structure, NFT economy, refund conditions, governance parameters (voting quorum, voting period).
Core smart contracts (1–1.5 weeks): Campaign, CampaignFactory (EIP-1167), MilestoneVoting, RefundEscrow.
NFT and revenue sharing (3–4 days): ERC-1155 contract, claim mechanism, royalty distribution.
The Graph subgraph (2–3 days): schema, mappings, deploy to Hosted Service or Decentralized Network.
Frontend integration (1–2 weeks): wagmi/viem hooks, campaign creation, backing page with wallet connect, creator dashboard.
Testing (3–5 days): unit tests all scenarios (success, failure, milestone dispute), fork tests on mainnet.
Deploy (2–3 days): Foundry script, verification, subgraph deploy.
Total: 3 weeks — 3 months depending on feature set. MVP with basic crowdfunding without milestone voting — 3–4 weeks. Full platform with arbitration, revenue sharing NFT and frontend — 2–3 months. Cost calculated after requirements detailing.







