本文作者分享了对一个 pump.fun 风格的代码库及其后端的审计经验。重点关注了后端代码的三个主要功能:从 bonding curve 中提取代币、创建 Raydium 池并迁移流动性、以及销毁剩余代币和灰尘代币。文中详细描述了在代币 decimal 处理、后端宕机处理和 JITO 捆绑交易处理中发现的几个关键问题,强调了对后端系统进行安全审计的重要性。
最近我有机会审计了一个 pump.fun 风格的代码库及其后端。对于那些不知道 pump.fun 是什么的人,这里有一个复习。Pump.fun 是 Solana 上的一个启动平台,允许任何人在 Solana 区块链上启动一个代币。它是 Solana 上 meme 币背后的动力。pump.fun 允许公平启动,没有预售,也没有团队分配。它在某种程度上有效地防止了我们过去见过的 rugpull。
部署者只需选择一个名称、代码和 JPG 图像,即可立即开始在 bonding curve 上交易。用户选择一个代币,在 bonding curve 上购买,并在他们喜欢的任何时候出售。
bonding curve 是一条数学曲线,它根据代币的供应量决定代币的价格。通常,购买的代币越多,价格越高。
当足够多的用户购买了代币,并且其市值达到 69,000 美元时,将有 12,000 美元的流动性存入 Solana 去中心化交易所 Raydium 并被销毁。
该项目是为 Solana 开发的,并用 Anchor Framework 编写。我们在 Solana 程序中发现了 1 个严重、1 个高危和 3 个中危漏洞,但在这篇文章中,我将重点关注代码库的后端部分,因为我们通常很少有机会审计链下组件。
后端执行三个主要功能。
现在,所有这些功能都很重要,我们为我们的审计提出了以下非详尽的威胁建模问题列表。
考虑到上述威胁,我们开始寻找潜在的问题。在审计之前列出威胁对我们非常有帮助,使我们能够超越代码的预期功能进行思考。通过制定项目的高级概述并全面列出可能的威胁,我们为我们的调查创建了一个战略框架。
重要的是要注意,并非所有已识别的威胁最终都适用于特定的代码库。然而,其价值在于全面的初始方法 —— 列出潜在的漏洞提供了一种系统的方法,可以在我们深入审计时有条不紊地评估和消除风险。
现在是有趣的部分,BUG 和 BUG。我将在这里讨论一些。
在创建流动性池时,当前实现存在与代币十进制处理相关的重大漏洞。此问题可能导致不正确的代币数量被存入池中,从而可能导致财务差异和交易风险。
核心问题在于 createPool
函数,它使用硬编码的 TOKEN_DECIMALS
常量。这种方法未能考虑到不同代币可能具有的不同的小数位数。
createPool = async (connection, payer, baseMint, baseTokenAmount, solAmount)
硬编码的小数处理导致了巨大的分配差异。只有 2% 的代币供应量进入池中,而不是预期的 20%。这表明了使用固定小数常数的关键风险
现在,这个问题更多的是一个架构问题,我们观察到系统假设它将永远运行,并且不考虑任何停机情况。
鉴于链上代码将持续运行,因此链下处理必须强大且能够抵御不可预见的威胁。如果后端基础设施由于任何原因遇到停机,则没有机制可以跟踪已处理/错过的事件。这将导致一个严重的问题,因为停机期间要迁移的池将被错过并且不会被处理。
我们建议后端应使用数据库来存储与 bonding curve 过程相关的事件。该数据库将跟踪每个事件的状态和相应的插槽,直到后端成功处理它们。如果后端停机,系统可以恢复并在恢复在线后处理任何错过的事件,确保不会丢失任何事件。
为了更好的管理,我们建议实施 pagerduty 或 telegram,以便在发生停机时进行通知。
我们发现的一个有趣的问题是,只有当 Jito-Solana 领导者生成区块时,才会处理 Jito Bundles。这意味着如果 JITO 不是提议者,则 tx 可能会被恢复,尽管在本次审计时 JITO 的网络权益为 91.69%。
根据 JITO 官方 repo 中的示例,使用以下检查。
这将确保每次 JITO 是区块生产者时发送 bundle。
要点:
- 原文链接: medium.com/@mahitman1/le...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!