Skip to content

Contracts ​

Addresses

BSC mainnet (chainId 56), deployed at block 130926361. The contracts that have an owner (the factory, the platform lists and both splitter factories) are owned by the Samefirst DAO multisig; the deployer holds no rights:

ContractRoleAddress
SamefirstFactoryfactory0xad8B527F69689d684dFa1E90678Cf281B33F673b
SamefirstLaunchClassic template (cloned per round)0xF0d80E71B7b038305dcb9ADb265fa9b2190332C7
SamefirstGateeach round's verification and entry-list gate0x05ca0BB28E2658666a38713827a96F191F312222
AgentIdIdentity / BabtIdentity / HoldingIdentityidentity sources: Binance Agent ID, BABT, token holdings0 Agent ID 0x95Bf076f8bE85555124fD5FAC0C611A001D1915a
1 BABT 0x51622297bB5Da039Ad6d74482d1364b0136Febb4
2 holding 0xFF7cb67D6307E91A5490ac38c6AD8721b16AD8c8
SamefirstListsplatform lists0x374d8f5DC377839124AbE25c9e54074FB68F82e4
SamefirstBindingwallet binding0x4e51C430b48B980047B9B471F40666e150B6FCCd
FlapAdapterFlap adapter0xBdCd1E7EA18F499D5FF34e912E107CC18Bba5042
SamefirstSwapperSwaps at non-BNB-pool launches0xA20081bC69790DEf1E984159916de04fF518e788
SamefirstSplitterFactorytax splitter factory0x5cb1d6c35837D6373D4Aa930ff0390E2B361259A
SamefirstXSplitterFactoryX-account splitter factory0x3BeCAc0ec785291631063cFb88b79ed1beF2079A
SafeSamefirst DAO multisig0x5e10756B82D8E7351dCFA482794767E74b8539F3

Components ​

ContractRole
SamefirstFactoryGeneric factory. Registers game templates (registered by the multisig, effective immediately; immutable once registered, can be disabled) and identity sources (also effective immediately, can be disabled), and creates each round with createLaunch(templateId, params[, salt]) as an EIP-1167 clone of a template (CREATE2): with a salt, the round's address is known in advance from predictLaunch(templateId, creator, salt); salts are per creator, so nobody else can take it. Holds the settings every template shares: fee (1%–5%), DAO address, raise range (at least 0.1 BNB), how long a full round waits for its launch (abandonAfter, 1 hour by default, 30 minutes–7 days), pause for new rounds, the launch signer for non-BNB pools (launchSigner, set by the multisig; clearing it stops every non-BNB launch, and this one setting applies to existing rounds too), and the issuer identity source (which decides who counts as the same issuer; Agent ID by default). Settings only affect rounds created afterwards.
SamefirstLaunch (Classic template)One round: subscribe, exit, launch, distribute, claim, refund. Creating costs nothing (the token's address is chosen at launch; nothing is locked). Shares are counted per identity: the gate settles the identity on the first subscription (an Agent ID, or the address itself), one share per identity, and the first subscribing address is the round's payee for that identity. For the first 10 minutes after the round fills only the issuer's launch address (launcher) can launch, then anyone can; up to 0.01 BNB of gas for the launch address can be prepaid at creation. Checked at creation: each tax at most 10% (Flap's limit), a 1%–5% slippage cap on non-BNB pools, the pool token must be a contract. Funds can only go to Flap, the swapper (at a non-BNB-pool launch), subscribers or the DAO.
SamefirstBindingLets each Agent ID bind one ordinary wallet: the ID signs an EIP-712 authorization (no gas), the wallet submits it. One wallet belongs to one ID; 3-day cooldowns on both the ID side and the wallet side; either side can unbind at any time. No admin.
FlapAdapterRead-only helper: checks the issuer's Flap parameters and builds the token-creation call; for non-BNB pools checks the launch plan (checkPlan: signed for this round and this sender by the factory's launch signer, unexpired and valid for at most 10 minutes, a path of genuine PancakeSwap pools from WBNB to the pool token) and, for a custom pool token, sets an independent floor from Flap's signed price (flapFloor, BNB via Chainlink BNB/USD, at least 85%). Vaults: any vault factory usable on Flap's VaultPortal can be chosen, unless it has no code, is on the platform's VAULT_BAN list, is disabled by Flap, or doesn't support the pool; the multisig can also switch to allowing official vaults only.
Identity sourcesImplement ISamefirstIdentity (identify(payer, config) returns the identity, checkConfig(config) validates the config), registered in the factory by number: 0 AgentIdIdentity (the Agent ID itself or the wallet bound to it; also the issuer identity), 1 BabtIdentity (addresses holding a BABT), 2 HoldingIdentity (config is a token and a minimum balance, checked at subscription).
SamefirstSplitterFactoryFactory for tax splitter contracts. Each round's splitter address is derived with CREATE2 from the round's address plus the DAO share, so it can be set as Flap's tax recipient when the round is created and the contract deployed later; tax received before deployment all belongs to it once deployed. Anyone can deploy it after launch (deploy(launch, share), which checks the round was registered by the factory and the token matches). The DAO share is the issuer's choice (on the site, subscribers 1–80%, so the DAO keeps at least 20%); an address that names less than 20% for the DAO is deployed with 20%, so the tax still flows. Owned by the multisig, which can only change the default share the site uses for new rounds (DAO 50% by default, never below 20%); existing splitter contracts are unaffected.
SamefirstSplitterOne token's tax recipient. Any BNB or token it receives is divided by split(asset) according to the share: the DAO's part goes straight to this round's DAO, and the subscribers' part is recorded as "claimable per allocated token"; subscribers claim it themselves from their subscribing address with claim(assets) (a contract address that can't receive an asset can use claimTo(assets, recipient) to have it sent elsewhere). Claimable = (allocated tokens × cumulative claimable per token − already settled) × holding factor; holding factor = amount held at claim time (including tokens still undelivered in the round contract) ÷ amount allocated, at most 1, and it can only go down, never up; the withheld part goes to the DAO. No admin; receiving BNB does nothing (with or without calldata), so tax payments can never fail; payments to the DAO are capped at 60,000 gas, and one the DAO can't take stays owed and is retried later. Known limit: the holding factor reads the balance only at claim time, so someone who sold can restore it by borrowing or buying back tokens just before claiming (this only costs the DAO the withheld part, never another subscriber).
SamefirstXSplitterFactoryFactory for X-account splitters. The address is derived with CREATE2 from the round's address + the X account (keccak256("x:" + numeric id)) + the account's share (at most 80%) + the claim window (1–90 days, 7 by default), so it can be Flap's tax recipient when the round is created. Anyone can deploy it after launch; the claim window starts at deployment. A share above 80% or a window out of bounds (only by going around the site) is brought within the bounds at deployment. Owned by the multisig, which can replace or clear the platform's claim key (setClaimer; cleared, nobody can bind) and change the window the site offers new rounds; money in existing splitters is unaffected.
SamefirstXSplitterOne token's tax recipient when the tax goes to an X account. Anyone can split(asset): the account's share is held, the DAO's goes straight to the round's DAO. After the account's owner signs in with X, the platform's claim key calls bind(wallet) (the first wallet within the window; a bound one can be changed), and every later split pays that wallet; if the window closes unbound, the held and all later account shares go to the DAO (Forfeited). BNB that can't be paid stays owed for the wallet's own withdraw; BNB transfers are capped at 100,000 gas. No admin; receiving BNB does nothing, so tax payments never fail.
SamefirstSwapperAt a non-BNB-pool launch, swaps the round's BNB along the launch plan's path (PancakeSwap V2 / V3, up to 3 hops) and hands the pool token back to the round, counting what actually arrived (transfer taxes included). No admin, holds nothing; reverts unless the whole amount is swapped.

Entry lists ​

ContractRole
SamefirstListsGeneral platform lists: any number of lists, each with its own rule on whether the operator may add and remove. A few to start: SUBSCRIBER_BLOCK (platform blacklist: the operator can only add; removal takes the multisig), NAME_BAN (banned token names: the operator can add and remove) and VAULT_BAN (banned vault factories: the operator can add and remove). Also holds parameters: MAX_UNBLOCKS (how often an issuer may take the same person off their round blacklist, default 1, 0–10) and Flap's name-check module. Every change carries an optional public reason and an event. Owned by the multisig.
SamefirstGateEach round's gate. At creation: the issuer isn't on the platform blacklist, the name and symbol aren't in NAME_BAN, Flap won't refuse the name (asked on-chain from Flap's anti-scam module); it records the round's verification methods (up to 5 identity sources with their configs, whether there's a whitelist, whether it's open to every address), its first whitelist batches (Merkle roots, up to 100), the round blacklist (up to 500 at creation) and MAX_UNBLOCKS at that moment. At subscription: platform blacklist and round blacklist (for both the paying address and the Agent ID it acts for), then it tries the identity sources, the whitelist proof (the Agent ID leaf first, then the address itself; the proof leads to any batch the round holds) and open-to-all in order; the first that passes settles the identity for good. The issuer (the creating address, or a wallet bound to the issuer's Agent ID) manages the lists while preparing and open: addWhitelist adds a batch, removeWhitelist only while preparing, openToAll opens the round to every address for good; blockHere adds to the blacklist, unblockHere is free while preparing and at most MAX_UNBLOCKS times per person once open.
SamefirstLaunch (Classic template), entry-list partBesides the above: the params carry the lists (abi.encode(SamefirstGate.Lists): identity sources and configs, whitelist or not, open or not, opening time, first batches, round blacklist); an exclusive round may prepare up to 7 days (no subscriptions before openAt), and the issuer can endPreparing(false) to open early or endPreparing(true) to cancel (stage Cancelled); subscriptions call SamefirstGate.check first; exclusive rounds subscribe with subscribe(bytes32[] proof). Exit, claim and refund ignore the lists, so blocking can never trap anyone's money.

The lists only affect who may subscribe and who may create, never people already in. Public page: samefirst.com/lists.

Round functions ​

FunctionCallerDoes
subscribe() payableAddresses that meet the round's verification methodsSubscribe or top up; the filling subscription only takes up to the target and returns the rest
exit()SubscribersExit before full, refunded minus the fee
launch(salts, plan)The launch address (within 10 minutes of filling), then anyoneLaunch once full. plan: empty for a BNB pool; for a non-BNB pool the launch plan the platform's launch signer signed for this round (swap path, least amount out, deadline, and Flap's signed price for a custom pool token). salts are candidate salts for the token address (Flap requires it to end in 7777 / 8888); the first one still free is used in the same transaction, nothing locked in advance (empty list = the one stored in the parameters). If someone copies every candidate from the pending transaction and uses them first, the launch reverts entirely and is retried with new ones; the keeper sends 4 candidates, privately when a private endpoint is configured
distribute(n)AnyonePush tokens and unused BNB in batches
claim()SubscribersClaim your own share
abandon()AnyoneFull refunds if not launched when the wait after filling ends (terms().abandonAfter, 1 hour by default)
refund() / refundBatch(n)Subscribers / anyoneClaim / push refunds in batches
withdraw()AnyoneWithdraw BNB that couldn't be pushed and was recorded instead
withdrawTokens()SubscribersWithdraw tokens that couldn't be transferred at distribution and were recorded instead
sweep() / sweepToken(t)AnyoneAfter full settlement, send dust and stray tokens to the DAO

Views: idOf(addr) (the ID this address acts for in the round), payeeOf(id) (the ID's payee in the round), creatorId(), stage(), raised(), subscriberCount(), subscribed(addr), exitQuote(addr), previewFor(addr), owedWei(addr), owedTokens(addr), totalOwed(), totalOwedTokens(), feeCharged(), spent(), tokensBought(), token(), cfg(), terms().

Events ​

Created(creator, creatorId, kind, quoteToken, target, feeBps, salt) · Subscribed(who, id, handle, amount, total, returned) · Exited(who, amount, fee, refunded, pushed) · Filled(raised, subscribers) · FeePaid(to, amount, atLaunch, pushed) · Launched(token, fee, spent, tokensBought, subscribers) · Abandoned() · Distributed(who, tokens, refundWei, pushed) · Refunded(who, amount, pushed) · Withdrawn(who, amount) · TokensOwed(who, amount) · TokensWithdrawn(who, amount) · DistributionDone() · Swept(to, bnb, tokens)

Factory: LaunchCreated(launch, creator, templateId) · TemplateProposed / TemplateActivated / TemplateCancelled / TemplateDisabled · BindingProposed / BindingActivated / BindingCancelled · LaunchSignerSet(signer) · PolicyUpdated() · Paused(paused)

Binding contract: Bound(id, wallet, handle) · Unbound(id, wallet, by) · SignaturesRevoked(id, nextNonce)

External contracts (BSC) ​

ContractAddress
Agent ID HandleRegistry0x60B9262456dE011F7d15a54CdD8c48bAaa8B022F
Flap Portal0xe2cE6ab80874Fa9Fa2aAE65D277Dd6B8e65C9De0
Flap VaultPortal0x90497450f2a706f1951b5bdda52B4E5d16f34C06
Flap Split Vault Factory0xfab75Dc774cB9B38b91749B8833360B46a52345F

Safety ​

  • No admin withdrawal, no upgrades; the factory owner can only change policy for new rounds.
  • A failed push never blocks others: BNB or tokens that can't be sent are recorded and the owner withdraws them.
  • The launch fee is capped so that fee + BNB spent never exceeds the raise; any raise amount settles.
  • Internal security review completed in October 2026: Slither and Aderyn static analysis, a function-by-function manual review, an independent second reviewer, about 2.3 million randomized calls of Foundry and Medusa fuzzing and invariant testing, and 41 tests (including real Flap on a BSC mainnet fork). All 8 issues found are fixed; the report is audit/REPORT.md in the contracts repository. A third-party audit is planned before launch.