ReferenceThe contract
One file, contracts/src/Flock.sol, Solidity 0.8.26. No owner, no admin, no proxy, no fee of ours. The only external dependencies are the Pons factory (address fixed at deployment) and the curve it creates.
Constants
| name | value | meaning |
| MAX_SIZE | 0.25 ETH | largest buy a flock can make |
| COMMIT_MULTIPLE | 100 | deposits may reach 100 × size |
| MIN_DEPOSIT | 0.001 ETH | smallest deposit, smallest minimum and per-wallet cap |
| MAX_TAX_BPS | 500 | creator tax a flock may carry (Pons allows 1000) |
| MIN_WINDOW / MAX_WINDOW | 5 minutes / 7 days | distance between open and the deadline |
| GRACE | 1 day | after the deadline, anybody can still launch; then it is refundable |
State
struct Info {
address creator; State state; // Open, Launched, Cancelled
uint64 deadline; uint96 minTotal; uint96 size; uint96 maxPerWallet;
uint128 total; uint128 used; uint128 reserve;
uint256 launchConfigId; uint256 minTokensPerEth;
bytes32 paramsHash; address token; address curve; uint256 tokensOut; uint128 reserveLeft;
}
mapping(uint256 => Info) public flocks;
mapping(uint256 => mapping(address => uint256)) public deposits;
uint256 public count;
Functions
| function | who | what |
open(params, terms) payable | anyone | stores the terms and the params hash, emits Opened with the params; msg.value ≥ Pons launch fee is the reserve |
join(id) payable | anyone | deposit before the deadline; bounded by the per-wallet cap and 100 × size |
leave(id) | depositor | full refund before the deadline |
launch(id, params) | anyone | after the deadline, within the grace: creates the token and buys min(total, size) |
claim(id) / claimFor(id, who[]) | depositor / anyone | tokens and refund for each depositor; tokens only go to the depositor |
cancel(id) | creator | before the deadline |
refund(id) | depositor | when the flock failed or was cancelled |
reclaim(id) | creator | fee reserve back (all of it if failed, the unused part if launched) |
failed(id), shareOf(id, who) | view | status, and the (tokens, refund) a depositor would receive |
What launch does, in order
- checks the state, the deadline, the grace, the minimum and the params hash
- reads the Pons launch fee and checks the reserve covers it
- computes
used, sets the state to Launched before any external call - calls
factory.launchToken with itself as snipe-tax exemption - calls
curve.buy(used, minOut, this) - reads its own balance of the new token and checks it against the floor (
PriceFloor) - stores the token, the curve and the tokens bought
Events
Opened(uint256 indexed id, address indexed creator, bytes32 paramsHash, Terms terms, bytes encodedParams)
Joined(id, who, amount, total) Left(id, who, amount, total)
Launched(id, token, curve, total, used, tokensOut)
Claimed(id, who, tokens, refund) Refunded(id, who, amount) Cancelled(id)
Errors
| error | meaning |
| BadTerms / BadParams | terms or params outside the allowed range, or launch params that do not match the hash |
| NotOpen / TooEarly / TooLate / Closed | wrong state or wrong moment; Closed = past the grace or below the minimum |
| OverCap / TooSmall | deposit above a cap or below 0.001 ETH |
| NotCreator / NotFailed / NothingToDo | caller, status or balance does not allow it |
| FeeNotCovered | the creator's reserve is below the Pons launch fee |
| PriceFloor | the buy gave fewer tokens than minTokensPerEth |
| SendFailed / Reentrancy | an ETH or token transfer failed; a re-entrant call was refused |