这是 TonUP 的首份事故报告。在部署 Jetton 合约期间,由于人为疏忽,我们错误地配置了 Jetton 合约的小数点,导致所有相关合约需要升级。我们之前在 Telegram 频道中提到了这次更新。现在,我们将这份事故报告公之于众,供大家参考。
事故日期:2023 年 12 月 21 日
严重程度:关键
披露日期:2024 年 1 月 9 日
在 TonUP,我们一直致力于高度的透明度,特别是在安全事故方面。我们相信,分享这些信息对于构建一个更安全的加密环境至关重要。这份事故报告代表了我们最新的披露,我们希望它能帮助其他区块链项目避免类似的情况。
2023 年 12 月 21 日,在 UP 代币的成功初始代币发行(IDO)后,TonUP 的 IDO 合约中发现了一个安全事故。一名社区开发者向我们报告,UP 代币的小数点配置被设置为了 8 位小数,而不是 TON 生态系统中常见的 9 位小数,导致 IDO 合约分配的 UP 数量错误。在报告时,UP 代币已经被铸造并发送到 IDO 合约,且 IDO 已成功完成。UP 代币的领取功能尚未激活。
这一差异发生的原因是,运营团队在未通知研发团队的情况下部署了 UP 代币。因此,研发团队在他们的部署和配置脚本中假设 UP 代币为 9 位小数,导致部署的 IDO 合约配置出现错误。
根据 Jetton 标准规范,为 Jetton 代币设置不同的小数点是允许的。然而,各种去中心化应用(dapps)/ 工具可能会假设为 9 位小数。例如,在 Typescript 中使用 toNano('1') 和在 Tact 中使用 ton("1") 表示 1 个代币,假设有 9 位小数,相当于 1_000_000_000,或在 8 位小数下的 10 个代币。在我们的案例中,小数点配置的差异导致了 UP/TON 价格设置中的意外增加,使每 TON 获得的 UP 数量比我们预期的多 10 倍。这将意味着早期领取者将获得 10 倍的 UP 代币,而晚期领取者将一无所有,实际上导致了用户资金的直接损失。此问题被归类为关键级别,并迅速升级处理。
在报告问题和预定领取时间之间有 12 小时的窗口期。考虑到不同小数点配置可能的未来影响、当前的关键问题,以及还未公开分发任何 UP 代币的事实,我们决定使用九位小数重新部署 UP 代币。我们迅速开发了一套新合约来处理领取过程。新合约在主网部署前已经过全面测试并通过了我们的内部安全审计。参与者信息和数量被迁移到新合约中,新的 UP 代币被部署并发送到新的领取合约,我们在网页前端替换了合约地址。
当按计划时间开放领取时,所有用户都能够无问题地领取 UP 代币。没有用户资金损失。
对于所有未来的初始代币发行(IDO)项目,虽然我们不鼓励,但支持设置非 9 位小数的小数点,我们已经改进了我们的入门流程以支持这一点。
该事件被归类为具有高影响力的关键事件。根据我们漏洞赏金计划的规则,我们向报告方颁发了 10,000 美元的漏洞赏金。
这一事件凸显了严格的测试不仅是智能合约本身,还包括配置参数的验证,以及已部署且与智能合约交互的所有智能合约状态的严格验证的必要性。
在 Jetton 标准中,没有链上方法来获取 Jetton 钱包的余额。给出的理由是 TON 是一个异步区块链,在调用智能合约接收到余额的时候,余额可能已经发生了变化。在我们看来,这不是一个有效的理由,因为例如在我们的案例中,没有这个方法阻止了我们在链上验证 UP 代币余额。如果能够获取自己的 UP 代币余额,IDO 合约就会知道它们没有足够的 Jetton 代币,并会拒绝启动 IDO。在类似情况下,如果智能合约知道在获取余额调用和响应之间不会发生任何外部转账,它可以知道它持有的最少量的 Jetton 代币。遗憾的是,当前的 Jetton 标准无法做到这一点。
因此,我们建议对 Jetton 标准(TEP-137 1)进行扩展,允许一种链上方法来检查钱包的余额。这一改变将防止未来发生类似的事件,并允许更安全、更可靠的智能合约操作。
我们非常感谢社区发现并向我们报告了这个问题。我们也非常感激这次事件得以在不影响用户的情况下解决。我们致力于在所有操作中保持最高标准的安全性和透明度。我们将继续向社区学习,并实施必要的措施来防止未来发生类似事件。我们也希望与社区分享经验,以便其他项目不会犯同样的错误。感谢您的理解和持续支持。
TonUP.io 首席技术官 Ken
【免责声明】市场有风险,投资需谨慎。本文不构成投资建议,用户应考虑本文中的任何意见、观点或结论是否符合其特定状况。据此投资,责任自负。