See also: API Reference Examples — executable TypeScript walkthroughs.
The Business
ArtFund is a creative crowdfunding platform where filmmakers, musicians, and artists raise funds for their projects. Campaigns have a funding goal and a deadline. If the goal is met, the creator receives the funds. If not, every backer gets a full refund. Backers can select reward tiers (digital downloads, signed merchandise, premiere tickets) when pledging.Why Oak?
ArtFund needs:- All-or-nothing funding — the creator only gets funds if the goal is met; backers are automatically refunded otherwise
- Campaign creation — on-chain campaign with goal, deadline, metadata, and NFT-backed pledges
- Reward tiers — backers select a tier when pledging; each tier has a minimum value and can include physical items
- Pledge tracking — each pledge mints an NFT representing the backer’s contribution and selected reward
- Transparent progress — raised amount, goal, deadline all readable on-chain
- Dual fee model — protocol fees and platform fees tracked and disbursed separately
Oak Contracts Used
| Contract | Purpose |
|---|---|
| CampaignInfoFactory | Creates campaign instances with metadata, goal, and deadline |
| CampaignInfo | Stores campaign state, pledge NFTs, platform/fee configuration |
| TreasuryFactory | Deploys the AllOrNothing treasury for the campaign |
| AllOrNothing | Holds pledged funds; enforces goal-or-refund logic |
Multi-token support
The protocol is multi-token:GlobalParams defines each currency as one or more ERC-20 addresses (initialize seeds tokensPerCurrency; the protocol admin uses addTokenToCurrency / removeTokenFromCurrency; getTokensForCurrency reads the list). CampaignInfoFactory copies that list onto CampaignInfo at creation; each pledge passes pledgeToken and the treasury checks CampaignInfo.isTokenAccepted. In the SDK, campaign.getAcceptedTokens() returns the cached whitelist for UI and validation.
Raised balances and refunds are tracked per token; amounts use that token’s decimals (reward values in pledge flows are denormalized from 18-decimal form where applicable). This guide uses USDC as an example—substitute any accepted token for your deployment.
Roles
| Role | Who | On-Chain Functions |
|---|---|---|
| Platform Admin | ArtFund backend | deploy (treasury), pauseTreasury, unpauseTreasury, cancelTreasury |
| Creator (Campaign Owner) | Maya (indie filmmaker) | createCampaign, addRewards, removeReward, cancelTreasury |
| Backer | Community supporters | ERC-20 approve, pledgeForAReward, pledgeWithoutAReward, claimRefund |
| Protocol Admin | Oak protocol | Receives protocol fees (via disburseFees) |
| Any caller | Anyone | disburseFees, withdraw, all read functions (getReward, getRaisedAmount, paused, etc.) |
Integration Flow
Step 1: Creator submits campaign — create on-chain
Role: Any caller — createCampaign is permissionless; the factory validates that the selected platform(s) are enlisted and that campaign timing constraints are met.
Maya wants to fund her documentary “Voices of the Valley.” She needs 10,000 USDC and sets a 30-day deadline. ArtFund’s backend creates the campaign on-chain.
Step 2: Look up the deployed CampaignInfo
Role: Any caller — all read functions are public.The factory emits a
CampaignCreated event that carries the new CampaignInfo address. Two approaches are available — prefer the receipt-based one when you have the receipt in hand.
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 hash and did not keep the receipt.
Step 3: Deploy the AllOrNothing treasury
Role: Platform Admin — only the platform admin can deploy treasuries via the factory.ArtFund deploys an AllOrNothing treasury linked to Maya’s campaign. The treasury enforces the all-or-nothing rule: if the goal is met by the deadline, the creator withdraws; if not, backers refund.
Step 4: Add reward tiers
Role: Creator (Campaign Owner) — only the campaign owner can add or remove rewards.Maya defines three reward tiers for backers.
Step 4b: Read and remove reward tiers
Role: Any caller forArtFund can verify a reward tier’s configuration, and Maya can remove one that’s no longer needed.getReward(read). Creator (Campaign Owner) forremoveReward(write).
Step 5: Backers pledge
Role: Backer — any wallet can pledge. The backer must first approve the treasury to transfer their ERC-20 tokens.Supporters pledge to Maya’s campaign, optionally selecting reward tiers. Before any pledge, the backer must approve the AllOrNothing treasury contract to spend the pledge amount on their behalf. This is a standard ERC-20 approval:
Step 6: Monitor campaign progress
Role: Any caller — all read functions are public.ArtFund’s campaign page shows live progress.
Step 7: Disburse fees
Role: Any caller — disburseFees is permissionless, but it only succeeds after the deadline when the goal is met. Fees are sent to the Protocol Admin and Platform Admin automatically.
Once the deadline has passed and the goal is met, anyone can trigger fee disbursement. This distributes the protocol fee to the Oak Protocol Admin and the platform fee to ArtFund.
Step 8 (Success): Goal met — creator withdraws
Role: Any caller —Ifwithdrawis permissionless, but it requiresdisburseFeesto have been called first. Funds are always sent to the campaign owner (Maya).
raised >= goal when the deadline passes, anyone can trigger the withdrawal. The remaining funds (after fees) are sent to Maya.
Step 8 (Failure): Goal not met — backers claim refunds
Role: Any caller — claimRefund is permissionless, but the refund is always sent to the current NFT owner.
If the deadline passes and the goal was not reached, each backer can claim a refund by providing their pledge NFT token ID. The NFT is burned during the refund.
Before calling claimRefund, the backer must approve the treasury to manage their pledge NFT. Pledge NFTs live on the CampaignInfo contract, so approve is called on the CampaignInfo entity:
Step 9: Pause, unpause, or cancel the treasury
Pause the treasury:Role: Platform Admin — only the platform admin can pause and unpause.If ArtFund needs to halt operations for compliance or investigation, the platform admin pauses the treasury. While paused, no pledges, refunds, fee disbursement, or withdrawals can occur.
Role: Platform Admin
Role: Platform Admin or Creator (Campaign Owner) — either party can cancel the treasury.Cancellation is irreversible. After cancellation, backers can still claim refunds, but no new pledges, fee disbursement, or withdrawals can happen.
Reading pledge NFT data
Role: Any caller — all read functions are public.Pledge NFTs are standard ERC-721 tokens minted by the CampaignInfo contract — not by the treasury. All NFT operations (
ownerOf, approve, balanceOf, tokenURI, etc.) go through the CampaignInfo entity. Backers can manage them using campaignInfo.approve(...) and campaignInfo.setApprovalForAll(...). If a pledge NFT is transferred, the new owner becomes eligible to claim the refund (on failure) or holds the reward entitlement.
Each pledge NFT stores on-chain metadata accessible through CampaignInfo:
Architecture Diagram
ArtFund Crowdfunding Campaign FlowKey Takeaways
- All-or-nothing is enforced by the contract — there is no way for the creator to withdraw if the goal is not met
- ERC-20 approval is required — backers must
approvethe treasury to transfer tokens before pledging - Multi-token campaigns — each pledge names
pledgeToken; only addresses whitelisted viaisTokenAcceptedare allowed; raised balances and refunds are per token (native decimals) - NFT-backed pledges give backers a verifiable, transferable proof of their contribution
- Reward tiers can be added, read, and removed dynamically by the campaign owner before the campaign ends
- Multi-reward pledges — backers can select multiple rewards in a single pledge call
- Role-based access —
addRewards/removeRewardare owner-only;pauseTreasury/unpauseTreasuryare platform-admin-only;cancelTreasurycan be called by either;disburseFees,withdraw, andclaimRefundare permissionless - Pause / cancel controls — the platform admin can pause operations; both platform admin and campaign owner can permanently cancel
multicallcombines treasury and campaign reads for efficient dashboard rendering- Two-phase fee model —
disburseFees()beforewithdraw()ensures fees are handled correctly - Campaign metadata (name, symbol, image URI) makes the pledge NFTs meaningful and displayable in wallets