问HN:在Move智能合约开发中常见的错误有哪些?
我一直在审计 Sui Move 合约,并不断发现一些微妙的错误,这些错误在 Move 强大的类型系统下依然会被漏掉。我很好奇其他人是否遇到过类似的问题。
热土豆模式与意外的“丢弃”:
该模式依赖于没有能力的结构体来强制显式消费。但我发现开发者们经常不小心添加“有丢弃”:
```move
struct FlashLoanReceipt has drop { // 错误:现在可以被忽略
pool_id: ID,
amount: u64,
}
```
现在这个收据会被自动丢弃,代币不会被退回。我在生产代码中发现了这个问题,就在部署之前。
缺少幻影类型参数:
收据没有绑定到正在使用的币种类型:
```move
struct PaymentReceipt { // 缺失:幻影 CoinType
amount: u64,
}
```
有人可能会用毫无价值的 ScamCoin 付款,获得收据,然后索取真实物品。添加“幻影 CoinType”可以解决这个问题,但很容易被忽视。
Option<T> 与不可丢弃类型:
即使是空的 Options,如果它们包装了不可丢弃的类型,也需要显式调用 `option::destroy_none()`。这让人感到意外。
相关事件:Cetus 事件(2.2 亿美元,2025 年 5 月)
这个错误不在 Cetus 的代码中,而是在一个数学库依赖的 integer-mate 中。三次审计仔细检查了能力注释,但忽略了依赖项。类型安全防止了整个漏洞类别,但无法捕捉到位移验证错误。
Move 的类型系统确实比其他替代方案更好,但在热土豆上添加“有丢弃”并不会产生警告——它只是默默地工作。代币上的“复制 + 丢弃”也是如此。
我已经开始将能力注释视为代码中最关键的安全部分,而不仅仅是样板。
你在 Move 开发中见过哪些错误?除了能力之外,还有其他模式让人困惑吗?我很想听听你或你的团队遇到的情况。
查看原文
I've been auditing Sui Move contracts and keep finding some subtle bugs that slip through despite Move's strong type system. Curious if others have run into similar issues.<p>Hot potato pattern with accidental "drop":<p>The pattern relies on structs with zero abilities to force explicit consumption. But I keep seeing developers accidentally add "has drop":<p>struct FlashLoanReceipt has drop { // Bug: can now be ignored
pool_id: ID,
amount: u64,
}<p>Now the receipt just gets auto-dropped and tokens aren't returned. Found this in production code right before deployment.<p>Missing phantom type parameters:<p>Receipts that don't bind to the coin type being used:<p>struct PaymentReceipt { // Missing: phantom CoinType
amount: u64,
}<p>Someone can pay with worthless ScamCoin, get a receipt, then claim real items. Adding "phantom CoinType" fixes this but it's easy to miss.<p>Option<T> with non-droppable types:<p>Even empty Options need explicit option::destroy_none() calls if they wrap non-droppable types. This catches people off guard.<p>Related: the Cetus incident ($220M, May 2025)<p>The bug wasn't in Cetus's code but in integer-mate, a math library dependency. Three audits checked ability annotations carefully but glossed over dependencies. Type safety prevented whole vulnerability classes but couldn't catch the bit-shift validation error.<p>Move's type system is genuinely better than alternatives, but adding "has drop" to a hot potato doesn't generate warnings - it just silently works. Same with "copy + drop" on tokens.<p>I've started treating ability annotations as the most security-critical part of the code, not just boilerplate.<p>What mistakes have you seen in Move development? Are there other patterns beyond abilities that trip people up? Would love to hear what's caught you or your teams.