正当朋友圈还在刷屏各种DeFi一夜暴富的故事时,一场发生在链上的 “数字劫案”,给整个行业当头浇了一盆冷水。今天,我们就来拆解这场堪称 “史上最贵代码” 的来龙去脉,看看漏洞究竟藏在哪里,又能给我们带来哪些警示。

2.3亿美元,约合16亿人民币——这并非资本市场的数字游戏,而是Sui链头部去中心化交易所Cetus,因一行代码漏洞被黑客卷走的真实损失。
当DeFi的造富神话还在朋友圈刷屏时,这场发生在链上的 “数字劫案”,给整个行业狠狠浇了一盆冷水。今天,我们就来拆解这行 “史上最贵代码” 的来龙去脉,看看漏洞究竟藏在哪里,又能给我们带来哪些警示。
事件始末:Cetus 遭遇 “灭顶之灾”
作为Sui生态最大的去中心化交易所,Cetus承载着大量用户的资产与交易需求。然而近期,黑客通过精心构造的交易,利用Cetus依赖的核心工具库中一个隐藏的漏洞,成功绕过了合约的安全校验,盗走了价值2.3亿美元的资产。
事后复盘发现,问题出在Sui链原生工具库math_u256.move中的checked_shlw函数——正是这短短几行代码里的一个逻辑错误,给了黑客可乘之机。
技术扒皮:一行代码如何捅出16亿的窟窿?
我们先来看看出问题的这段代码:
public fun checked_shlw(n: u256): (u256, bool) {
let mask = 0xffffffffffffffff << 192; // 原漏洞行
if (n > mask) {
(0, true)
} else {
((n << 64), false)
}
}
修复代码(新版):
public fun checked_shlw(n: u256): (u256, bool) {
let mask = 1 << 192; // 修复后的正确行
if (n > mask) {
(0, true)
} else {
((n << 64), false)
}
}
漏洞原理:
checked_shlw函数的设计初衷,是对256位无符号整数n执行左移64位操作,并检查是否会溢出。如果溢出,就返回(0, true)表示错误;如果安全,就返回左移后的结果和false。
旧版逻辑问题:原代码中mask = 0xffffffffffffffff << 192,这行计算后,mask的值是2^256 - 2^192(相当于u256的高64位全部为1,低192位为0)。这意味着,只要输入的n小于等于这个mask,函数就会认为左移64位是安全的,进而执行n << 64。
黑客的攻击逻辑:黑客精心构造了一个输入n,让它满足2^192 ≤ n ≤ mask。此时n << 64的结果是n * 2^64,而因为n ≥ 2^192,所以n * 2^64 ≥ 2^192 * 2^64 = 2^256——这已经超出了u256类型的最大值(u256的最大值是2^256 - 1)。溢出后,计算结果会被截断,产生一个非预期的错误值,黑客正是利用这个错误值绕过了合约的其他校验,最终盗走了池子中的巨额资产。
修复思路:新版本代码把mask改成了1<<192,这样只要n > mask(也就是n ≥ 2^192),函数就会直接返回错误(0, true),从根本上避免了溢出风险。
警钟长鸣:DeFi 安全,从来不是小事
这场16亿的教训,给所有DeFi从业者和开发者都上了一课:
基础工具库的安全是生命线:很多项目会依赖底层工具库,但如果这些“基建”存在漏洞,上层项目都会遭殃。这次事件中,Cetus作为上层应用,就因为底层math_u256的问题被拖下水。
边界测试不能少:数值计算的溢出、截断等问题,往往藏在边界条件里。开发者在写代码时,必须对所有极端情况做测试,不能想当然。
代码审计要“较真”:哪怕是一行看起来简单的赋值,也要反复检查逻辑是否严谨。这次的漏洞如果在审计时被揪出来,16亿的损失本可以避免。
DeFi生态的信任需要共同守护:一次重大安全事件,不仅会让项目方和用户承受财产损失,更会打击整个生态的信心。安全不是某一个人的事,而是所有参与者的共同责任。
16亿的代价,换来了一行代码的修复,也换来了整个行业的警示。在DeFi的世界里,没有“万无一失”的神话,只有“如履薄冰”的谨慎。
对于开发者来说,每一行代码都可能是资产的闸门;对于用户来说,选择项目时也要多一份对安全的审视。希望这次事件能让更多人记住:在链上,安全永远是第一位的。
