Protocol
Lifecycle
Every state a pot can be in, and the way out of each one.
States
A pot has no status field. Its state is derived from three booleans, the balance and the clock, which means it cannot get stuck in a state nobody expected.
| State | Condition | What is possible |
|---|---|---|
| Open | not released, not cancelled, raised < target, now <= deadline | contribute, cancel if empty |
| Goal reached | raised >= target | release, by anyone. Contributions are refused. |
| Refunding | now > deadline and raised < target | refund, one contributor at a time |
| Released | released == true | nothing, the pot is empty |
| Cancelled | cancelled == true | nothing, it was empty when it closed |
The three endings
- 1Released. The balance met the target. Anyone calls release, the treasury takes its fee, the beneficiary takes the rest. One release per pot, forever.
- 2Refunded. The deadline passed short of the target. Each contributor calls refund and receives exactly their recorded share. The pot empties as people claim.
- 3Cancelled. The creator closes a pot that never received anything. Only possible while raised and contributors are both zero, so nobody can be cancelled out of their money.
Edge cases
- The target is met after the deadline. Release still works. The deadline blocks contributions, not payouts.
- The pot overshoots. Release sends the whole balance, not just the target. The fee applies to the whole balance.
- A contribution lands on the deadline second. Allowed. The check is
block.timestamp > deadline, so the deadline second itself still counts. - Refunding after the goal was reached. Impossible.
refundreverts withTargetMet. Once the pile is high enough it belongs to the beneficiary. - Refunding after release. Impossible, and there would be nothing to take: the contract balance for that pot is zero.
- Nobody calls release. The pot sits there. Anyone can trigger it at any time, including the beneficiary, and the money can only go to the beneficiary.