20250823 Equilibria攻击事件,为何balanceOf非安全参数?

摘要:背景信息 Equilibria Finance 是一个为 $PENDLE 代币持有者提高收益的 DeFi 协议。其主要功能包括将 PENDLE 代币转换为 ePENDLE(PENDLE --lock--> vePEND
背景信息 Equilibria Finance 是一个为 $PENDLE 代币持有者提高收益的 DeFi 协议。其主要功能包括将 PENDLE 代币转换为 ePENDLE(PENDLE --lock--> vePENDLE --mint--> ePENDLE),将 ePENDLE 进行 stake 后获得 stk-ePENDLE 等,目的是提升流动性提供者的收益。除此以外,Equilibria 还为 stk-ePENDLE 的持有者提供了 xEQB 和 vlEQB 代币激励。 本次攻击的原因是 stk-ePENDLE 相关的奖励计算逻辑错误,在 stk-ePENDLE 代币可以转移的前提下,根据用户持有的 stk-ePENDLE 代币余额来进行奖励计算。使得攻击者可以通过一笔 stk-ePENDLE 代币在多个账户间重复利用来领取超额的奖励。 攻击交易:https://app.blocksec.com/explorer/tx/eth/0x185a16017fb4d9b2fefdf5935435253d53d4758238275426b507fe54eb4fe97a 漏洞合约:https://etherscan.io/address/0xd30d6fd662c0d92b49f3c3e478e125ba1d968059#code Alert: https://x.com/Equilibriafi/status/1959296722930483668 https://x.com/BlockscopeCo/status/1959287312283496854 Trace 分析 攻击合约通过一系列的代币转换获取价值 0.01 ETH 的 ePENDLE 代币 调用 stk-ePendle.harvest() 从 ePENDLE 奖励池中收集奖励代币,将收集到的 WETH 和 PENDLE 兑换成 ePendle 代币后进行 stake。 此时可以看到 stk-ePendle 合约中存在 13.6 ETH 随后通过闪电贷 Balancer.receiveFlashLoan() 发起攻击。 Balancer.receiveFlashLoan() 先通过闪电贷获取了大量的 ePENDLE,然后 deposit 获得 stk-PENDLE,所有准备工作已经完成。 执行攻击部分, 创建一个新的合约 将 stk-PENDLE 发送到该合约 调用 getReward() 函数获取 EQB,xEQB 和 ETH 等奖励代币 把 ETH 汇总到主攻击合约 把 stk-PENDLE 发送到主攻击合约 把 EQB,xEQB 返还给 stk-PENDLE 合约 随后将这个攻击流程重复进行了 20 次,每次获利约 0.664 ETH,总计获利 13.27 ETH。 攻击者通过漏洞获取到奖励代币后,只要 ETH,把 EQB,xEQB 返还给 stk-PENDLE 合约,是为了重复 20 次的奖励获取能够正常运行下去。因为合约中持有 EQB 的数量是 5538 个,而每次获取 EQB 383 个,20 次就是 7660 个。所以需要每次都将获得的 EQB 和 xEQB 返还给 stk-PENDLE 合约。 代码分析 在 Trace 分析中可以了解到,攻击者利用同一笔 stk-PENDLE 发送到不同的合约中进行重复的奖励领取,多半是计算奖励的逻辑中采用了 balanceOf 的方法来计算奖励权重。 stk-PENDLE 合约:https://etherscan.deth.net/address/0xd30d6fd662c0d92b49f3c3e478e125ba1d968059 在 getReward() 函数中利用 updateReward() 计算用户奖励。 而在 earned() 函数中,通过 balanceOf 获取目标账户 stk-PENDLE 的余额,余额越大,奖励越多。所以攻击者可以通过同一笔 stk-PENDLE 代币重复获取大量的奖励。 后记 漏洞修复 对于这个漏洞修复方案,看到社区也存在一些讨论,主要是围绕着以下几个方面 避免直接采用 balanceOf 来计算收益。 如果需要采用 balanceOf 来计算收益,需要限制 stk-PENDLE 代币不允许 transfer。 stk-PENDLE 代币可以 transfer 的场景下,则需要在代币转移前后,更新 sender 和 recipient 的奖励累计情况。
阅读全文