热门话题
#
Bonk 生态迷因币展现强韧势头
#
有消息称 Pump.fun 计划 40 亿估值发币,引发市场猜测
#
Solana 新代币发射平台 Boop.Fun 风头正劲
欢迎回到 Sherlock 的漏洞聚焦,我们在这里突出展示在 Sherlock 审计中发现的一个重要漏洞。
本周,我们审查了在 @plaza_finance 竞赛中发现的错误抵押水平计算,该竞赛由 @0xadrii、@KupiaSecurity、@f、
@farman1094_ 和 @0xnovaman33 提供。

漏洞摘要:
在 getRedeemAmount(...) 中,合约使用交易后状态计算 BOND 赎回的抵押水平:
// 当前代码(易受攻击)
collateralLevel =
((tvl - (depositAmount * BOND_TARGET_PRICE)) * PRECISION)
/ ((bondSupply - depositAmount) * BOND_TARGET_PRICE);
因为赎回定价使用这个估算的 collateralLevel 来决定是否支付最高价格($100),攻击者可以以混合(有时折扣)创建率购买 BOND,直到(当前)抵押水平降至 ≤ 1.2,然后以 $100 上限赎回所有 BOND——计算时使用一个精心设计的 depositAmount,使估算的抵押水平再次超过 1.2。这使得攻击者能够提取 ETH(“无风险”差价),直到池的当前抵押水平达到阈值。
攻击步骤:
1) 设置阶段
池示例参数:
- poolReserve = 120 ETH,bondSupply = 3000,levSupply = 200,ETH 价格 = $3075
定价规则:
创建(购买)BOND:
- 如果 collateralLevel ≤ 1.2:creationRate = tvl * 0.8 / bondSupply
- 否则:creationRate = $100
赎回(出售)BOND:
- 如果估计的 collateralLevel ≤ 1.2:redeemRate = tvl * 0.8 / bondSupply
- 否则:redeemRate = $100
2) 阶段 A – 以混合/折扣价格购买 BOND
- 在监控 (当前) 抵押水平 = tvl / (bondSupply * 100) 的同时购买 BOND。
- 首次购买发生在抵押水平 > 1.2 时 → 每个 BOND 近乎铸造 $100。
- 随后的购买将当前抵押水平压低至 1.2 以下 → 以折扣创建率铸造 (例如,~$94.07),以便便宜地积累大量 BOND 余额。
3) 阶段 B – 以最高价格赎回所有 BOND
- 调用 redeem(BOND, depositAmount = attackerBondBalance, ...)
- 合约使用赎回后的状态计算估计的抵押水平 (bondSupply - depositAmount) 和 (tvl - depositAmount * 100),并且 (在这个例子中) 得到一个值 > 1.2
- 因为这个估计值超过了阈值,赎回率被设定为最高 $100,允许攻击者以 $100 兑现所有累积的 BOND
4) 利润实现
- 折扣购买与 $100 销售之间的差异产生净 ETH 利润。
- 在 PoC 数字中:在两次购买中花费 60 ETH,赎回时返回 ~61.89 ETH → ~1.89 ETH 利润。
- 攻击者可以迭代,直到当前池抵押水平降至 ~1.2,提取大约:可提取的 USD ≈ ethPrice × poolReserve − 120 × bondSupply
影响是什么?
直接资金提取/价值泄漏:攻击者以折扣价铸造并以100美元赎回,从池中 siphoning ETH。
在阈值之前无限制:可以继续,直到池的当前抵押水平缩小到≈1.2。
系统性定价不一致:造成套利,诚实用户通过更糟糕的池储备/结果为此买单。
根本原因:
使用交易后状态来定价赎回
代码计算 collateralLevel 时假设赎回已经发生:
// 使用 (tvl - depositAmount*100) 和 (bondSupply - depositAmount)
collateralLevel =
((tvl - (depositAmount * BOND_TARGET_PRICE)) * PRECISION)
/ ((bondSupply - depositAmount) * BOND_TARGET_PRICE);
1. 这让攻击者可以选择 depositAmount,使得估计水平超过阈值 (> 1.2),解锁 $100 的 redeemRate,即使当前池状态并不合理。
2. 基于操控指标的阈值限制
$100 的上限决策依赖于这个可操控的估计抵押水平,而不是当前(交易前)水平,从而使价格操控成为可能。
缓解措施:
根据当前池状态计算赎回定价,而不是估计的赎回后余额。项目建议的修复是正确的:
- collateralLevel = ((tvl - (depositAmount * BOND_TARGET_PRICE)) * PRECISION)
- / ((bondSupply - depositAmount) * BOND_TARGET_PRICE);
+ collateralLevel = (tvl * PRECISION) / (bondSupply * BOND_TARGET_PRICE);
额外的加固(推荐):
1. 价格单调性:确保赎回价格不会随着存款金额的增加而增加(没有“卖得更多,获得更好的单位价格”)。
2. 不变性定价:从单一不变性中推导创建/赎回,以便买卖对称防止单边套利。
3. 滑点检查:要求用户提供创建和赎回的最小/最大汇率。
4. 限制与节流:每笔交易和每个区块的赎回上限,以限制接近阈值时的损害。
5. 路径一致性:对齐创建和赎回路径,以使用相同的抵押品水平定义(仅当前状态)。
我们很自豪能够通过这一发现帮助 @plaza_finance 确保安全。
当绝对需要安全时,Sherlock 是正确的选择。
3.28K
热门
排行
收藏

