Sui链DeFi借贷协议Scallop遭骇,旧合约漏洞致15万SUI被盗
近期,Sui链去中心化金融借贷协议Scallop遭遇安全攻击,因已弃用的旧版V2套件中spool账户的last索引未初始化,攻击者利用该漏洞窃取约15万枚SUI代币。核心合约未受任何影响,用户所有存款安全,全部功能已恢复正常。
Sui链上的DeFi借贷协议Scallop刚刚经历了一场不大不小的风波。团队在官方渠道发布安全通知,确认平台遭到攻击,一个与sSUI spool奖励池相关的侧合约被利用,导致约15万枚SUI被盗。好在核心合约安然无恙,受影响的侧合约已被紧急冻结。Scallop在随后的更新中表示,核心合约已解冻,所有操作恢复正常,用户的存款分文未损,存取款功能也已全面恢复。团队承诺后续会分享更多技术细节,并持续加强协议安全监控。

前NEAR核心成员Vadim:问题出在17个月前的旧版套件
这次事件能这么快被拆解,前NEAR核心开发者Vadim功不可没。他在技术分析中直接指出了漏洞的核心:问题并不在当前的运行代码,也不是什么SDK路径,而是2023年11月一个早已被弃用的旧版V2套件。这个版本的代码已经闲置了数月之久,却依然能被人精准命中。Vadim直言,这要么是深度逆向工程的结果,要么就是有人早就知道该朝哪个方向使劲。这个漏洞,已经在链上潜伏了整整17个月。
具体是怎么回事?spool机制会追踪一个随着奖励分配而不断增长的index指数。正常情况下,每个用户在做质押时,系统会记录下当前的last_index,后续计算收益的公式是:质押量 × (current_index last_index)。这样用户只能从加入之后开始赚取奖励,逻辑非常清晰。
但问题就出在,那个被弃用的V2套件里,当系统创建一个全新的spool_account时,last_index字段压根没有被初始化,默认值为0。于是当update_points函数被执行时,计算结果瞬间变成了:点数 = 质押量 × (current_index 0),也就是质押量乘以完整的、自spool建立以来的历史指数。换言之,新创建的账户一次性记入了自2023年8月spool诞生以来累积的全部奖励。
Vadim给出了具体数据:spool指数在20个月间增长到了惊人的11.9亿。攻击者质押了13.6万枚sSUI,瞬间获得了162兆点数的记入。更致命的是,奖励池采用1:1的兑换比例(分子分母都是1),这162兆点数直接对应价值16.2万枚SUI的奖励。池子里只有15万枚SUI,结果自然是瞬间被抽干。
4月链上安全事件皆发生在周边系统
Vadim进一步解释,正常用户通过SDK使用的是新的套件版本,那里已经修复了last_index的同步问题。但麻烦就麻烦在,Sui上的套件具有不可变性——一旦发布,每一个历史版本都将永远可以被调用。共享的Spool与RewardsPool对象接受来自任何版本的调用,攻击者只需要绕过SDK,直接对着旧版代码路径下手就行了。
他把这类问题归类为“Sui过时套件类漏洞”。正确的修复方式,需要在共享对象上加入版本字段,并在每个函数里加上assert!(version == CURRENT_VERSION)这样的版本检查。没有这道防线,每一个过去发布的套件版本,都会是活生生的攻击面。
Vadim还点出了一个更值得行业反思的现象:四月份发生的多数攻击事件,都不是出在核心协议代码上,而是发生在周边系统。换句话说,那些被大家认为“不重要”、“没人在用”的旧代码,反而成了最容易被突破的薄弱环节。这件事对任何在Sui上构建的项目方来说,都是一个足够深刻的提醒。
