W3

Rug Pull 识别器

粘一段合约源码,检查 18 条典型跑路项目的写法。 它给的不是一个分数,而是带行号的证据—— 每条命中都指向源码里的具体位置,未命中的规则也全部列出来。 这样你既能知道「发现了什么」,也能知道「这次排除了什么」。

规则 18可载入样本 4分级随写法浮动 3引擎:本站后端 · 无需密钥

粘贴合约源码

只做静态模式匹配,不会执行代码、不会联网
载入示例:
0 / 400,000 字符Ctrl / ⌘ + Enter 开始扫描

扫描在服务端完成,源码不出网、不入库,请求结束即丢弃。

这里检查的 18 类模式

全部规则都是从「历史上真实发生过损失的写法」里总结出来的。 下面这份目录在未扫描时也列出来,是为了让你知道:结论里的「没命中」 具体排除了什么,而不是一个笼统的「安全」。

  • 严重任何人都能调用 mint 增发代币
  • 高危Owner 保留增发权限
  • 高危存在黑名单机制
  • 中危~严重税率可以在部署后修改
  • 中危交易由开关控制
  • 中危存在单笔 / 单钱包限额
  • 中危合约可以被暂停
  • 高危没有 renounceOwnership,权限无法放弃
  • 高危Owner 可以提取合约资金或改写关键地址
  • 中危~严重tx.origin 被用于权限校验
  • 高危~严重存在 selfdestruct
  • 严重用区块变量生成随机数
  • 高危存在外部调用且全合约没有重入锁
  • 中危部分含外部调用的函数没有加 nonReentrant
  • 中危底层调用的返回值没有被检查
  • 提示合约逻辑可以升级
  • 中危使用了内联汇编
  • 严重转账逻辑对买卖方向做了区别对待

先说清它做不到的三件事

它是模式匹配,不是数据流分析。引擎把注释与字符串掩掉之后,按「函数」为单位切分代码体, 所以能准确说出「哪个函数里出现了这种写法」, 但不会追踪「这个变量是从哪来的」。跨函数、跨合约的资金流它看不见。
命中的是写法,不是意图。有增发权限、可升级、用了内联汇编、有提现函数——正规项目全都有。 命中只说明这种写法存在,是否危险取决于权限给了谁、参数是谁能改。
它一条逻辑漏洞也抓不到。18 条规则覆盖的是「故意写坏」的合约。 重入、闪电贷操纵价格、舍入套利这些把正规协议掏空的漏洞, 代码语法完全正常,在这套扫描里是零命中——去漏洞库看为什么。

引擎是怎么判定的

三层结构。写在这里是因为「为什么有的规则我说它可能误报」这个问题, 答案就在第一层。

1掩码:先把注释和字符串换成等长空格

用等长空格而不是直接删掉,是为了保持行号不变——证据里那个行号要能对得上你编辑器里看到的那一行。 这一步不做的话,文档里写一句「这是个假 mint」就会被当成真实调用。

2切分:按括号配平把源码切成一个个函数

有了函数边界,规则才能问出「这个 mint 上面有没有权限修饰器」这种问题。 只在全文上做正则的话,一个合约里有 mint、另一个没有,是没法区分的。

3判定:在函数级跑规则,附带文件与行号

判定权限用的是「修饰器定义体里有没有针对调用者身份的 require」, 而不是一份修饰器名字白名单—— 修饰器名是用户自定义的,onlyGovernorgovernanceOnlyauthGuard 全都合法, 白名单永远追不上,而漏认一个的代价是凭空造出一条严重级假警报。

规则库与前端目录共用同一份 id。如果引擎命中了目录里没有的规则, 结果区会显式提示「已检查 N 类这句话是不准的」, 而不是悄悄丢掉——前端说明落后于引擎时,这件事本身应该被看见。

为什么给 4 份样本,其中还有一份是「好」的

让人自己去找一段合约来粘,门槛太高,结果就是没人用。 所以给了可一键载入的样本。但只放反面教材会被理解成「有权限 = 恶意」—— 这是错的,于是第二份样本是同样拥有增发能力、但写法规范的对照。

每份样本的预期命中列表都是拿真实引擎跑出来校对过的, 不是手写的猜测;后端还有一份固定样本的回归测试, 断言每条证据的行号都大于 0。

无权限合约(三个致命项一起出现)
预期命中 3
貔貅盘代币(典型 Rug Pull)
预期命中 9
对照:同样能增发,但写法规范
预期命中 1
进阶:可升级金库(七个「语法正常」的坑)
预期命中 7
相关:命中一条规则之后想弄懂它的原理与修复写法,点证据卡片里的链接直接到漏洞库;工具查不出的部分按审计检查清单逐项过;要对照链上的实际状态(验证状态、持仓分布、代理实现),用合约体检