Source: Full executable TypeScript in contract/src/examples/02-campaign-keep-whats-raised/. This page summarizes the flow — read the source for complete per-step code.
PrerequisitesYour platform must be enlisted with the Keep-What’s-Raised implementation registered and approved — see Platform Enlistment.
The Story
TechForge is a small team of developers building an open-source code review tool. They want to raise $10,000 to fund a working prototype, but they know that even partial funding would let them build a smaller version. Unlike Maya’s All-or-Nothing campaign, TechForge wants the flexibility to keep whatever they raise, even if the full $10,000 is not reached. TechForge chooses the Keep-What’s-Raised funding model on ArtFund. This model offers several features the All-or-Nothing model does not:- Partial withdrawals — early access to raised funds mid-campaign (subject to platform approval and a configurable delay)
- Final withdrawal — after the deadline, the creator sweeps the remaining balance with applicable fees
- Tips — backers can include an optional tip on top of their pledge
- Configurable fee structure — flat fees, percentage-based fees, and fee exemption thresholds
- Refund delays — a configurable waiting period after the deadline before backers can claim refunds
- Updatable parameters — extend the deadline or adjust the funding goal (before the config lock period)
Multi-token support
Same model as All-or-Nothing: the campaign whitelists multiple ERC-20s per currency; each pledge namespledgeToken; withdraw(token, amount) and fee paths are per token.
Role Reference
| Function | Who can call | Contract modifier |
|---|---|---|
configureTreasury | Platform Admin | onlyPlatformAdmin |
approveWithdrawal | Platform Admin | onlyPlatformAdmin |
withdraw(token, amount) | Platform Admin or Creator | onlyPlatformAdminOrCampaignOwner |
claimFund | Platform Admin | onlyPlatformAdmin |
claimTip | Platform Admin | onlyPlatformAdmin |
disburseFees | Anyone | (no role modifier) |
addRewards / removeReward | Creator | onlyCampaignOwner |
pledgeForAReward / pledgeWithoutAReward | Anyone (backer) | (no role modifier — time-gated) |
setFeeAndPledge / setPaymentGatewayFee | Platform Admin | onlyPlatformAdmin |
claimRefund | Anyone (NFT owner) | (no role modifier — time-gated) |
updateDeadline / updateGoalAmount | Platform Admin or Creator | onlyPlatformAdminOrCampaignOwner |
cancelTreasury | Platform Admin or Creator | onlyPlatformAdminOrCampaignOwner |
Steps
Step 1: Create Campaign
TechForge creates a 60-day campaign with a $10,000 goal through the CampaignInfoFactory.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: Deploy Treasury
TechForge deploys a Keep-What’s-Raised treasury linked to the campaign. Slot1n is the KWR implementation.
Step 3: Configure Treasury (Platform Admin)
The Platform Admin configures withdrawal delays, refund policies, and fee structure. The creator cannot call this. This step useswithdrawalDelay: 0n so Step 6a and 6b can run back-to-back in the tutorial; in production, use a positive value.
Step 4: Manage Reward Tiers
TechForge adds reward tiers. Tiers can also be removed withremoveReward.
Step 5: Backer Pledges
Three pledge options:pledgeForAReward, pledgeWithoutAReward, or (Platform Admin only) setFeeAndPledge which records a payment-gateway fee and the pledge atomically. Every pledge requires a unique pledgeId and supports an optional tip.
Step 6a: Approve Partial Withdrawal (Platform Admin)
Before the creator can withdraw mid-campaign, the Platform Admin must approve once. The creator may then callwithdraw(token, amount) after the configured withdrawalDelay has elapsed.
Step 6b: Execute Partial Withdrawal (Creator)
With approval granted (and after any withdrawal delay), the creator withdraws a specific amount of an accepted ERC-20.Step 6c: Final Withdrawal (Post-Deadline)
After the deadline, the creator (or Platform Admin) sweeps the entire remaining balance of a specific token. Theamount parameter is ignored; pass 0n. Call disburseFees() first so protocol and platform fees are already transferred out.
Step 7: Monitor Progress
Anyone can read the campaign dashboard — raised amounts, available balance, fees, approval status, and state.Step 8: Disburse Fees
disburseFees() transfers accumulated protocol and platform fees to their recipients. Anyone can call it. Must be called before cancellation — disburseFees has a whenNotCancelled modifier.
Step 9: Claim Residual Funds (Platform Admin)
After the withdrawal delay has fully elapsed (deadline + withdrawalDelay), the Platform Admin can sweep any remaining balance of every accepted token to the platform admin’s wallet. Only callable once.
Step 10: Claim Tips (Platform Admin)
Tips included by backers on top of pledges are tracked separately and claimed by the Platform Admin (not the creator). Callable after the deadline or after cancellation. Only callable once.Step 11: Claim Refund (Backer)
After the deadline plus refund delay window, backers can reclaim their pledges.claimRefund(tokenId) burns the NFT and returns the pledged tokens (minus payment fees) to the NFT owner. Pledge NFTs live on the CampaignInfo contract, so approval must be done there.