Source: Full executable TypeScript in contract/src/examples/01-campaign-all-or-nothing/. This page summarizes the flow — read the source for complete per-step code.
PrerequisitesYour platform must be enlisted — see Platform Enlistment.
The Story
Maya is a ceramic artist who sells her handmade pottery through ArtFund, a creative crowdfunding platform built on Oak Protocol. She wants to raise $5,000 to fund a new collection called “Earth & Fire” — a series of hand-thrown vases and bowls inspired by volcanic landscapes. Maya chooses the All-or-Nothing funding model. This means every dollar pledged is held in an on-chain treasury until the campaign deadline. If the campaign reaches its $5,000 goal, Maya can withdraw the funds and fulfill rewards to her backers. If the goal is not met, every backer receives a full refund automatically — no questions asked. This model builds trust with backers because their funds are protected by the smart contract. Maya cannot access the money unless the community collectively meets the target.Multi-token support
Maya’s campaign accepts whatever ERC-20s the platform mapped to her campaign currency at creation time. Each pledge passespledgeToken; the All-or-Nothing treasury checks CampaignInfo.isTokenAccepted. Raised totals aggregate across accepted tokens (normalized on-chain); refunds return the same token the backer used.
Role Reference
| Function | Who can call | Contract modifier |
|---|---|---|
addRewards / removeReward | Creator | onlyCampaignOwner |
pledgeForAReward / pledgeWithoutAReward | Anyone (backer) | (no role modifier — time-gated) |
claimRefund(tokenId) | Anyone (refund goes to NFT owner) | (no role modifier) |
disburseFees | Anyone | (no role modifier — requires deadline passed + goal met) |
withdraw | Anyone (funds go to campaign owner) | (no role modifier — requires fees disbursed) |
pauseTreasury / unpauseTreasury | Platform Admin | onlyPlatformAdmin |
cancelTreasury | Platform Admin or Creator | custom check (both roles) |
Steps
Step 1: Create Campaign
Maya creates the campaign through the CampaignInfoFactory, setting the funding goal, deadline, platform, and NFT metadata for backer receipts. The factory emits aCampaignCreated event that contains the deployed CampaignInfo address.
CampaignInfo address can be discovered two ways. Both are shown in the source file — prefer Approach 1 when you have the receipt.
Approach 1 — Decode CampaignCreated from the receipt (recommended): deterministic and works immediately, regardless of RPC indexing lag.
identifierToCampaignInfo (convenience): handy when you only have the identifier and did not keep the receipt. On some RPC providers the mapping may briefly return the zero address right after the transaction, so prefer Approach 1 when the receipt is available.
Step 2: Look Up the Campaign Address
A standalone lookup is useful for any caller (not just the creator) who only has the identifier hash and wants to resolve it to the deployedCampaignInfo address — for example, a front end displaying campaign data. Maya also validates that the factory recognizes the address as a legitimate campaign.
Step 3: Review Campaign Details
Before sharing the campaign link, Maya reads back the on-chain campaign details to catch any configuration mistakes before backers start pledging.Step 4: Deploy the Treasury
Every campaign needs a treasury — the smart contract that holds all pledged funds until the campaign outcome is decided. Maya deploys an All-or-Nothing treasury through the TreasuryFactory.Step 5: Manage Reward Tiers
Maya sets up reward tiers. Each tier has a minimum pledge value. When a backer pledges at a tier, they receive an NFT receipt representing their pledge and chosen reward. Rewards can also be removed before backers pledge for them.Step 6: Backer Pledges
Backers can pledge in two ways: choosing a specific reward tier withpledgeForAReward, or contributing a flat amount without a reward via pledgeWithoutAReward. In both cases the treasury transfers ERC-20 tokens and mints an NFT receipt on the CampaignInfo contract.
Step 7: Monitor Campaign Progress
Anyone can check the campaign’s progress at any time with read-only calls — no wallet required. This combines reads from bothCampaignInfo (goal, deadline) and the AllOrNothing treasury (raised amount, paused/cancelled, fees, reward tiers).
Step 8: Disburse Fees
Before anyone can withdraw funds from a successful campaign, the protocol and platform fees must be disbursed first.disburseFees() has no role restriction — anyone can call it. The contract verifies internally that the deadline has passed and the goal is met.
Step 9a: Success — Withdraw Funds
After fees have been disbursed, the remaining funds are available for withdrawal.withdraw() has no role restriction — anyone can call it. The contract always sends the funds to the campaign owner, regardless of who initiates the transaction.
Step 9b: Failure — Claim Refund
If the goal is not met, every backer is entitled to a full refund.claimRefund(tokenId) has no role restriction; the contract always sends the refund to the current NFT owner, then burns the NFT.
Prerequisite: the backer must approve the treasury on the CampaignInfo contract (where pledge NFTs live) before calling claimRefund.
Step 10: Pause and Unpause
If an investigation is needed, the Platform Admin can temporarily freeze all treasury activity.pauseTreasury(message) takes a bytes32 reason code emitted in the Paused event.