去中心化金融的世界里,代码执行的顺序就是生死线。一个看似普通的资产转移,如果发生在状态更新之前,足以让整个资金池陷入瘫痪。这不是假设——我在审计Panoptic协议时,发现了一个真实的致命漏洞。
问题的根源藏在CollateralTracker合约的settleLiquidation函数里。清算奖励本该先完成内部记账,再向外转账。但代码偏偏反着来:先给清算人打ETH,再更新被清算者的份额余额。这个违反Checks-Effects-Interactions(CEI)原则的设计,让攻击者有机可乘。
打开网易新闻 查看精彩图片
漏洞的运作机制相当精巧。当清算触发负向奖励(即协议需要向清算人支付ETH)时,合约会先执行payable(liquidator).call{value: msg.value}("")这行外部调用。如果清算人地址是一个恶意合约,它可以在receive()函数里立刻重入协议。此时 victim 的余额处于"脏状态"——bonus已经加到balanceOf[liquidatee],但后续的归零和燃烧逻辑还没执行。
攻击者利用这个时间差,劫持所谓的"幻影份额"。这些份额是协议在清算过程中动态计算的过渡状态,本不该被外部触碰。但在脏状态下,攻击者可以反复操作这些未完成的计算,人为制造无限供应膨胀。_internalSupply的累加逻辑_internalSupply += type(uint248).max - liquidateeBalance被恶意触发多次后,整个池子的记账体系将彻底崩坏。
我已完成完整的PoC验证,使用Foundry框架复现了整个攻击流程。从外部调用介入,到幻影份额被劫持,再到供应无限膨胀——每一步都可稳定重现。这个案例再次证明:在智能合约安全领域,顺序不是细节,是架构。
热门跟贴