合约
部署地址
BSC 主网(chainId 56),部署区块 130926361。有所有者的合约(工厂、平台名单、两个分账合约工厂)都归 Samefirst DAO 多签,部署钱包没有任何权限:
| 合约 | 作用 | 地址 |
|---|---|---|
| SamefirstFactory | 工厂 | 0xad8B527F69689d684dFa1E90678Cf281B33F673b |
| SamefirstLaunch | Classic 模板(每场首发克隆它) | 0xF0d80E71B7b038305dcb9ADb265fa9b2190332C7 |
| SamefirstGate | 每场首发的验证方式和黑白名单门禁 | 0x05ca0BB28E2658666a38713827a96F191F312222 |
| AgentIdIdentity / BabtIdentity / HoldingIdentity | 身份来源:币安 Agent ID、BABT、持币 | 0 Agent ID 0x95Bf076f8bE85555124fD5FAC0C611A001D1915a1 BABT 0x51622297bB5Da039Ad6d74482d1364b0136Febb42 持币 0xFF7cb67D6307E91A5490ac38c6AD8721b16AD8c8 |
| SamefirstLists | 平台名单 | 0x374d8f5DC377839124AbE25c9e54074FB68F82e4 |
| SamefirstBinding | 钱包绑定 | 0x4e51C430b48B980047B9B471F40666e150B6FCCd |
| FlapAdapter | Flap 适配器 | 0xBdCd1E7EA18F499D5FF34e912E107CC18Bba5042 |
| SamefirstSwapper | 非 BNB 池发射时的兑换合约 | 0xA20081bC69790DEf1E984159916de04fF518e788 |
| SamefirstSplitterFactory | 税收分账合约工厂 | 0x5cb1d6c35837D6373D4Aa930ff0390E2B361259A |
| SamefirstXSplitterFactory | 推特账号分账合约工厂 | 0x3BeCAc0ec785291631063cFb88b79ed1beF2079A |
| Safe | Samefirst DAO 多签钱包 | 0x5e10756B82D8E7351dCFA482794767E74b8539F3 |
组成
| 合约 | 作用 |
|---|---|
SamefirstFactory | 通用工厂。登记玩法模板(多签登记,立即生效;登记后不可修改,可停用)和身份来源(同样立即生效,可停用),用 createLaunch(模板编号, 参数包[, salt]) 为每个首发克隆一个模板(EIP-1167,CREATE2):带 salt 时首发地址可以事先用 predictLaunch(模板编号, 创建者, salt) 算出,salt 按创建者区分,别人抢不走。管理所有模板共用的设置:手续费(1%–5%)、DAO 地址、募资额范围(最低 0.1 BNB)、募满后等待发射的时间(abandonAfter,默认 1 小时,30 分钟–7 天)、暂停新首发、非 BNB 池的发射签名密钥(launchSigner,多签设置;清空即停止所有非 BNB 池发射,这一项对已有首发也立即生效)、发行人身份来源(决定谁算同一个发行人,默认 Agent ID)。设置只影响之后新建的首发。 |
SamefirstLaunch(Classic 模板) | 单个首发:认购、退出、发射、分发、领取、退款。创建时不付任何费用(代币地址在发射时才定,不锁定)。份额按身份计:第一次认购时由门禁确定身份(某个 Agent ID,或地址本身),一个身份一份,第一次认购的地址就是本轮的收款地址。募满后的前 10 分钟只有发行人的发射地址(launcher)能发射,之后任何人都可以;创建时可以给发射地址预付最多 0.01 BNB 的 gas。创建时检查:税率各不超过 10%(Flap 的上限)、非 BNB 池滑点上限 1%–5%、池子代币要是一个合约。资金只会流向 Flap、兑换合约(非 BNB 池发射时)、认购者或 DAO。 |
SamefirstBinding | 每个 Agent ID 绑定一个普通钱包:ID 签 EIP-712 授权(不花 gas),钱包提交上链。一个钱包只属于一个 ID;ID 一侧和钱包一侧各有 3 天冷却;钱包或 ID 可随时解绑。没有管理员。 |
FlapAdapter | 只读助手:校验发行人的 Flap 参数,生成创建代币的调用;非 BNB 池:核对发射方案(checkPlan:工厂登记的发射签名密钥为这一轮和这个发送地址签的、未过期且有效期不超过 10 分钟、路径是 PancakeSwap 官方池子且从 WBNB 到池子币),自定义池子代币再按 Flap 签名报价算独立底线(flapFloor,Chainlink BNB/USD 折算,至少 85%)。金库:任何在 Flap VaultPortal 上可用的金库工厂都能选,除非它没有代码、在平台的 VAULT_BAN 名单上、被 Flap 停用、或不支持这个池子;多签也可以切换为只允许官方金库。 |
| 身份来源 | 实现 ISamefirstIdentity(identify(付款地址, 配置) 返回身份,checkConfig(配置) 校验配置),在工厂登记编号:0 AgentIdIdentity(Agent ID 本身或它绑定的钱包,也是发行人身份)、1 BabtIdentity(持有 BABT 的地址)、2 HoldingIdentity(配置是代币和最低余额,认购时查)。 |
SamefirstSplitterFactory | 税收分账合约的工厂。每一轮的分账合约地址由「首发地址 + DAO 比例」用 CREATE2 算出来,创建首发时就能填进 Flap 的收税地址,合约可以晚点部署,之前收到的税部署后全部归它。发射后任何人都能部署(deploy(首发, 比例),会核对首发是工厂登记的、代币对得上)。DAO 比例由发行人选(网站上首发参与者 1–80%,即 DAO 至少 20%);地址里写的 DAO 比例低于 20% 的,部署时按 20% 算,税收照常分。所有者是多签,只能改网站给新首发的默认比例(默认 DAO 50%,不能低于 20%),不影响已有的分账合约。 |
SamefirstSplitter | 一个代币的收税地址。收到的 BNB 或任意代币,split(资产) 时按比例分开:DAO 那份直接转进这一轮的 DAO,认购者那份记入「每个分到的代币可领多少」;认购者用认购地址 claim(资产列表) 自己领(收不了某种资产的合约地址可以用 claimTo(资产列表, 收款地址) 让它发到别处)。可领 =(分到的代币 × 每代币累计可领 − 已结算)× 持币系数;持币系数 = 领取时持有量(含首发合约里还没发出的)÷ 分到的量,最多 1,只降不升,扣下的归 DAO。没有管理员;收 BNB 不做任何事(带不带 calldata 都收),所以收税不会失败;付给 DAO 的转账限 60,000 gas,DAO 收不了时先记着、下次再付。已知局限:持币系数只在领取那一刻读余额,卖掉的人领取前临时借来或买回代币就能恢复系数(只影响扣给 DAO 的那部分,不影响别的认购者)。 |
SamefirstXSplitterFactory | 推特账号分账合约的工厂。地址由「首发地址 + 推特账号(keccak256("x:" + 数字 ID))+ 推特主比例(最多 80%)+ 认领期限(1–90 天,默认 7 天)」用 CREATE2 算出来,创建首发时就能填进 Flap 的收税地址。发射后任何人都能部署,认领期限从部署时开始算;绕过网站写进地址的比例超过 80% 或期限超出范围的,部署时按上下限算。所有者是多签:可以更换或清空平台的认领密钥(setClaimer,清空后谁都绑定不了),改网站给新首发的默认期限;不影响已有合约里的钱。 |
SamefirstXSplitter | 一个代币的收税地址(税收给推特账号)。split(资产) 谁都能调:推特主那份先留着,DAO 那份直接转进这一轮的 DAO。平台的认领密钥在推特主用推特登录后 bind(钱包)(期限内首次绑定;已绑定的可以换钱包),之后每次分账直接付给这个钱包;期限过了还没绑定,留着的和以后的推特主那份都转给 DAO(Forfeited 事件)。付不出去的 BNB 记账,钱包自己 withdraw 取;BNB 转账限 100,000 gas。没有管理员;收 BNB 不做任何事,收税不会失败。 |
SamefirstSwapper | 非 BNB 池发射时,把这一轮的 BNB 沿发射方案的路径(PancakeSwap V2 / V3,最多 3 跳)换成池子币并交回这一轮,按实际到账计(转账税算在内)。没有管理员、不存任何东西,换不完整笔就回滚。 |
黑白名单
| 合约 | 作用 |
|---|---|
SamefirstLists | 平台通用名单:可以建任意多份名单,每份名单分别设定操作员能否添加、能否移除。初始几份:SUBSCRIBER_BLOCK(平台黑名单:操作员只能加,移出要多签)、NAME_BAN(禁用的代币名称:操作员可以加也可以移除)和 VAULT_BAN(禁用的金库工厂:操作员可以加也可以移除)。另存参数:MAX_UNBLOCKS(发行人对同一个人最多移出几次,默认 1,0–10)、Flap 名称检查模块地址。所有增删都带可选的公开原因,事件可查。所有者是多签。 |
SamefirstGate | 每场首发的门禁:创建时检查发行人不在平台黑名单、名称和代号不在 NAME_BAN、Flap 不会拒绝这个名称(直接调用 Flap 的防诈骗模块),记录这一轮的验证方式(最多 5 个身份来源及其配置、是否有白名单、是否对所有地址开放)、初始白名单批次(Merkle 根,最多 100 批)、项目黑名单(创建时最多 500 个)和当时的 MAX_UNBLOCKS;认购时检查平台黑名单、项目黑名单(付款地址和它代表的 Agent ID 都查),再按顺序尝试身份来源、白名单证明(先 Agent ID 的叶子,再地址本身;证明指向这一轮持有的任意一批)、对所有地址开放,第一个满足的决定身份,之后不变。发行人(创建地址,或绑定到发行人 Agent ID 的钱包)在准备期和认购期管理名单:addWhitelist 追加批次,removeWhitelist 只在准备期能删,openToAll 一次性转为对所有地址开放;blockHere 追加黑名单,unblockHere 准备期不计次、开放后每人最多 MAX_UNBLOCKS 次。 |
SamefirstLaunch(Classic 模板)的名单部分 | 参数包多一段名单数据(abi.encode(SamefirstGate.Lists):身份来源和配置、是否有白名单、是否开放、开放时间、初始批次、项目黑名单);专属轮可以先准备最多 7 天(openAt 之前不能认购),发行人可以 endPreparing(false) 提前开放或 endPreparing(true) 取消(状态 Cancelled);认购前调用 SamefirstGate.check;专属轮用 subscribe(bytes32[] proof) 认购。退出、领取、退款不受名单影响,拉黑不会卡住任何人的钱。 |
名单只影响认购资格和创建,不影响已经认购的人。公开名单页:samefirst.com/lists。
首发合约的函数
| 函数 | 谁调用 | 作用 |
|---|---|---|
subscribe() payable | 符合这一轮验证方式的地址 | 认购或追加;让首发募满的那一笔只收到目标为止,多余部分当场退回 |
exit() | 认购者 | 募满前退出,退回金额减手续费 |
launch(salts, plan) | 发射地址(募满后 10 分钟内),之后任何人 | 募满后发射。plan:BNB 池为空;非 BNB 池是平台发射签名密钥为这一轮签的发射方案(兑换路径、最少应得、截止时间,自定义池子代币还带 Flap 的签名报价)。salts 是代币地址的候选 salt(Flap 要求 7777 / 8888 结尾),用第一个还没被占用的,在同一笔交易里发币,不预先锁定(空列表 = 用参数里存的)。有人从待打包交易里抄走全部候选先用掉时,发射失败、整笔回滚,换一批重试;keeper 一次带 4 个候选,并在配置了私有通道时私下发送 |
distribute(n) | 任何人 | 分批推送代币和未用完的 BNB |
claim() | 认购者 | 自己领取 |
abandon() | 任何人 | 募满后等待期(terms().abandonAfter,默认 1 小时)结束仍未发射成功 → 全额退款 |
refund() / refundBatch(n) | 认购者 / 任何人 | 领取 / 批量推送退款 |
withdraw() | 任何人 | 领取没能推送成功、记在账上的 BNB |
withdrawTokens() | 认购者 | 领取分发时没能转出、记在账上的代币 |
sweep() / sweepToken(t) | 任何人 | 全部结算后,把零头和其他代币转给 DAO |
只读:idOf(addr)(这个地址本轮代表的 ID)、payeeOf(id)(这个 ID 本轮的收款地址)、creatorId()、stage()、raised()、subscriberCount()、subscribed(addr)、exitQuote(addr)、previewFor(addr)、owedWei(addr)、owedTokens(addr)、totalOwed()、totalOwedTokens()、feeCharged()、spent()、tokensBought()、token()、cfg()、terms()。
事件
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)
工厂:LaunchCreated(launch, creator, templateId) · TemplateProposed / TemplateActivated / TemplateCancelled / TemplateDisabled · BindingProposed / BindingActivated / BindingCancelled · LaunchSignerSet(signer) · PolicyUpdated() · Paused(paused)
绑定合约:Bound(id, wallet, handle) · Unbound(id, wallet, by) · SignaturesRevoked(id, nextNonce)
依赖的外部合约(BSC)
| 合约 | 地址 |
|---|---|
| Agent ID HandleRegistry | 0x60B9262456dE011F7d15a54CdD8c48bAaa8B022F |
| Flap Portal | 0xe2cE6ab80874Fa9Fa2aAE65D277Dd6B8e65C9De0 |
| Flap VaultPortal | 0x90497450f2a706f1951b5bdda52B4E5d16f34C06 |
| Flap Split Vault Factory | 0xfab75Dc774cB9B38b91749B8833360B46a52345F |
安全
- 没有管理员提款、不可升级;工厂 owner 只能调整新首发的策略。
- 推送失败不会卡住别人:BNB 或代币转不出去时记在账上,由本人领取。
- 发射手续费封顶,保证「手续费 + 实际花费」不超过募资额,任何募资金额都能正常结算。
- 2026 年 10 月完成内部安全审查:Slither、Aderyn 静态分析,人工逐函数复核,另一位审查者独立复核,Foundry 和 Medusa 模糊与不变量测试约 230 万次随机调用,以及 41 个测试(含 BSC 主网分叉上的真实 Flap)。发现的 8 个问题已全部修复,报告见合约仓库
audit/REPORT.md。第三方审计计划在上线前进行。