the state machine
four states. once a vault hitsLAUNCHED or REFUND it never leaves. these
are terminal.
OPEN
the vault is accepting deposits. anyone with BNB can calldeposit(). the
deposit is tracked per-address:
withdraw() your deposit back. this is a clean
exit, no fees, no penalty. once the vault transitions out of OPEN, withdraw
is no longer available, but refund is (if you reach REFUND state).
deposits are rejected if:
- the vault is not in OPEN state
- adding your deposit would exceed
presaleCapfor the tier - the close window has passed (
block.timestamp >= closeTimestamp)
the close transition
close() is permissionless. anyone can call it. it requires either:
totalDeposited >= presaleCap(the cap was hit), orblock.timestamp >= closeTimestamp(the window has passed)
close() snapshots the deposit total into totalDepositedAtLaunch and emits
the Closed event. the vault is now in CLOSED.
the bundle bot can skip
close() and call pullBnbForLaunch directly from
OPEN if the cap is hit. this is legal but unusual. the math handles both
paths with the same correctness guarantees.CLOSED
the bundle bot is processing this launch. it has the vault in its queue. it will callexecuteBundle() on the router, which calls
vault.pullBnbForLaunch() first.
at this point you cannot:
- deposit more
- withdraw
- claim (no token has been distributed yet)
- refund (unless the bundle fails, see below)
LAUNCHED
the bundle ran. the vault has tokens.vault.distribute(token, vaultAmt)
was called inside the bundle, so:
vault.tokenis set to the FlapTaxTokenV3 addressvault.presalerShareis the total tokens allocated to all presalersvault.launchTimestampis the block timestamp of execution
claim() to pull your pro-rata share. see
vesting explained for the unlock schedule.
REFUND
the vault has reached refund state through one of three paths:- under-subscribed. the close window passed without the cap being met.
anyone can call
enableRefundUnderSubscribed(). - bundle failed. after three failed bundle attempts, the bot calls
enableRefundBundleFailed(). - admin emergency stop. the platform owner first calls
scheduleAdminRefund(reason), then waits the on-chain delay before callingadminEnableRefund(reason). it only works if the vault is not yetLAUNCHED.
refund() independently to get their
BNB back plus a pro-rata bonus from the bonus pool.
bonus pool
if your launch was undersubscribed and there was a bonus pool stake, the bonus is paid out proportional to your principal share. the math:what you can call, by state
events you should care about
Deposited(user, amount, newTotal)your deposit landedWithdrew(user, amount, newTotal)you backed out before closeClosed(by, totalDeposited, bonusPool)the vault is in CLOSEDLaunchExecuted(0, amount, timestamp)the router pulled BNB, vault is in LAUNCHEDDistributed(token, vaultAmt)tokens are in the vault and ready to claimClaimed(user, amount, totalClaimed)you pulled a claimRefundEnabled(by, reason)the vault is in REFUNDRefunded(user, principal, bonus, total)you pulled a refund

